10

Trying to bring up an unaswered question I found here - How to highlight android setting app menu item?

As seen in this video https://www.youtube.com/watch?v=eHXBc5Mmsqs

The "Power Shade" menu item is being highlighted once you enter the screen. I am trying to add the same feature to my app, guiding users to an item in the settings menu using this highlight feature. I can't seem to find any information on how to actually implement this, nor do I know if it has a specific name I could search for.

Any help would be appreciated!

Hadar Shamir
  • 111
  • 1
  • 6

3 Answers3

16

After decompiling the app, here's how it works (simplified):

Intent intent = new Intent("com.samsung.accessibility.installed_service");
if (intent.resolveActivity(context.getPackageManager()) == null) {
    intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
}
    
final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args";
    
Bundle bundle = new Bundle();
String showArgs = context.getPackageName() + "/" + MyService.class.getName();
bundle.putString(EXTRA_FRAGMENT_ARG_KEY, showArgs);
intent.putExtra(EXTRA_FRAGMENT_ARG_KEY, showArgs);
intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, bundle);
    
try {
    context.startActivity(intent);
    String toastText = "Find PowerShade here";
    Toast.makeText(context, toastText, LENGTH_LONG).show();
} catch (Exception e) {
    // ask user to grant permission manually
}

Basically it's using undocumented features of Android (see SettingsActivity.java in Android source).

Lev Leontev
  • 2,538
  • 2
  • 19
  • 31
  • 1
    Is there something similar for SAW permission, perhaps? Starting from Android 11, using Settings.ACTION_MANAGE_OVERLAY_PERMISSION will ignore the package name, and instead will show a list of all apps that can have this permission: https://developer.android.com/reference/android/provider/Settings#ACTION_MANAGE_OVERLAY_PERMISSION . So maybe there is a way to at least scroll&highlight like here? – android developer Aug 07 '20 at 12:20
  • What the "MyService" should be? Also, any solution for the Settings.ACTION_MANAGE_OVERLAY_PERMISSION? I have the same issue with Android 11 and I want to guide the user to the specific app. – Kzaf Dec 09 '20 at 10:30
  • 1
    @Kzaf MyService is the service you're trying to grant the permissions to. Unfortunately I don't know the solution for Android 11 - just decompiled the code and posted it (almost) as is. – Lev Leontev Dec 10 '20 at 08:07
  • 1
    This is no longer working on new Samsung devices. Looks like they changed something? Anyone know how to make this work? – Tyler Mar 08 '21 at 17:13
5

A solution for the people who want to highlight Settings.ACTION_MANAGE_OVERLAY_PERMISSION or other permissions. AppSettings -> Highlight Permission

Example for Settings.ACTION_MANAGE_OVERLAY_PERMISSION:

private const val EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"
private const val EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args"
private const val EXTRA_SYSTEM_ALERT_WINDOW = "system_alert_window"

fun askForOverlayPermission(context: Context) {
    val intent = Intent(
        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
        Uri.parse("package:${context.packageName}")
    ).highlightSettingsTo(EXTRA_SYSTEM_ALERT_WINDOW)
    context.startActivity(intent)
}

private fun Intent.highlightSettingsTo(string: String): Intent {
    putExtra(EXTRA_FRAGMENT_ARG_KEY, string)
    val bundle = bundleOf(EXTRA_FRAGMENT_ARG_KEY to string)
    putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, bundle)
    return this
}

Keys for permission. install_other_apps,alarms_and_reminders, default_browseretc.

Harun Işık
  • 81
  • 1
  • 5
2

In Kotlin from a Fragment in which you want to check if the user has granted your app notification access. This code will scroll down to the list item and highlight it. Works on Android 11 with a Samsung S20 device. Use onActivityResult() or the new Activity result API inside the Fragment to check if the user has indeed granted the notification access permission.

private fun launchNotificationPermissionSettingsPageAndHighlight[your app]() {

        val intent = Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS").apply {
            val [your app] = "${requireContext().packageName}/${[your app service]::class.java.name}"
            val fragmentKey = ":settings:fragment_args_key"
            val showFragmentKey = ":settings:show_fragment_args"
            putExtra(fragmentKey, [your app])
            putExtra(showFragmentKey, Bundle().apply { putString(fragmentKey, [your app]) })
        }

        try {
            startActivityForResult(intent, requestCodeNotificationPermission)
            Toast.makeText(context, "Grant [your app] this permission", LENGTH_LONG).show()
        } catch (e: Exception) {
        }
    }
Rvb84
  • 675
  • 1
  • 6
  • 14