WRITE_SETTINGS izni alınamıyor


85

Android M Preview 3'te 23 hedef API'ye sahip olduğumda, Manifest.permission.WRITE_SETTTINGS iznini alamıyorum.

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

İzin isteme, beklediğim diyaloğu getirmiyor, ancak aşağıdaki çağrıyı bu izin olmadan yaparsam,

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

Çağrı, iznim olmadığı için yapılacak.

Buradan nereye gideceğimi bilmiyorum. 23 için yeni bir zil sesi API'si var mı? Yoksa bu izin değişikliği, sistem dışı uygulamaların zil sesini değiştirmesini imkansız hale mi getirdi?

Yanıtlar:


134

WRITE_SETTINGSDokümanlara göre kullanmak için:

  1. Var <uses-permission>Normal olarak Manifestte elemanı.

  2. Settings.System.canWrite()Ayarları yazmak için uygun olup olmadığınızı öğrenmek için arayın .

  3. Eğer canWrite()döner false, başlangıç faaliyeti kullanıcı aslında ayarlarına yazmak için uygulamanızı izin orada hemfikir böylece.ACTION_MANAGE_WRITE_SETTINGS

Başka bir deyişle, ayarlara yazmak artık bir çift onay (yüklemeyi kabul edin, izin vermek için Ayarlar'da ayrı ayrı karar verin), cihaz yöneticisi API'lerine, erişilebilirlik hizmetlerine vb. Benzer.

Ayrıca bunları kullanmayı henüz denemediğimi de unutmayın - bu, dün Android 6.0 değişiklikleri üzerinde yaptığım araştırmaya dayanıyor .


Teşekkürler Mark! Bir cazibe gibi çalıştı. Developer.android.com/preview/features/runtime-permissions.html , izin istemek için birden fazla yeni yolumuz olacaksa, biraz güncellenmesi gerekiyor. (Blogunuzu yayınlamadan önce zaten okumuştum, ancak bu bilgiyi ihtiyacım olduğunda elimde
Justin

Bu gerçekten işe yaradı. Ancak son kullanıcı için bu kötü bir yaklaşım. Google'ın bu davranışı değiştirdiğine dair herhangi bir işaret var mı?
Fhl

2
@Fhl: dangerousAndroid 6.0'da başka şeylerle birlikte gittikleri normal çalışma zamanı izin yaklaşımı yerine neden bu rotaya gittiklerini bilmiyorum . Bu yakında herhangi bir zamanda değişirse şaşıracağım.
CommonsWare

2
uygulamanızı şu şekilde belirtebilirsiniz:intent.setData(Uri.parse("package:" + Context.getPackageName()));
Olegas Gončarovas

8
Unutulmaması gereken bir diğer nokta da, Android'de daha önce kullanıcının yukarıda açıklanan iletişim kutusunda yazma izinleri verdiği, geçiş anahtarının etkin konuma getirileceği ancak canWrite'ın false döndürdüğü bir uygulamaya neden olan bir hata var gibi görünüyor. CanWrite () yönteminin true değerini döndürmesi için, kullanıcının anahtarı kapatıp tekrar açması gerekir ... Bunu geliştirme aşamasında görüyorum ama umarım müşterilerin gördüğü bir şey olmayacaktır.
Matt Wolfe

45

CommonsWare'den gelen cevaba ve Ogix'ten gelen yoruma ek olarak, işte bazı kukla kodlar:

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;
}

Fragment PopupwritePermission daha sonra durumun açıklandığı bir pencere verir. Tamam Düğmesine tıklandığında, İznin verilebileceği Android Sistem Menüsü açılır:

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

40

Önceki cevaplar harika, izin istemek için sonucu almak için çok az eklemem var.

 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);
            }
        }
    }

Ve sonra Activity:

@SuppressLint("NewApi")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == MainActivity.CODE_WRITE_SETTINGS_PERMISSION && Settings.System.canWrite(this)){
            Log.d("TAG", "MainActivity.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 == MainActivity.CODE_WRITE_SETTINGS_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //do your code
        }
    }

Kodunuzu koydum ve verilen izin bile iyi çalışıyor, ancak yine de özel zil sesi atamıyor ve yine de Write_Setting izni reddedildi sorunu var.
Zia Ur Rahman

