API to open app settings

Hi folks,

Is there a way to open OS app settings on iOS? (On Android it looks like we have Opening Device Settings on Android using Linking)

Non-expo example of what I’d like to be able to do:


I would use this to take users who have denied push notification settings to the settings page, should they choose to re-enable them.

Native code:

if let appSettings = NSURL(string: UIApplicationOpenSettingsURLString) {
            UIApplication.sharedApplication().openURL(appSettings)
}

Thank you!

1 Like

@aje do you mean Linking.openURL('app-settings:'); doesnt work for you in iOS?

https://snack.expo.io/@quinlanj/os-settings <-- (ie) does this snack redirect you to the settings page (it does for me on an iphone 7 plus)?

7 Likes

Hi @quinlanj, thanks for the response. You’re right, that works perfectly. I should have read the post I linked to better :slight_smile:

Thanks again!

I’d like to link to notifications settings. I found this:

https://stackoverflow.com/questions/44582694/react-native-open-settings-through-linking-openurl-in-ios#comment76271660_44582884 (comment)

It works for Expo client, like this: Linking.openURL("app-settings://notification/expo")

What should be the last part for a stand alone app? Is it expo.ios.bundleIdentifier from app.json, expo.slug, or something else?

1 Like

To answer @lazurski’s question, you use expo.ios.bundleIdentifier

Linking.openURL('app-settings://notification/<bundleIdentifier>')

2 Likes

Thanks for this snack demo, it works perfectly for me as well! :smiley:

what is the equivalent on Android?

https://docs.expo.io/versions/latest/sdk/intent-launcher/

thanks. im in managed mode, and tried this but still not opening :frowning:

IntentLauncher.startActivityAsync(IntentLauncher.ACTION_APP_NOTIFICATION_SETTINGS);

even with package name still not working:

IntentLauncher.startActivityAsync(IntentLauncher.ACTION_APP_NOTIFICATION_SETTINGS, { data: 'package:' + pkg  });

not sure what is going on with that particular intent type but here’s an example of using it for application details: https://snack.expo.io/@notbrent/launch. notice that in expo client you need to use host.exp.exponent as the package name

looks like this is different depending on the operating system version: https://stackoverflow.com/a/45192258/659988

you can use the extra field instead of putExtra

1 Like

Yup that one works. I mean its not ideal but at least takes me to the app’s settings screen. Do you think this one at least is not version dependent?

it does seem to work on all versions yeah, i’m not very familiar with these details. you could handle it so on android 8+ you open notifs directly easily with this: https://snack.expo.io/@notbrent/suspicious-milkshake

not sure if we expose the uid for the android 5-7 approach

actually a better way to get the package name is with expo-application:

import * as Application from 'expo-application';

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Button
          title="Open settings"
          onPress={() => {
            IntentLauncher.startActivityAsync(
              IntentLauncher.ACTION_APPLICATION_DETAILS_SETTINGS,
              {
                data: `package:${Application.applicationId}`,
              }
            );
          }}
        />
      </View>
    );
  }
}
2 Likes

Ah nice!
But yeah not sure what’s the best way to get Android version, to know if I should do one thing for v > 8 and for those before v8 …

import { Platform } from 'react-native';

// assuming this code is just running on android..
if (Platform.Version >= 26) {
  // do something for android 8+ (api 26 and higher)
} else {
  // do other thing
}

gotcha. didnt know 26 is for v8.
Thanks so much!

you can check out the mappings here: https://en.wikipedia.org/wiki/Android_version_history

1 Like

The following url scheme not open notification settings screen only the app settings, any way to open app notification settings directly?

you could use app-settings: and produces the same effect

Here working unified example:

import { Linking } from 'expo';
import * as Application from 'expo-application';
import * as IntentLauncher from 'expo-intent-launcher';

const open_settings = () => {
  // TODO: it might work on SDK 37?
  // Linking.openSettings();
  if (Platform.OS === 'ios') {
    Linking.openURL(`app-settings:`);
  } else {
    const bundleIdentifier = Application.applicationId;
    IntentLauncher.startActivityAsync(IntentLauncher.ACTION_APPLICATION_DETAILS_SETTINGS, {
      data: `package:${bundleIdentifier}`,
    });
  }
}

has @notbrent say, you must render open_settings button when the following conditon:

import { Platform } from 'react-native';

(Platform.OS === 'android' && Platform.Version >= 26) || Platform.OS === 'ios';