简体   繁体   中英

How can I intercept the Intent when the user open another application?

Let's say the user open "Settings" application, is there a way to "intercept" this intent, from my app's service, in order to detect that "Settings" app is going to be openned?

For instance, in SOTI MobiControl app you can manage (from a web dashboard) the permissions of the user with the app installed (and enrolled to your server). If you don't allow one user to open Settings app, when he tries to open it, a toast appears saying "Unauthorized". How do they that?

Doing so is against Google Play Developer Program Policy, as it states in its System Interference section:

  • An app downloaded from Google Play (or its components or derivative elements) must not make changes to the user's device outside of the app without the user's knowledge and consent.

  • This includes behavior such as replacing or reordering the default presentation of apps, widgets, or the settings on the device. If an app makes such changes with the user's knowledge and consent, it must be clear to the user which app has made the change and the user must be able to reverse the change easily, or by uninstalling the app altogether.

  • Apps and their ads must not modify or add browser settings or bookmarks, add homescreen shortcuts, or icons on the user's device as a service to third parties or for advertising purposes.

  • Apps and their ads must not display advertisements through system
    level notifications on the user's device, unless the notifications
    derive from an integral feature provided by the installed app (eg, an airline app that notifies users of special deals, or a game that
    notifies users of in-game promotions).

  • Apps must not encourage, incentivize, or mislead users into removing or disabling third-party apps except as part of a security service
    provided by the app.

https://play.google.com/intl/ALL_us/about/developer-content-policy.html

Is there a way to "intercept" this intent, from my app's service, in order to detect that "Settings" app is going to be opened?

As other mentioned before it's not possible to intercept a launch intent.

For instance, in SOTI MobiControl app you can manage (from a web dashboard) the permissions of the user with the app installed (and enrolled to your server). If you don't allow one user to open Settings app, when he tries to open it, a toast appears saying "Unauthorized". How do they that?

It's however possible to determine if an app is opened and "intercept" that call. By intercept I mean draw over the starting app's screen and present a login screen or a not authorized screen.

I haven't worked out a full sample that would work an any Android version but from my research with AppLocks, I'd say it works more or less like this:

On pre-Lollipop Android you'd use this to retrieve the running processes:

    ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
    for (ActivityManager.RunningAppProcessInfo info : manager.getRunningAppProcesses()) {
        Log.e("TAG", "Running process: " + info.processName);
        if ("com.mycompany.mycoolapp".equals(info.processName)) {
           // do stuff...
        }
    }

requires:

<uses-permission android:name="android.permission.GET_TASKS"/>

or alternatively:

    for (ActivityManager.RunningTaskInfo recentTaskInfo : manager.getRunningTasks(100)) {
        Log.e("TAG", "Recent tasks: " + recentTaskInfo.baseActivity.getPackageName());
    }

On Lollipop and higher you'd use UsageStats to determine if an app is running:

    UsageStatsManager usageStatsManager = (UsageStatsManager)getSystemService(USAGE_STATS_SERVICE);
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.YEAR, -1);
    long start = cal.getTimeInMillis();
    long end = System.currentTimeMillis();
    List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, start, end);
    for (UsageStats stats : queryUsageStats) {
        Log.e("TAG", "Usage stats for: " + stats.getPackageName());
    }

requires:

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>

I would probably run both using the AlarmManager to perform that recurring task.

I'm fairly certain these are the two ways to get the list of running apps. If the permission for usage stats is denied to AppLock it's not working any more an Android 6.0 devices. On pre-M devices it however still works which is an indicator that the app has an alternative way to get the list of running apps (the first option described above).

Once it's determined an app has been started (it's running and hasn't been running the last time we checked), we can "take over" the screen. And that's how I'd do it: http://www.piwai.info/chatheads-basics/

Of course that's just the basic idea and I'm sure there are a couple of pitfalls when implementing a reliable solution but this should give you something to start with.

Let's say the user open "Settings" application, is there a way to "intercept" this intent, from my app's service, in order to detect that "Settings" app is going to be openned?

No, unless you are the one that is calling startActivity() to launch the application in the first place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM