下面列出了android.content.Intent#getFlags ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
// Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
// generally not allowed, except if the caller specifies the task id the activity should
// be launched in.
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
/**
* Update given flags when being used to request {@link ComponentInfo}.
*/
private int updateFlagsForComponent(int flags, int userId, Intent intent) {
if (intent != null) {
if ((intent.getFlags() & Intent.FLAG_DIRECT_BOOT_AUTO) != 0) {
flags |= MATCH_DIRECT_BOOT_AUTO;
}
}
// Caller is asking for component details, so they'd better be
// asking for specific Direct Boot matching behavior
if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
| MATCH_DIRECT_BOOT_AWARE
| MATCH_DIRECT_BOOT_AUTO)) == 0) {
onImplicitDirectBoot(userId);
}
return flags;
}
@SuppressWarnings("ResourceType")
@TargetApi(Build.VERSION_CODES.KITKAT)
public static Uri ensureUriPermission(Context context, Intent intent) {
Uri uri = intent.getData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final int takeFlags = intent.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION;
context.getContentResolver().takePersistableUriPermission(uri, takeFlags);
}
return uri;
}
private void handleExternalPlayOnChromecast(final Intent intent) {
if(intent != null) {
// If we're connected to a chromecast when we receive this video to play, play it there, otherwise
// forward it on to the local player. HOWEVER, we need to skip this if the calling Intent's class name
// is YouTubePlayerActivity, otherwise we'll get stuck in an endless loop!
if(intent.getAction() != null &&
intent.getAction().equals(Intent.ACTION_VIEW) &&
!intent.getComponent().getClassName().equals(YouTubePlayerActivity.class.getName()) &&
(intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
/**
* If a default Chromecast has been set for videos received via an external app (AutoCast), show the
* loading spinner and save the intent (which contains the video to play). When the Chromecast (route) is
* discovered above, it will find the default Chromecast and connect to it. Once the connection is
* established, {@link #handleExternalPlayOnChromecast(Intent)} will be called again, this time with
* externalPlayIntent set, which will allow the video to be launched on the Chromecast. Also only do
* this if we aren't already connected to a Chromecast.
*/
final boolean connectedToChromecast = YouTubePlayer.isConnectedToChromecast();
if(launchExternalOnDefaultChromecast(this) && externalPlayIntent == null && !connectedToChromecast) {
showLoadingSpinner();
externalPlayIntent = intent;
} else {
if (connectedToChromecast) {
new GetVideoDetailsTask(this, intent, (videoId, video) -> playVideoOnChromecast(video, 0)).executeInParallel();
} else {
Intent i = new Intent(this, YouTubePlayerActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
i.setAction(Intent.ACTION_VIEW);
i.setData(intent.getData());
startActivity(i);
finish(); // Finish this activity, so that the back button returns to the app that launched this video
}
}
}
}
}
@Override
protected void onResume() {
super.onResume();
final Intent intent = getIntent();
this.setIntent(intent);
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
return;
}
NFCReaderX.scanFromActivity(this, intent);
}
@Override
public void onReceive(Context context, Intent intent) {
if (mApp.isBooting()) {
return;
}
if ((intent.getFlags() & FLAG_RECEIVER_REGISTERED_ONLY) != 0 || isInitialStickyBroadcast()) {
return;
}
PendingResult result = goAsync();
synchronized (mAMS) {
if (!mAMS.handleStaticBroadcast(appId, info, intent, new PendingResultData(result))) {
result.finish();
}
}
}
@Override
protected void onResume() {
super.onResume();
final Intent intent = getIntent();
this.setIntent(intent);
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
return;
}
}
@Override
public final void onActivityResult(final int requestCode, final int resultCode, final Intent resultData)
{
if (resultCode == AppCompatActivity.RESULT_OK && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
//if (requestCode == REQUEST_CODE_STORAGE_ACCESS)
//{
// Get Uri from Storage Access Framework.
Uri treeUri = resultData.getData();
if(!treeUri.toString().endsWith("%3A"))
{
//show the user that we are not happy
Toast.makeText(this, R.string.please_sd_root, Toast.LENGTH_LONG).show();
return;
}
// Persist URI in shared preference so that you can use it later.
SharedPreferences sharedPreferences = getSharedPreferences(PREFERENCES_GENERAL_FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("sdcard_uri", treeUri.toString());
editor.apply();
LibraryService.TREE_URI = treeUri;
// Persist access permissions, so you dont have to ask again
final int takeFlags = resultData.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Toast.makeText(this, getString(R.string.perm_granted) + " : " + treeUri, Toast.LENGTH_LONG).show();
//}
}
}
public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
boolean ordered, boolean sticky, int sendingUser) {
super(resultCode, resultData, resultExtras,
mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
mCurIntent = intent;
mOrdered = ordered;
}
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity)null, intent, -1, options);
}
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity)null, intent, -1, options);
}
public List<R> queryIntentFromList(Intent intent, String resolvedType, boolean defaultOnly,
ArrayList<F[]> listCut) {
ArrayList<R> resultList = new ArrayList<R>();
final boolean debug = localLOGV || ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
final String scheme = intent.getScheme();
int N = listCut.size();
for (int i = 0; i < N; ++i) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme, listCut.get(i), resultList);
}
sortResults(resultList);
return resultList;
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// If it is not launched from history, then reset to top-level
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
if (mFirstHeader != null && !onIsHidingHeaders() && onIsMultiPane()) {
switchToHeaderLocal(mFirstHeader);
}
getListView().setSelectionFromTop(0, 0);
}
}
public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly) {
String scheme = intent.getScheme();
ArrayList<R> finalList = new ArrayList<R>();
final boolean debug = localLOGV || ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
if (debug)
VLog.v(TAG, "Resolving type=" + resolvedType + " scheme=" + scheme + " defaultOnly=" + defaultOnly + " of "
+ intent);
F[] firstTypeCut = null;
F[] secondTypeCut = null;
F[] thirdTypeCut = null;
F[] schemeCut = null;
// If the intent includes a MIME type, then we want to collect all of
// the filters that match that MIME type.
if (resolvedType != null) {
int slashpos = resolvedType.indexOf('/');
if (slashpos > 0) {
final String baseType = resolvedType.substring(0, slashpos);
if (!baseType.equals("*")) {
if (resolvedType.length() != slashpos + 2 || resolvedType.charAt(slashpos + 1) != '*') {
// Not a wild card, so we can just look for all filters
// that
// completely match or wildcards whose base type
// matches.
firstTypeCut = mTypeToFilter.get(resolvedType);
if (debug)
VLog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
secondTypeCut = mWildTypeToFilter.get(baseType);
if (debug)
VLog.v(TAG, "Second type cut: " + Arrays.toString(secondTypeCut));
} else {
// We can match anything with our base type.
firstTypeCut = mBaseTypeToFilter.get(baseType);
if (debug)
VLog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
secondTypeCut = mWildTypeToFilter.get(baseType);
if (debug)
VLog.v(TAG, "Second type cut: " + Arrays.toString(secondTypeCut));
}
// Any */* types always apply, but we only need to do this
// if the intent type was not already */*.
thirdTypeCut = mWildTypeToFilter.get("*");
if (debug)
VLog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut));
} else if (intent.getAction() != null) {
// The intent specified any type ({@literal *}/*). This
// can be a whole heck of a lot of things, so as a first
// cut let's use the action instead.
firstTypeCut = mTypedActionToFilter.get(intent.getAction());
if (debug)
VLog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut));
}
}
}
// If the intent includes a data URI, then we want to collect all of
// the filters that match its scheme (we will further refine matches
// on the authority and path by directly matching each resulting
// filter).
if (scheme != null) {
schemeCut = mSchemeToFilter.get(scheme);
if (debug)
VLog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut));
}
// If the intent does not specify any data -- either a MIME type or
// a URI -- then we will only be looking for matches against empty
// data.
if (resolvedType == null && scheme == null && intent.getAction() != null) {
firstTypeCut = mActionToFilter.get(intent.getAction());
if (debug)
VLog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut));
}
FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
if (firstTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme, firstTypeCut, finalList);
}
if (secondTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme, secondTypeCut, finalList);
}
if (thirdTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme, thirdTypeCut, finalList);
}
if (schemeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme, schemeCut, finalList);
}
sortResults(finalList);
if (debug) {
VLog.v(TAG, "Final result list:");
for (int i = 0; i < finalList.size(); i++) {
VLog.v(TAG, " " + finalList.get(i));
}
}
return finalList;
}
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("android"))
return;
XC_MethodHook hook = new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
settingsHelper.reload();
if (settingsHelper.isModDisabled())
return;
Intent intent = (Intent) XposedHelpers.getObjectField(param.thisObject, "intent");
// The launching app does not expect data back. It's safe to run the activity in a
// new task.
int requestCode = getIntField(param.thisObject, "requestCode");
if (requestCode != -1)
return;
// The intent already has FLAG_ACTIVITY_NEW_TASK set, no need to do anything.
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == Intent.FLAG_ACTIVITY_NEW_TASK)
return;
String intentAction = intent.getAction();
// If the intent is not a known safe intent (as in, the launching app does not expect
// data back, so it's safe to run in a new task,) ignore it straight away.
if (intentAction == null)
return;
// If the app is launching one of its own activities, we shouldn't open it in a new task.
int uid = ((ActivityInfo) getObjectField(param.thisObject, "info")).applicationInfo.uid;
if (getIntField(param.thisObject, "launchedFromUid") == uid)
return;
ComponentName componentName = (ComponentName) getObjectField(param.thisObject, "realActivity");
String componentNameString = componentName.flattenToString();
// Log if necessary.
if (settingsHelper.isLogEnabled()) {
// Get context
Context context = AndroidAppHelper.currentApplication();
if (context != null)
context.sendBroadcast(new Intent(Common.INTENT_LOG).putExtra(Common.INTENT_COMPONENT_EXTRA, componentNameString));
else
XposedBridge.log("activityforcenewtask: couldn't get context.");
XposedBridge.log("activityforcenewtask: componentString: " + componentNameString);
}
// If the blacklist is used and the component is in the blacklist, or if the
// whitelist is used and the component isn't whitelisted, we shouldn't modify
// the intent's flags.
boolean isListed = settingsHelper.isListed(componentNameString);
String listType = settingsHelper.getListType();
if ((listType.equals(Common.PREF_BLACKLIST) && isListed) ||
(listType.equals(Common.PREF_WHITELIST) && !isListed))
return;
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
};
Class ActivityRecord = findClass("com.android.server.am.ActivityRecord", lpparam.classLoader);
XposedBridge.hookAllConstructors(ActivityRecord, hook);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// Close the menu
if (Intent.ACTION_MAIN.equals(intent.getAction())) {
// also will cancel mWaitingForResult.
closeSystemDialogs();
if (mTransitionEffectDialog != null) {
mTransitionEffectDialog.cancel();
}
final boolean alreadyOnHome = mHasFocus
&& ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
if (mWorkspace == null) {
// Can be cases where mWorkspace is null, this prevents a NPE
return;
}
Folder openFolder = mWorkspace.getOpenFolder();
// In all these cases, only animate if we're already on home
mWorkspace.exitWidgetResizeMode();
if (alreadyOnHome && mState == State.WORKSPACE
&& !mWorkspace.isTouchActive() && openFolder == null
&& shouldMoveToDefaultScreenOnHomeIntent()) {
mWorkspace.moveToDefaultScreen(true);
}
closeFolder();
exitSpringLoadedDragMode();
// If we are already on home, then just animate back to the
// workspace,
// otherwise, just wait until onResume to set the state back to
// Workspace
if (alreadyOnHome) {
showWorkspace(true);
} else {
mOnResumeState = State.WORKSPACE;
}
final View v = getWindow().peekDecorView();
if (v != null && v.getWindowToken() != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
// Reset the apps customize page
if (!alreadyOnHome && mAppsCustomizeLayout != null) {
mAppsCustomizeLayout.reset();
}
onHomeIntent();
}
}
private boolean compareFlags(Intent other) {
return other != null && this.getFlags() == other.getFlags();
}
/**
* Broadcast the given intent to all interested BroadcastReceivers. This
* call is asynchronous; it returns immediately, and you will continue
* executing while the receivers are run.
*
* @param intent
* The Intent to broadcast; all receivers matching this Intent
* will receive the broadcast.
*
* @see #registerReceiver
*/
public boolean sendBroadcast(Intent intent) {
synchronized (mReceivers) {
final String action = intent.getAction();
final String type = intent.resolveTypeIfNeeded(mAppContext
.getContentResolver());
final Uri data = intent.getData();
final String scheme = intent.getScheme();
final Set<String> categories = intent.getCategories();
final boolean debug = DEBUG
|| ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
if (debug)
Log.v(TAG, "Resolving type " + type + " scheme " + scheme
+ " of intent " + intent);
ArrayList<ReceiverRecord> entries = mActions
.get(intent.getAction());
if (entries != null) {
if (debug)
Log.v(TAG, "Action list: " + entries);
ArrayList<ReceiverRecord> receivers = null;
for (int i = 0; i < entries.size(); i++) {
ReceiverRecord receiver = entries.get(i);
if (debug)
Log.v(TAG, "Matching against filter " + receiver.filter);
if (receiver.broadcasting) {
if (debug) {
Log.v(TAG, " Filter's target already added");
}
continue;
}
int match = receiver.filter.match(action, type, scheme,
data, categories, "LocalBroadcastManager");
if (match >= 0) {
if (debug)
Log.v(TAG,
" Filter matched! match=0x"
+ Integer.toHexString(match));
if (receivers == null) {
receivers = new ArrayList<ReceiverRecord>();
}
receivers.add(receiver);
receiver.broadcasting = true;
} else {
if (debug) {
String reason;
switch (match) {
case IntentFilter.NO_MATCH_ACTION:
reason = "action";
break;
case IntentFilter.NO_MATCH_CATEGORY:
reason = "category";
break;
case IntentFilter.NO_MATCH_DATA:
reason = "data";
break;
case IntentFilter.NO_MATCH_TYPE:
reason = "type";
break;
default:
reason = "unknown reason";
break;
}
Log.v(TAG, " Filter did not match: " + reason);
}
}
}
if (receivers != null) {
for (int i = 0; i < receivers.size(); i++) {
receivers.get(i).broadcasting = false;
}
mPendingBroadcasts.add(new BroadcastRecord(intent,
receivers));
if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {
mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);
}
return true;
}
}
}
return false;
}
private Object proceed(final Object proxy, final Method method, final Object[] args) throws Throwable {
final String method_name = method.getName();
OutboundType outbound_type = null;
switch (method_name) {
case "queryIntentServices":
outbound_type = OutboundType.QUERY_SERVICES;
if (IPackageManager_queryIntentServices == null) IPackageManager_queryIntentServices = method;
if (args[0] == DUMMY_INTENT) return null; // Short-circuit for capturing IPackageManager_queryIntentServices.
case "queryIntentReceivers":
if (outbound_type == null) outbound_type = OutboundType.QUERY_RECEIVERS;
final Object result = super.invoke(proxy, method, args);
final List<ResolveInfo> list = mCondom.proceedQuery(outbound_type, (Intent) args[0], () -> asList(result),
outbound_type == OutboundType.QUERY_SERVICES ? CondomCore.SERVICE_PACKAGE_GETTER : CondomCore.RECEIVER_PACKAGE_GETTER); // Both "queryIntentServices" and "queryIntentReceivers" reach here.
if (list.isEmpty()) asList(result).clear(); // In case Collections.emptyList() is returned due to targeted query being rejected by outbound judge.
return result;
case "resolveService":
// Intent flags could only filter background receivers, we have to deal with services by ourselves.
final Intent intent = (Intent) args[0];
final int original_intent_flags = intent.getFlags();
return mCondom.proceed(OutboundType.QUERY_SERVICES, intent, null, () -> {
if (! mCondom.mExcludeBackgroundServices && mCondom.mOutboundJudge == null)
return (ResolveInfo) CondomProcessPackageManager.super.invoke(proxy, method, args);
if (IPackageManager_queryIntentServices == null) {
mCondom.mBase.getPackageManager().queryIntentServices(DUMMY_INTENT, 0);
if (IPackageManager_queryIntentServices == null)
throw new IllegalStateException("Failed to capture IPackageManager.queryIntentServices()");
}
final List<ResolveInfo> candidates = asList(CondomProcessPackageManager.super.invoke(proxy, IPackageManager_queryIntentServices, args));
return mCondom.filterCandidates(OutboundType.QUERY_SERVICES, intent.setFlags(original_intent_flags), candidates, FULL_TAG, false);
});
case "resolveContentProvider":
final ProviderInfo provider = (ProviderInfo) super.invoke(proxy, method, args);
final int flags = (int) args[1];
if ((flags & PackageManager.MATCH_ALL) != 0) return provider; // MATCH_ALL will be used by the hooked IActivityManager.getContentProvider().
return mCondom.shouldAllowProvider(provider) ? provider : null;
case "getInstalledApplications":
case "getInstalledPackages":
mCondom.logConcern(FULL_TAG, "IPackageManager." + method_name);
break;
}
return super.invoke(proxy, method, args);
}
/**
* Whether a browser receiving the given intent should always use browser UI and avoid using any
* custom tabs UI.
*
* @param intent The intent to check for the required flags and extras.
* @return Whether the browser UI should be used exclusively.
*/
public static boolean shouldAlwaysUseBrowserUI(Intent intent) {
return intent.getBooleanExtra(EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, false)
&& (intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0;
}