4
ActivityCompat.requestPermissions (bağlam, yeni String [] {Manifest.permission.WRITE_SETTINGS}, ....); kullanılamaz. Bu özel bir izin. Bu izni yalnızca belgelerde belirtildiği gibi bir niyetle talep edebiliriz. Ayrıca Marshmello'dan önce izin, yükleme sırasında kalıcı olarak verilir
Anonymous

2
@yshahak değişkeniniz MainActivity.CODE_WRITE_SETTINGS_PERMISSIONnedir?
Bruno Bieri

@BrunoBieri evet haklısın, bunu atladım. Cevabımı ayrıntılı olacak şekilde düzenleyeceğim.
yshahak

Öyleyse ne MainActivity.CODE_WRITE_SETTINGS_PERMISSION?
Konsollar

13

Bu tam bir örnek:

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);
    }
}

intent.setData (Uri.parse ("paket:" + getActivity (). getPackageName ()));
Ole K

8

Android Marshmellow itibariyle burada ihtiyaç olduğunda fazla güvenlik veya kullanım izni için hangi amaçlara çalışma zamanı izinlerini kullanmak gerektiren documenatation

ve Yazma Ayarları belgeleri için buradadır

Manifestte ekle

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

Sınıfında

private boolean checkSystemWritePermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if(Settings.System.canWrite(context))
            return true;
        else 
            openAndroidPermissionsMenu();
    }
    return false;
}

private void openAndroidPermissionsMenu() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
        intent.setData(Uri.parse("package:" + context.getPackageName()));
        context.startActivity(intent);
    }
}

Ve bunu böyle kullan

try {
       if (checkSystemWritePermission()) {
            RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, newUri);
            Toast.makeText(context, "Set as ringtoon successfully ", Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(context, "Allow modify system settings ==> ON ", Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            Log.i("ringtoon",e.toString());
            Toast.makeText(context, "unable to set as Ringtoon ", Toast.LENGTH_SHORT).show();
        }

5

İzin android.permission.WRITE_SETTINGSartık grupta ve signature|appop|pre23|preinstalledgibiandroid.permission.CHANGE_NETWORK_STATEandroid.permission.SYSTEM_ALERT_WINDOW

Bu, sdk 22 ve altı sürümlerde alacağınız anlamına gelir. Daha yeni sürümde, bir uygulama operatörü olmanız gerekir.


4

Feryat kullandım ..

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        boolean retVal = true;
        retVal = Settings.System.canWrite(this);
        if (retVal == false) {
            if (!Settings.System.canWrite(getApplicationContext())) {

                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName()));
                Toast.makeText(getApplicationContext(), "Please, allow system settings for automatic logout ", Toast.LENGTH_LONG).show();
                startActivityForResult(intent, 200);
            }
        }else {
            Toast.makeText(getApplicationContext(), "You are not allowed to wright ", Toast.LENGTH_LONG).show();
        }
    }

Manifest izni

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

2

AndroidManifest.xml'de aşağıdaki izinlerden bahsedin

Aktivitede ayarı değiştirmek için başka ise aşağıda kullanın.

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);
}

Lütfen bu izni kullanın. <uses-
allow

1

Kotlin Version in Simple Steps

Bu adımları takip et:

1.manifest.xml Normalde iznin kullanım öğesini ekleyin :

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

2. Ayarları değiştirmek istediğiniz yerde yazma erişimini kontrol edin:

if (context.canWriteSettings) {
    // change the settings here ...
} else {
    startManageWriteSettingsPermission()
}

3. Ayrıca izin isteme durumunda şu kod satırlarını ekleyin:

private fun startManageWriteSettingsPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        Intent(
            Settings.ACTION_MANAGE_WRITE_SETTINGS,
            Uri.parse("package:${context.packageName}")
        ).let {
            startActivityForResult(it, REQUEST_CODE_WRITE_SETTINGS_PERMISSION)
        }
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    when (requestCode) {
        REQUEST_CODE_WRITE_SETTINGS_PERMISSION -> {
            if (context.canWriteSettings) {
                // change the settings here ...
            } else {
                Toast.makeText(context, "Write settings permission is not granted!", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

val Context.canWriteSettings: Boolean
    get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.System.canWrite(this)

companion object {
    private const val REQUEST_CODE_WRITE_SETTINGS_PERMISSION = 5
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.