下面列出了android.os.Bundle#putBinder ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void installApk(UriForwardProxy uriForwarder, IAppInstallCallback callback) {
// Directly install an APK through a given Fd
// instead of installing an existing one
Intent intent = new Intent(DummyActivity.INSTALL_PACKAGE);
intent.setComponent(new ComponentName(ShelterService.this, DummyActivity.class));
// Generate a content Uri pointing to the Fd
// DummyActivity is expected to release the Fd after finishing
Uri uri = FileProviderProxy.setUriForwardProxy(uriForwarder, "apk");
intent.putExtra("direct_install_apk", uri);
// Send the callback to the DummyActivity
Bundle callbackExtra = new Bundle();
callbackExtra.putBinder("callback", callback.asBinder());
intent.putExtra("callback", callbackExtra);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
DummyActivity.registerSameProcessRequest(intent);
startActivity(intent);
}
static public void start(Context context, @NonNull Uri uri) {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
Bundle extras = new Bundle();
extras.putBinder("android.support.customtabs.extra.SESSION", null);
intent.putExtras(extras);
intent.putExtra("android.support.customtabs.extra.TOOLBAR_COLOR",
ViewUtils.getThemeAttrColor(context, R.attr.colorPrimary));
}
try {
context.startActivity(intent);
}catch(ActivityNotFoundException e) {
// unlikely to happen
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
public static void openChromeCustomTabs(Context context, String url, boolean showTitle) {
if (!URLUtil.isValidUrl(url)) {
Log.w("Utility", "Url not valid!");
Log.w("Utility", url);
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
Bundle extras = new Bundle();
// Something needs to be done about the min SDK...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
extras.putBinder(Constants.EXTRA_CUSTOM_TABS_SESSION, null);
extras.putInt(Constants.EXTRA_CUSTOM_TABS_TOOLBAR_COLOR, ContextCompat.getColor(context, R.color.ets_red_fonce));
if (showTitle) {
extras.putInt(Constants.EXTRA_CUSTOM_TABS_TITLE_VISIBILITY_STATE, Constants.EXTRA_CUSTOM_TABS_SHOW_TITLE);
}
}
intent.putExtras(extras);
context.startActivity(intent);
}
public static Intent getBrowserIntent(Context context, String url) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
final int accentColor = ThemeHelper.getThemeAttrColor(context, R.attr.colorAccent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
Bundle extras = new Bundle();
extras.putBinder(EXTRA_CUSTOM_TABS_SESSION, null);
intent.putExtra(EXTRA_CUSTOM_TABS_TOOLBAR_COLOR, accentColor);
intent.putExtras(extras);
// Optional. Use an ArrayList for specifying menu related params. There
// should be a separate Bundle for each custom menu item.
ArrayList<Bundle> menuItemBundleList = new ArrayList<>();
// For each menu item do:
// Bundle menuItem = new Bundle();
// menuItem.putString(KEY_CUSTOM_TABS_MENU_TITLE, "Share");
// menuItem.putParcelable(KEY_CUSTOM_TABS_PENDING_INTENT, PendingIntent.getActivity(context, 0, new Intent()));
// menuItemBundleList.add(menuItem);
//
// intent.putParcelableArrayListExtra(EXTRA_CUSTOM_TABS_MENU_ITEMS, menuItemBundleList);
}
return intent;
}
static public void start(Context context, @NonNull Uri uri) {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
Bundle extras = new Bundle();
extras.putBinder("android.support.customtabs.extra.SESSION", null);
intent.putExtras(extras);
intent.putExtra("android.support.customtabs.extra.TOOLBAR_COLOR",
ViewUtils.getThemeAttrColor(context, R.attr.colorPrimary));
}
try {
context.startActivity(intent);
}catch(ActivityNotFoundException e) {
// unlikely to happen
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
@TargetApi(18)
public static void openCustomTab(AppCompatActivity activity, Uri uri) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle bundle = new Bundle();
bundle.putBinder("android.support.customtabs.extra.SESSION", null);
intent.putExtras(bundle);
intent.putExtra("android.support.customtabs.extra.SHARE_MENU_ITEM", true);
TypedValue typedValue = new TypedValue();
activity.getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
intent.putExtra("android.support.customtabs.extra.TOOLBAR_COLOR", typedValue.data);
intent.putExtra("android.support.customtabs.extra.ENABLE_URLBAR_HIDING", true);
activity.startActivity(intent);
}
@Override
public void installApp(ApplicationInfoWrapper app, IAppInstallCallback callback) throws RemoteException {
if (!app.isSystem()) {
// Installing a non-system app requires firing up PackageInstaller
// Delegate this operation to DummyActivity because
// Only it can receive a result
Intent intent = new Intent(DummyActivity.INSTALL_PACKAGE);
intent.setComponent(new ComponentName(ShelterService.this, DummyActivity.class));
intent.putExtra("package", app.getPackageName());
intent.putExtra("apk", app.getSourceDir());
// Send the callback to the DummyActivity
Bundle callbackExtra = new Bundle();
callbackExtra.putBinder("callback", callback.asBinder());
intent.putExtra("callback", callbackExtra);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
DummyActivity.registerSameProcessRequest(intent);
startActivity(intent);
} else {
if (mIsProfileOwner) {
// We can only enable system apps in our own profile
mPolicyManager.enableSystemApp(
mAdminComponent,
app.getPackageName());
// Also set the hidden state to false.
mPolicyManager.setApplicationHidden(
mAdminComponent,
app.getPackageName(), false);
callback.callback(Activity.RESULT_OK);
} else {
callback.callback(RESULT_CANNOT_INSTALL_SYSTEM_APP);
}
}
}
@Override
public void uninstallApp(ApplicationInfoWrapper app, IAppInstallCallback callback) throws RemoteException {
if (!app.isSystem()) {
// Similarly, fire up DummyActivity to do uninstallation for us
Intent intent = new Intent(DummyActivity.UNINSTALL_PACKAGE);
intent.setComponent(new ComponentName(ShelterService.this, DummyActivity.class));
intent.putExtra("package", app.getPackageName());
// Send the callback to the DummyActivity
Bundle callbackExtra = new Bundle();
callbackExtra.putBinder("callback", callback.asBinder());
intent.putExtra("callback", callbackExtra);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
DummyActivity.registerSameProcessRequest(intent);
startActivity(intent);
} else {
if (mIsProfileOwner) {
// This is essentially the same as disabling the system app
// There is no way to reverse the "enableSystemApp" operation here
mPolicyManager.setApplicationHidden(
mAdminComponent,
app.getPackageName(), true);
callback.callback(Activity.RESULT_OK);
} else {
callback.callback(RESULT_CANNOT_INSTALL_SYSTEM_APP);
}
}
}
private void startKiller() {
// Start the sticky KillerService to kill the ShelterService
// for us when we are removed from tasks
// This is a dirty hack because no lifecycle events will be
// called when task is removed from recents
Intent intent = new Intent(this, KillerService.class);
Bundle bundle = new Bundle();
bundle.putBinder("main", mServiceMain.asBinder());
bundle.putBinder("work", mServiceWork.asBinder());
intent.putExtra("extra", bundle);
startService(intent);
}
static AppListFragment newInstance(IShelterService service, boolean isRemote) {
AppListFragment fragment = new AppListFragment();
Bundle args = new Bundle();
args.putBinder("service", service.asBinder());
args.putBoolean("is_remote", isRemote);
fragment.setArguments(args);
return fragment;
}
public static void putBinder(Bundle bundle, String key, IBinder value) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
bundle.putBinder(key, value);
} else {
Reflector.QuietReflector.with(bundle).method("putIBinder", String.class, IBinder.class).call(key, value);
}
}
/**
* Adds the required extras and flags to an {@link Intent} for using Chrome Custom Tabs. If
* Chrome Custom Tabs are not available or supported no change will be made to the {@link Intent}.
*
* @param context Application context
* @param intent The {@link Intent} to add the extras and flags to for Chrome Custom Tabs.
* @return The {@link Intent} supplied with additional extras and flags if Chrome Custom Tabs
* are supported and available.
*/
public static Intent addChromeCustomTabsExtras(Context context, Intent intent) {
if (SDK_INT >= JELLY_BEAN_MR2 && ChromeCustomTabs.isAvailable(context)) {
Bundle extras = new Bundle();
extras.putBinder("android.support.customtabs.extra.SESSION", null);
intent.putExtras(extras);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
return intent;
}
public static void putBinder(Bundle bundle, String key, IBinder value) {
if (Build.VERSION.SDK_INT >= 18) {
bundle.putBinder(key, value);
} else {
mirror.android.os.Bundle.putIBinder.call(bundle, key, value);
}
}
public static void putBinder(Bundle bundle, String key, IBinder iBinder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
bundle.putBinder(key, iBinder);
} else {
RefIectUtil.invokeMethod(bundle, Bundle.class, "putIBinder", new Class[]{String.class, IBinder.class}, new Object[]{key, iBinder});
}
}
public static void putBinder(Bundle bundle, String key, IBinder value) {
if (Build.VERSION.SDK_INT >= 18) {
bundle.putBinder(key, value);
} else {
if(putIBinder != null) {
try {
putIBinder.invoke(bundle, key, value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/** Puts an IBinder in a bundle safely. */
private static void putBinder(Bundle b, String key, IBinder val) {
if (null != PUT_IBINDER) {
try {
PUT_IBINDER.invoke(b, key, val);
return;
} catch (InvocationTargetException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
b.putBinder(key, val);
}
/**
* Returns the created options as a Bundle, which can be passed to
* {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
* Context.startActivity(Intent, Bundle)} and related methods.
* Note that the returned Bundle is still owned by the ActivityOptions
* object; you must not modify it, but can supply it to the startActivity
* methods that take an options Bundle.
*/
public Bundle toBundle() {
Bundle b = new Bundle();
if (mPackageName != null) {
b.putString(KEY_PACKAGE_NAME, mPackageName);
}
if (mLaunchBounds != null) {
b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds);
}
b.putInt(KEY_ANIM_TYPE, mAnimationType);
if (mUsageTimeReport != null) {
b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
}
switch (mAnimationType) {
case ANIM_CUSTOM:
b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
!= null ? mAnimationStartedListener.asBinder() : null);
break;
case ANIM_CUSTOM_IN_PLACE:
b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
break;
case ANIM_SCALE_UP:
case ANIM_CLIP_REVEAL:
b.putInt(KEY_ANIM_START_X, mStartX);
b.putInt(KEY_ANIM_START_Y, mStartY);
b.putInt(KEY_ANIM_WIDTH, mWidth);
b.putInt(KEY_ANIM_HEIGHT, mHeight);
break;
case ANIM_THUMBNAIL_SCALE_UP:
case ANIM_THUMBNAIL_SCALE_DOWN:
case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
// Once we parcel the thumbnail for transfering over to the system, create a copy of
// the bitmap to a hardware bitmap and pass through the GraphicBuffer
if (mThumbnail != null) {
final Bitmap hwBitmap = mThumbnail.copy(Config.HARDWARE, false /* isMutable */);
if (hwBitmap != null) {
b.putParcelable(KEY_ANIM_THUMBNAIL, hwBitmap.createGraphicBufferHandle());
} else {
Slog.w(TAG, "Failed to copy thumbnail");
}
}
b.putInt(KEY_ANIM_START_X, mStartX);
b.putInt(KEY_ANIM_START_Y, mStartY);
b.putInt(KEY_ANIM_WIDTH, mWidth);
b.putInt(KEY_ANIM_HEIGHT, mHeight);
b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
!= null ? mAnimationStartedListener.asBinder() : null);
break;
case ANIM_SCENE_TRANSITION:
if (mTransitionReceiver != null) {
b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
}
b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
b.putParcelable(KEY_RESULT_DATA, mResultData);
b.putInt(KEY_RESULT_CODE, mResultCode);
b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
break;
}
b.putBoolean(KEY_LOCK_TASK_MODE, mLockTaskMode);
b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode);
b.putInt(KEY_LAUNCH_ACTIVITY_TYPE, mLaunchActivityType);
b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
b.putBoolean(KEY_TASK_OVERLAY_CAN_RESUME, mTaskOverlayCanResume);
b.putBoolean(KEY_AVOID_MOVE_TO_FRONT, mAvoidMoveToFront);
b.putInt(KEY_SPLIT_SCREEN_CREATE_MODE, mSplitScreenCreateMode);
b.putBoolean(KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING,
mDisallowEnterPictureInPictureWhileLaunching);
if (mAnimSpecs != null) {
b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
}
if (mAnimationFinishedListener != null) {
b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
}
if (mSpecsFuture != null) {
b.putBinder(KEY_SPECS_FUTURE, mSpecsFuture.asBinder());
}
b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
if (mAppVerificationBundle != null) {
b.putBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE, mAppVerificationBundle);
}
if (mRemoteAnimationAdapter != null) {
b.putParcelable(KEY_REMOTE_ANIMATION_ADAPTER, mRemoteAnimationAdapter);
}
return b;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.main_menu_freeze_all:
// This is the same as clicking on the batch freeze shortcut
// so we just forward the request to DummyActivity
Intent intent = new Intent(DummyActivity.PUBLIC_FREEZE_ALL);
intent.setComponent(new ComponentName(this, DummyActivity.class));
startActivity(intent);
return true;
case R.id.main_menu_settings:
Intent settingsIntent = new Intent(this, SettingsActivity.class);
Bundle extras = new Bundle();
extras.putBinder("profile_service", mServiceWork.asBinder());
settingsIntent.putExtra("extras", extras);
startActivity(settingsIntent);
return true;
case R.id.main_menu_create_freeze_all_shortcut:
Intent launchIntent = new Intent(DummyActivity.PUBLIC_FREEZE_ALL);
launchIntent.setComponent(new ComponentName(this, DummyActivity.class));
launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Utility.createLauncherShortcut(this, launchIntent,
Icon.createWithResource(this, R.mipmap.ic_freeze),
"shelter-freeze-all", getString(R.string.freeze_all_shortcut));
return true;
case R.id.main_menu_install_app_to_profile:
Intent openApkIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
openApkIntent.addCategory(Intent.CATEGORY_OPENABLE);
openApkIntent.setType("application/vnd.android.package-archive");
startActivityForResult(openApkIntent, REQUEST_DOCUMENTS_CHOOSE_APK);
return true;
case R.id.main_menu_show_all:
Runnable update = () -> {
mShowAll = !item.isChecked();
item.setChecked(mShowAll);
LocalBroadcastManager.getInstance(this)
.sendBroadcast(new Intent(AppListFragment.BROADCAST_REFRESH));
};
if (!item.isChecked()) {
new AlertDialog.Builder(this)
.setMessage(R.string.show_all_warning)
.setPositiveButton(R.string.first_run_alert_continue,
(dialog, which) -> update.run())
.setNegativeButton(R.string.first_run_alert_cancel, null)
.show();
} else {
update.run();
}
return true;
}
return super.onOptionsItemSelected(item);
}
public static void putValueToBundle(
@NonNull Bundle bundle, @NonNull String key, @NonNull Object value) {
if (value instanceof String) {
bundle.putString(key, (String) value);
} else if (value instanceof Integer) {
bundle.putInt(key, (int) value);
} else if (value instanceof Boolean) {
bundle.putBoolean(key, (boolean) value);
} else if (value instanceof Long) {
bundle.putLong(key, (long) value);
} else if (value instanceof Short) {
bundle.putShort(key, (short) value);
} else if (value instanceof Double) {
bundle.putDouble(key, (double) value);
} else if (value instanceof Float) {
bundle.putFloat(key, (float) value);
} else if (value instanceof Character) {
bundle.putChar(key, (char) value);
} else if (value instanceof Byte) {
bundle.putByte(key, (byte) value);
} else if (value instanceof CharSequence) {
bundle.putCharSequence(key, (CharSequence) value);
} else if (value instanceof Bundle) {
bundle.putBundle(key, (Bundle) value);
} else if (value instanceof Parcelable) {
bundle.putParcelable(key, (Parcelable) value);
} else if (value instanceof String[]) {
bundle.putStringArray(key, (String[]) value);
} else if (value instanceof int[]) {
bundle.putIntArray(key, (int[]) value);
} else if (value instanceof boolean[]) {
bundle.putBooleanArray(key, (boolean[]) value);
} else if (value instanceof long[]) {
bundle.putLongArray(key, (long[]) value);
} else if (value instanceof short[]) {
bundle.putShortArray(key, (short[]) value);
} else if (value instanceof double[]) {
bundle.putDoubleArray(key, (double[]) value);
} else if (value instanceof float[]) {
bundle.putFloatArray(key, (float[]) value);
} else if (value instanceof char[]) {
bundle.putCharArray(key, (char[]) value);
} else if (value instanceof byte[]) {
bundle.putByteArray(key, (byte[]) value);
} else if (value instanceof CharSequence[]) {
bundle.putCharSequenceArray(key, (CharSequence[]) value);
} else if (value instanceof Parcelable[]) {
bundle.putParcelableArray(key, (Parcelable[]) value);
} else if (value instanceof ArrayList) {
bundle.putIntegerArrayList(key, (ArrayList<Integer>) value);
} else if (value instanceof SparseArray) {
bundle.putSparseParcelableArray(key, (SparseArray<? extends Parcelable>) value);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
if (value instanceof IBinder) {
bundle.putBinder(key, (IBinder) value);
return;
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (value instanceof Size) {
bundle.putSize(key, (Size) value);
return;
} else if (value instanceof SizeF) {
bundle.putSizeF(key, (SizeF) value);
return;
}
}
if (value instanceof Serializable) {
bundle.putSerializable(key, (Serializable) value);
return;
}
throw new RuntimeException(String.format(Locale.getDefault(),
"Arguments extra %s has wrong type %s.", key, value.getClass().getName()));
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private static void putBinerAPI18(Bundle data, String key, IBinder value) {
data.putBinder(key, value);
}