2015-08-18 9 views
58

Wenn ich eine Ziel-API von 23 auf Android M Preview 3 habe, kann ich nicht scheinen, die Manifest.permission.WRITE_SETTTINGS-Berechtigung zu erwerben.Kann nicht WRITE_SETTINGS Berechtigung

requestPermissions(new String[]{Manifest.permission.WRITE_SETTINGS}, 
       101); 

Antrag Erlaubnis bringen nicht den Dialog ich erwarten würde, aber wenn ich den folgenden Aufruf ohne diese Berechtigung,

RingtoneManager.setActualDefaultRingtoneUri(activity, RingtoneManager.TYPE_RINGTONE, ringUri); 

Der Anruf wird ausnehmen, weil ich die Erlaubnis nicht haben .

Ich bin mir nicht sicher, wohin ich von hier aus gehen soll. Gibt es eine neue Klingelton-API für 23? Oder hat diese Änderung der Berechtigung es für andere Nicht-System-Apps unmöglich gemacht, den Klingelton zu ändern?

Antwort

90

Um WRITE_SETTINGS, verwenden Sie basiert auf der Dokumentation:

  1. Haben die <uses-permission> Element im Manifest als normal.

  2. Call Settings.System.canWrite() um zu sehen, ob Sie Einstellungen schreiben können.

  3. Wenn canWrite()false zurückgibt, starten Sie the ACTION_MANAGE_WRITE_SETTINGS activity, damit der Benutzer zustimmen kann, dass Ihre App tatsächlich in Einstellungen schreiben kann.

IOW ist, um die Einstellungen zu schreiben jetzt ein Double-Opt-in (zustimmen, zu installieren separat in den Einstellungen stimmen zu ermöglichen), ähnlich Gerät Admin-APIs, Zugänglichkeit Dienste usw.

Beachten Sie auch, dass ich noch nicht versucht habe mit diesen — dies basiert auf research that I did yesterday on Android 6.0 changes basiert. android.permission.WRITE_SETTINGS

+0

Vielen Dank! Lief wie am Schnürchen. https://developer.android.com/preview/features/runtime-permissions.html benötigt einige Updates, wenn wir mehrere neue Möglichkeiten haben, um Berechtigungen anzufordern. (Ich hatte Ihren Blog schon gelesen, bevor Sie ihn gepostet haben, aber ich habe ihn offensichtlich nicht behalten, als ich ihn brauchte) – Justin

+0

Das hat in der Tat funktioniert. Aber für den Endnutzer ist das ein schlechter Ansatz. Gibt es Anzeichen dafür, dass Google dieses Verhalten ändert? – Fhl

+2

@Fhl: Ich weiß nicht, warum sie diesen Weg gegangen sind, anstatt den normalen 'gefährlichen' Laufzeitrechtsansatz, den sie mit anderen Dingen in Android 6.0 verfolgten. Ich werde überrascht sein, wenn sich das in absehbarer Zeit ändert. – CommonsWare

3

Die Erlaubnis ist jetzt in der Gruppe signature|appop|pre23|preinstalled wie android.permission.CHANGE_NETWORK_STATE und android.permission.SYSTEM_ALERT_WINDOW

Dies bedeutet, dass Sie es auf sdk 22 und unten zu bekommen. Bei neueren Versionen müssen Sie ein App-Betreiber sein.

30

Als Ergänzung zu der Antwort von CommonsWare, und der Kommentar von Ogix, hier einige Blindkode

private boolean checkSystemWritePermission() { 
    boolean retVal = true; 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
     retVal = Settings.System.canWrite(this); 
     Log.d(TAG, "Can Write Settings: " + retVal); 
     if(retVal){ 
      Toast.makeText(this, "Write allowed :-)", Toast.LENGTH_LONG).show(); 
     }else{ 
      Toast.makeText(this, "Write not allowed :-(", Toast.LENGTH_LONG).show(); 
      FragmentManager fm = getFragmentManager(); 
      PopupWritePermission dialogFragment = new PopupWritePermission(); 
      dialogFragment.show(fm, getString(R.string.popup_writesettings_title)); 
     } 
    } 
    return retVal; 
} 

Das Fragment PopupwritePermission wird dann ein Fenster geben, wo die Situation erklärt. Ein Klick auf der OK-Taste wird das Android-System-Menü öffnen, in dem kann die Erlaubnis erteilt bekommen:

private void openAndroidPermissionsMenu() { 
    Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); 
    intent.setData(Uri.parse("package:" + getActivity().getPackageName())); 
    startActivity(intent); 
} 
23

Die bisherigen Antworten sind groß, ich habe nur wenig zusätzlich für auch fragen, das Ergebnis für die Erlaubnis zu bekommen.

public static void youDesirePermissionCode(Activity context){ 
     boolean permission; 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      permission = Settings.System.canWrite(context); 
     } else { 
      permission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED; 
     } 
     if (permission) { 
      //do your code 
     } else { 
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { 
       Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); 
       intent.setData(Uri.parse("package:" + context.getPackageName())); 
       context.startActivityForResult(intent, MainActivity.CODE_WRITE_SETTINGS_PERMISSION); 
      } else { 
       ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_SETTINGS}, MainActivity.CODE_WRITE_SETTINGS_PERMISSION); 
      } 
     } 
    } 

Und dann in den Activity:

@SuppressLint("NewApi") 
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     if (requestCode == CODE_WRITE_SETTINGS_PERMISSION && Settings.System.canWrite(this)){ 
      Log.d("TAG", "CODE_WRITE_SETTINGS_PERMISSION success"); 
      //do your code 
     } 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
     if (requestCode == CODE_WRITE_SETTINGS_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      //do your code 
     } 
    } 
+0

I Setzen Sie Ihren Code, und es funktioniert gut, sogar die Erlaubnis erteilt, aber immer noch der benutzerdefinierte Klingelton ist nicht zuweisen und immer noch die Write_Setting Berechtigung verweigert. –

+2

ActivityCompat.requestPermissions (Kontext, neuer String [] {Manifest.permission.WRITE_SETTINGS}, ....); kann nicht benutzt werden. Es ist eine spezielle Erlaubnis. Wir können diese Erlaubnis nur mit der in der Dokumentation genannten Absicht anfordern. Auch vor Marshmello wird die Erlaubnis dauerhaft zur Installationszeit – Anonymous

6

Dies ist ein komplettes Beispiel:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
    if (Settings.System.canWrite(context) { 
     // Do stuff here 
    } 
    else { 
     Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS); 
     intent.setData(Uri.parse(“package:” + getActivity().getPackageName())); 
     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     startActivity(intent); 
    } 
} 
+0

intention.setData (Uri.parse ("package:" + getActivity(). GetPackageName())); –

1

Erwähnung unter Erlaubnis in AndroidManifest.xml

In Aktivität verwenden Sie unten, wenn sonst zum Ändern der Einstellung.

if(Settings.System.canWrite(this)){ 
    // change setting here 
} 
else{ 
    //Migrate to Setting write permission screen. 
    Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); 
    intent.setData(Uri.parse("package:" + mContext.getPackageName())); 
    startActivity(intent); 
} 
+0

Bitte benutzen Sie diese Erlaubnis.

Verwandte Themen