java - 尽管有 WRITE_SETTINGS 权限代码,应用程序在 Android OS v7.1 中仍会崩溃

标签 java android permissions

我创建了一个 Android 应用程序,可以在 OS v6.0/6.01 (Marshmallow) 上正常运行。当我在 OS v7.1 (Nougat) 上尝试它时,由于 WRITE_SETTINGS 要求,它崩溃了。添加添加的代码后,修改系统设置的屏幕会在 v6.0 中显示,但呈灰色。 v7.1 也会发生同样的情况,只是应用程序首先崩溃。

onCreate方法

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

    //***added code***
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.System.canWrite(getApplicationContext())) {
            Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
            intent.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
            startActivity(intent);
        }
    }


     if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_CODE_ASK_PERMISSIONS);
    }


    if (android.provider.Settings.System.getInt(getContentResolver(),
            Settings.System.ACCELEROMETER_ROTATION, 0) == 1) {

        android.provider.Settings.System.putInt(getContentResolver(),
                Settings.System.ACCELEROMETER_ROTATION, 0);
    }


    start = (Button) findViewById(R.id.button_start);
    start.setEnabled(true);

    stop = (Button) findViewById(R.id.button_stop);
    stop.setEnabled(true);

    confirm_ip = (Button) findViewById(R.id.button_confirm_ip);
    confirm_ip.setEnabled(true);
    confirm_ip.setOnClickListener(this);

    grab_device = (Button) findViewById(R.id.button_device);
    grab_device.setEnabled(true);
    grab_device.setOnClickListener(this);

    send = (Button) findViewById(R.id.button_send);
    send.setEnabled(false);
    send.setOnClickListener(this);

    clear_loc = (Button) findViewById(R.id.button_cl);
    clear_loc.setEnabled(true);
    clear_loc.setOnClickListener(this);

    device_name = (EditText) findViewById(R.id.et_device_name);
    device_name.setEnabled(true);

    location = (EditText) findViewById(R.id.et_location);
    location.setEnabled(true);

    scenario = (EditText) findViewById(R.id.et_scenario);
    scenario.setEnabled(true);

    distance = (EditText) findViewById(R.id.et_distance);
    distance.setEnabled(true);

    server_ip = (EditText) findViewById(R.id.et_server_ip);
    server_ip.setEnabled(true);
    server_ip.setText(R.string.server_ip);

    mAppStatus = (TextView) findViewById(R.id.tv_app_status);

    scenario_spinner = (Spinner) findViewById(R.id.spinner_scenario);
    scenario_spinner.setOnItemSelectedListener(this);

    ArrayAdapter<CharSequence> adp_scenario = ArrayAdapter.createFromResource(this, R.array.scenario_array,
            android.R.layout.simple_spinner_item);
    adp_scenario.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
    scenario_spinner.setAdapter(adp_scenario);


    distance_spinner = (Spinner) findViewById(R.id.spinner_distance);
    distance_spinner.setOnItemSelectedListener(this);

    ArrayAdapter<CharSequence> adp_distance = ArrayAdapter.createFromResource(this, R.array.distance_array,
            android.R.layout.simple_spinner_item);
    adp_distance.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
    distance_spinner.setAdapter(adp_distance);

    handler = new Handler(Looper.getMainLooper());

}

AndroidManifext.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.rssicollector">
<user-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

这是 v7.1 产生的错误

08-10 09:51:19.002 31732-31732/? E/AndroidRuntime: FATAL EXCEPTION: main
                                               Process: com.example.android.rssicollector, PID: 31732
                                               java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.rssicollector/com.example.android.rssicollector.MainActivity}: java.lang.SecurityException: com.example.android.rssicollector was not granted  this permission: android.permission.WRITE_SETTINGS.
                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2666)
                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727)
                                                   at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1478)
                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                   at android.os.Looper.loop(Looper.java:154)
                                                   at android.app.ActivityThread.main(ActivityThread.java:6121)
                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
                                                Caused by: java.lang.SecurityException: com.example.android.rssicollector was not granted  this permission: android.permission.WRITE_SETTINGS.
                                                   at android.os.Parcel.readException(Parcel.java:1684)
                                                   at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
                                                   at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
                                                   at android.content.ContentProviderProxy.call(ContentProviderNative.java:646)
                                                   at android.provider.Settings$NameValueCache.putStringForUser(Settings.java:1595)
                                                   at android.provider.Settings$System.putStringForUser(Settings.java:1965)
                                                   at android.provider.Settings$System.putIntForUser(Settings.java:2070)
                                                   at android.provider.Settings$System.putInt(Settings.java:2064)
                                                   at com.example.android.rssicollector.MainActivity.onCreate(MainActivity.java:132)
                                                   at android.app.Activity.performCreate(Activity.java:6682)
                                                   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2619)
                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727) 
                                                   at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1478) 
                                                   at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                   at android.os.Looper.loop(Looper.java:154) 
                                                   at android.app.ActivityThread.main(ActivityThread.java:6121) 
                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) 

关于发生了什么/如何解决它有什么想法吗?任何帮助将不胜感激!

最佳答案

if (android.provider.Settings.System.getInt(getContentResolver(),
        Settings.System.ACCELEROMETER_ROTATION, 0) == 1) {

    android.provider.Settings.System.putInt(getContentResolver(),
            Settings.System.ACCELEROMETER_ROTATION, 0);
}

仅当 Settings.System.canWrite(getApplicationContext()) 返回 true 时才执行该代码。现在,无论 canWrite() 返回什么,您都会执行该代码。

关于java - 尽管有 WRITE_SETTINGS 权限代码,应用程序在 Android OS v7.1 中仍会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45614517/

相关文章:

java - 更改后 Firebase 数据库无法正确同步

android - 覆盖其内容的 LinearLayout 的背景

android - 如何以编程方式更改android中的铃声?

postgresql - Postgres : Restricting users ability to view schemas

android - 权限映射问题

java - 为什么java不支持多重继承?

java - 我可以使用什么代替AudioPlayer.player.stop();?

c# - Windows 如何解决冲突的文件系统权限/权利?

java - 从 Eclipse 将多行插入到 oracle 数据库中

java - 从移动设备到服务器的强大文件传输