public class

SlicePermissionActivity

extends AppCompatActivity

Gradle dependencies

compile group: 'androidx.slice', name: 'slice-core', version: '1.1.0-alpha02'

  • groupId: androidx.slice
  • artifactId: slice-core
  • version: 1.1.0-alpha02

Artifact androidx.slice:slice-core:1.1.0-alpha02 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.slice:slice-core com.android.support:slices-core

Overview

Dialog that grants slice permissions for an app.

Summary

Constructors
publicSlicePermissionActivity()

Methods
public voidonClick(DialogInterface dialog, int which)

protected voidonCreate(Bundle savedInstanceState)

Perform initialization of all fragments.

protected voidonDestroy()

Destroy all fragments.

public voidonDismiss(DialogInterface dialog)

from AppCompatActivityaddContentView, attachBaseContext, closeOptionsMenu, dispatchKeyEvent, findViewById, getDelegate, getDrawerToggleDelegate, getMenuInflater, getResources, getSupportActionBar, getSupportParentActivityIntent, invalidateOptionsMenu, onConfigurationChanged, onContentChanged, onCreateSupportNavigateUpTaskStack, onKeyDown, onLocalesChanged, onMenuItemSelected, onMenuOpened, onNightModeChanged, onPanelClosed, onPostCreate, onPostResume, onPrepareSupportNavigateUpTaskStack, onStart, onStop, onSupportActionModeFinished, onSupportActionModeStarted, onSupportContentChanged, onSupportNavigateUp, onTitleChanged, onWindowStartingSupportActionMode, openOptionsMenu, setContentView, setContentView, setContentView, setSupportActionBar, setSupportProgress, setSupportProgressBarIndeterminate, setSupportProgressBarIndeterminateVisibility, setSupportProgressBarVisibility, setTheme, startSupportActionMode, supportInvalidateOptionsMenu, supportNavigateUpTo, supportRequestWindowFeature, supportShouldUpRecreateTask
from FragmentActivitydump, getSupportFragmentManager, getSupportLoaderManager, onActivityResult, onAttachFragment, onCreateView, onCreateView, onMenuItemSelected, onPause, onRequestPermissionsResult, onResume, onResumeFragments, onStateNotSaved, setEnterSharedElementCallback, setExitSharedElementCallback, startActivityFromFragment, startActivityFromFragment, startIntentSenderFromFragment, supportFinishAfterTransition, supportPostponeEnterTransition, supportStartPostponedEnterTransition, validateRequestPermissionsRequestCode
from ComponentActivityaddMenuProvider, addMenuProvider, addMenuProvider, addOnConfigurationChangedListener, addOnContextAvailableListener, addOnMultiWindowModeChangedListener, addOnNewIntentListener, addOnPictureInPictureModeChangedListener, addOnTrimMemoryListener, getActivityResultRegistry, getDefaultViewModelCreationExtras, getDefaultViewModelProviderFactory, getLastCustomNonConfigurationInstance, getLifecycle, getOnBackPressedDispatcher, getSavedStateRegistry, getViewModelStore, invalidateMenu, onBackPressed, onCreateOptionsMenu, onMultiWindowModeChanged, onMultiWindowModeChanged, onNewIntent, onOptionsItemSelected, onPictureInPictureModeChanged, onPictureInPictureModeChanged, onPrepareOptionsMenu, onRetainCustomNonConfigurationInstance, onRetainNonConfigurationInstance, onSaveInstanceState, onTrimMemory, peekAvailableContext, registerForActivityResult, registerForActivityResult, removeMenuProvider, removeOnConfigurationChangedListener, removeOnContextAvailableListener, removeOnMultiWindowModeChangedListener, removeOnNewIntentListener, removeOnPictureInPictureModeChangedListener, removeOnTrimMemoryListener, reportFullyDrawn, startActivityForResult, startActivityForResult, startIntentSenderForResult, startIntentSenderForResult
from ComponentActivitydispatchKeyShortcutEvent, getExtraData, putExtraData, shouldDumpInternalState, superDispatchKeyEvent
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public SlicePermissionActivity()

Methods

protected void onCreate(Bundle savedInstanceState)

Perform initialization of all fragments.

