How Do I Disable AIRPLANE MODE tablet supports 4.4

2019-01-26 02:41发布

问题:

I have to disable AIRPLANE MODE and DATE TIME SETTINGS in my app, for that i used these intent filters but none of them works for me

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

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter>
           <action android:name="android.settings.AIRPLANE_MODE_SETTINGS" />
           <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

        <intent-filter>
           <action android:name="android.settings.DATE_SETTINGS" />
           <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

But earlier i successfully disabled Settings by using below intent-filter

        <intent-filter >
            <action android:name="android.settings.SETTINGS" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

回答1:

As for version 4.2 and up you are not able to control the Airplane mode programmatically.

You are able to do so only if the user has a rooted device.

As written in the API DOC:

"Some device settings defined by Settings.System are now read-only. If your app attempts to write changes to settings defined in Settings.System that have moved to Settings.Global, the write operation will silently fail when running on Android 4.2 and higher. Even if your value for android:targetSdkVersion and android:minSdkVersion is lower than 17, your app is not able to modify the settings that have moved to Settings.Global when running on Android 4.2 and higher."



回答2:

TLDR: Don't do that.

Think what happens if user couldn't enable airplane mode though if they want/should.
Important system settings cannot allowed to change from your app.

I recommend:

  1. Check airplane mode is disabled or not
  2. If enabled, prompt "this app is not work on airplane mode. open system settings app?" with "yes/cancel" dialog
  3. Close your app and/or open system settings app

EDIT: it looks like this:

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private void checkAirplaneMode() {
    int mode;
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        Log.v(TAG, "work with new api.");
        mode = Settings.Global.getInt(getActivity().getContentResolver(),
                Settings.Global.AIRPLANE_MODE_ON, 0);
    } else {
        Log.v(TAG, "work with old api.");
        mode = Settings.System.getInt(getActivity().getContentResolver(),
                Settings.System.AIRPLANE_MODE_ON, 0);
    }
    Log.v(TAG, "airplane mode: " + mode);

    if(mode == 1 /* airplane mode is on */) {
        new AlertDialog.Builder(getActivity()).setTitle("Sorry!")
                .setMessage("This app doesn't work with Airplane mode.\n"
                        + "Please disable Airplane mode.\n")
                .setPositiveButton("Open Settings", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startActivity(new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS));
                        getActivity().finish();
                    }
                })
                .setNegativeButton("Close app", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        getActivity().finish();
                    }
                })
                .show();
    }
}

here's some point.

  • Check Build.VERSION.SDK_INT to use Settings.Global for newer devices. Airplane mode is moved to here.
  • If mode == 1, device is in airplane mode.
  • Open airplane mode setting Activity by
    startActivity(new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS));