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.