public void onClick(DialogInterface dialog, int which)

public void onDismiss(DialogInterface dialog)

protected void onDestroy()

Destroy all fragments.

Source

/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.slice.compat;

import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;

import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.text.BidiFormatter;
import androidx.slice.core.R;

/**
 * Dialog that grants slice permissions for an app.
 * @hide
 */
@RestrictTo(RestrictTo.Scope.LIBRARY)
@RequiresApi(19)
public class SlicePermissionActivity extends AppCompatActivity implements OnClickListener,
        OnDismissListener {

    private static final float MAX_LABEL_SIZE_PX = 500f;

    private static final String TAG = "SlicePermissionActivity";

    private Uri mUri;
    private String mCallingPkg;
    private String mProviderPkg;
    private AlertDialog mDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mUri = getIntent().getParcelableExtra(SliceProviderCompat.EXTRA_BIND_URI);
        mCallingPkg = getIntent().getStringExtra(SliceProviderCompat.EXTRA_PKG);
        mProviderPkg = getIntent().getStringExtra(SliceProviderCompat.EXTRA_PROVIDER_PKG);

        try {
            PackageManager pm = getPackageManager();
            CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(
                    loadSafeLabel(pm, pm.getApplicationInfo(mCallingPkg, 0))
                    .toString());
            CharSequence app2 = BidiFormatter.getInstance().unicodeWrap(
                    loadSafeLabel(pm, pm.getApplicationInfo(mProviderPkg, 0))
                    .toString());
            mDialog = new AlertDialog.Builder(this)
                    .setTitle(getString(R.string.abc_slice_permission_title, app1, app2))
                    .setView(R.layout.abc_slice_permission_request)
                    .setNegativeButton(R.string.abc_slice_permission_deny, this)
                    .setPositiveButton(R.string.abc_slice_permission_allow, this)
                    .setOnDismissListener(this)
                    .show();
            TextView t1 = mDialog.getWindow().getDecorView().findViewById(R.id.text1);
            t1.setText(getString(R.string.abc_slice_permission_text_1, app2));
            TextView t2 = mDialog.getWindow().getDecorView().findViewById(R.id.text2);
            t2.setText(getString(R.string.abc_slice_permission_text_2, app2));
        } catch (NameNotFoundException e) {
            Log.e(TAG, "Couldn't find package", e);
            finish();
        }
    }

    // Based on loadSafeLabel in PackageitemInfo
    private CharSequence loadSafeLabel(PackageManager pm, ApplicationInfo appInfo) {
        // loadLabel() always returns non-null
        String label = appInfo.loadLabel(pm).toString();
        // strip HTML tags to avoid <br> and other tags overwriting original message
        String labelStr = Html.fromHtml(label).toString();

        // If the label contains new line characters it may push the UI
        // down to hide a part of it. Labels shouldn't have new line
        // characters, so just truncate at the first time one is seen.
        final int labelLength = labelStr.length();
        int offset = 0;
        while (offset < labelLength) {
            final int codePoint = labelStr.codePointAt(offset);
            final int type = Character.getType(codePoint);
            if (type == Character.LINE_SEPARATOR
                    || type == Character.CONTROL
                    || type == Character.PARAGRAPH_SEPARATOR) {
                labelStr = labelStr.substring(0, offset);
                break;
            }
            // replace all non-break space to " " in order to be trimmed
            if (type == Character.SPACE_SEPARATOR) {
                labelStr = labelStr.substring(0, offset) + " " + labelStr.substring(offset
                        + Character.charCount(codePoint));
            }
            offset += Character.charCount(codePoint);
        }

        labelStr = labelStr.trim();
        if (labelStr.isEmpty()) {
            return appInfo.packageName;
        }
        TextPaint paint = new TextPaint();
        paint.setTextSize(42);

        return TextUtils.ellipsize(labelStr, paint, MAX_LABEL_SIZE_PX, TextUtils.TruncateAt.END);
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (which == DialogInterface.BUTTON_POSITIVE) {
            SliceProviderCompat.grantSlicePermission(this, getPackageName(), mCallingPkg,
                    mUri.buildUpon().path("").build());
        }
        finish();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        finish();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.cancel();
        }
    }
}