I want to open the Settings-> Sound & Display-> Phone Ringtones screen from my application. How can I do that?
Depending on your needs, there are a couple of alternatives to bring up the 'Ringtones' settings screen from your application.
If you want to bring up the actual preferences screen that is usually available through system settings -- letting your user modify the phone's universal ringtone settings through your application -- you can use the ACTION_SOUND_SETTINGS constant from the android.provider.Settings class to create a new Intent to start the sound settings activity.
startActivityForResult(new Intent(android.provider.Settings.ACTION_SOUND_SETTINGS), 0);
If you want to select a custom ringtone to use in your application you need to add a RingtonePreference in your preferences.xml definition file, like this:
<RingtonePreference
android:key="alerts_ringtone"
android:title="Select ringtone"
android:showDefault="true"
android:showSilent="true"
android:ringtoneType=""
/>
You'll be able to get the URI to the selected preference in the application's default SharedPreferences using alerts_ringtone as the key.
The latter technique uses the PreferenceActivity class to host the preference options. I won't describe that in detail here, as the Android documentation has a good writeup and some sample code.
This is an alternate solution for the problem. I am also working in the same task but the above code does not work for me. I have changed the code to
startActivityForResult(new Intent(android.provider.Settings.ACTION_SOUND_SETTINGS), 0);
and it now works.
Related
I'm having troubles opening system DND preferences from my App so that user can create or edit Automatic Time rule.
Current situation
Our app already has a similar feature which disables App-notification LED, sound and vibration for some specific time period (for example between 10pm-8am) and is applied app-wide. As of Android Oreo, our feature doesn't work anymore because of Notification Channels. The only solution is, as far as I understand, to create in System preferences Automatic Time rule which is then applied system-wide.
What I want to do?
Just to redirect Oreo user from my app to System preferences ie. Do Not Disturb preferences in order to add or edit Time rule.
The problem
There is no specific Intent which opens Do Not Disturb preferences. The closest one I could find was Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS which leads me to this Preference screen. I also found action which I exactly need, but as you can see, it is hidden by annotation.
Does this mean there is no way to open this Preference screen and I should use another approach?
I also had this question for a long time, now I finally found the solution that works for me:
Java
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$ZenModeSettingsActivity"));
startActivity(intent);
Kotlin
val intent = Intent()
intent.component = ComponentName("com.android.settings", "com.android.settings.Settings\$ZenModeSettingsActivity")
startActivity(intent)
If you take a look at the AndroidManifest.xml for the Settings app you can see that there is an Activity Settings$ZenModeSettingsActivity (as mentioned by #cyb3rko in https://stackoverflow.com/a/63713587/467650) already from Android 5.0.
To send the user to the "Do not disturb" screen you can use the action android.settings.ZEN_MODE_SETTINGS like this:
try {
startActivity(new Intent("android.settings.ZEN_MODE_SETTINGS"));
} catch (ActivityNotFoundException e) {
// TODO: Handle activity not found
}
I would expect the intent filter to be even more stable than the class name.
I have an Android app with a PreferenceActivity, and one of the Preference entries launches one of my own activities (the "About" screen). The entry looks like this:
<PreferenceScreen android:title="#string/about.Title">
<intent ... />
</PreferenceScreen>
Also (and this is important), I use Gradle and a .debug application ID suffix for my debug builds. I install both the Play Store version and the debug version on my phone.
The question is: What kind of intent to use above? I know of two options, neither of which work:
Use an android:action intent with my own action string, and register that action string in my manifest with <intent-filter>.
If I use android:exported="false" in the manifest, then the activity fails to load on Android 7.1 when both apps are installed. (I get "Complete action using ... No apps can perform this action".) It works fine if only one is installed (either).
If I use android:exported="true", then not only am I exporting an internal Activity, but when I tap the preference, two instances of the activity are pushed on the stack (one for each app). If I install only one of the two apps, then only one instance shows up.
Use the android:targetPackage and android:androidClass approach, but then I don't know what to use for the package, since it's different for the release and debug versions (because of the suffix). One solution is to have a copy of the preferences.xml file in the debug resource folder with only the package changed, but this is bug-prone.
I was using option #1.1 for years but it recently broke on my phone, and I suspect the 7.1 update is to blame. I've never had cross-talk between these two installed apps before!
This has to be a pretty common pattern! Any ideas?
Please follow this steps:
After you add preferences using
addPreferencesFromResource(R.xml.preferences);
find your preference that you want to set onClick and define it by casting like
Preference pref = (Preference) findPreference("pref");
Then you can easily set its onClick using:
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(CurrentActivity.this, NextActivity.class));
return true;
}
});
I'm sure I'm overlooking something in the Settings class documentation. What Intent can open the Settings app in the "Do not disturb" section?
I expected it to be the ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS action, but that is only for the screen which lists which apps have requested DND access.
Update
Looking at the AndroidManifest.xml for the Settings app there is an Activity Settings$ZenModeSettingsActivity already from Android 5.0.
To send the user to the "Do not disturb" screen you can use the action android.settings.ZEN_MODE_SETTINGS like this:
try {
startActivity(new Intent("android.settings.ZEN_MODE_SETTINGS"));
} catch (ActivityNotFoundException e) {
// TODO: Handle activity not found
}
Original answer
It looks like there are no screens in the Settings app (at least on Android 6+7) where you can enable/disable DND. It seems like this is only available through the settings tile (and can be disabled in the dialog when changing the volume).
I have a Samsung S6 (Android 6.0.1) which has this screen, but this is probably some custom Samsung changes. The screen is represented by the class com.android.settings.Settings$ZenModeDNDSettingsActivity which can be started by any app. This might be of help for some people out there.
AndroidManifest.xml for Settings app for Android 6+7:
https://android.googlesource.com/platform/packages/apps/Settings/+/android-6.0.1_r68/AndroidManifest.xml
https://android.googlesource.com/platform/packages/apps/Settings/+/android-7.0.0_r6/AndroidManifest.xml
You have to use the following Intent: ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE and then pass a boolean through EXTRA_DO_NOT_DISTURB_MODE_ENABLED.
Make note that the documentation specifies the following: This intent MUST be started using startVoiceActivity.
I want to show only wi-fi settings fragment from settings. I have achieved this by using following code:
Intent i = new Intent(Settings.ACTION_SETTINGS);
i.putExtra(":android:show_fragment", "com.android.settings.wifi.WifiSettings");
i.putExtra(":android:no_headers", true);
startActivity(i);
Now I want to show only date & time fragment from settings so I changed my code to:
Intent i = new Intent(Settings.ACTION_SETTINGS);
i.putExtra(":android:show_fragment","com.android.settings.ACTION_DATE_SETTINGS");
i.putExtra(":android:no_headers", true);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
unfortunately it's not working.How can I display only specific Settings fragment from android inbuilt Settings app like this
I want to show only wi-fi settings fragment from settings. I have achieved this by using following code:
I would recommend that you use ACTION_WIFI_SETTINGS and get rid of the undocumented extras.
Now I want to show only date & time fragment from settings so I changed my code... unfortunately it's not working.
The right solution is to use ACTION_DATE_SETTINGS and get rid of the undocumented extras. Beyond that, com.android.settings.ACTION_DATE_SETTINGS is not the name of a fragment.
Evidently no_headers was silently removed from Android L and above... so we are out of luck. Re-write just select pieces of com.android.settings and block the standard settings through MDM - then pray for SYSTEM signature on your app.
Is there a way to detect that a phone has a default application chosen for an intent such as android.intent.action.SEND ?
Is there a way to clear the default application via code?
I'd like to give the user an option to remove the default or at least show a screen telling them how to do it manually, if I can detect it.
Take a look at PackageManager. With it, you can determine how an Intent will be handled with resolveActivity(intent). It looks like the method for clearing the preference (clearPackagePreferredActivities) only works on your own package.
Use 2-step detection of defaults:
PackageManager.queryIntentActivities to get all activities for Intent, PackageManager.resolveActivity to get resolved.
If resolved one is in the list returned by queryIntentActivities, then there will be no "Complete action using" dialog, thus "default" activity was set.