WRITE_SETTINGS की अनुमति नहीं मिल सकती


85

जब मेरे पास Android M पूर्वावलोकन 3 पर 23 का लक्ष्य API है, तो मैं Manifest.permission.WRITE_SETTTINGS अनुमति प्राप्त नहीं कर सकता।

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

अनुरोध की अनुमति से वह संवाद नहीं आएगा जिसकी मुझे अपेक्षा थी, लेकिन यदि मैं इस अनुमति के बिना निम्नलिखित कॉल करता / करती हूं,

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

कॉल को छोड़कर, क्योंकि मेरे पास अनुमति नहीं है।

मुझे यकीन नहीं है कि यहाँ से कहाँ जाना है। क्या 23 के लिए एक नया रिंगटोन एपीआई है? या क्या इस अनुमति परिवर्तन ने रिंगटोन को बदलने के लिए किसी भी गैर-सिस्टम एप्लिकेशन के लिए असंभव बना दिया है?

जवाबों:


134

WRITE_SETTINGSडॉक्स के आधार पर उपयोग करने के लिए :

  1. है <uses-permission>सामान्य रूप में प्रकट में तत्व।

  2. Settings.System.canWrite()यह देखने के लिए कॉल करें कि क्या आप सेटिंग लिखने के योग्य हैं।

  3. अगर canWrite()रिटर्न false, शुरू गतिविधि उपयोगकर्ता वहाँ सहमत कर सकते हैं ताकि वास्तव में सेटिंग्स के लिए लिखने के लिए अपने अनुप्रयोग अनुमति देने के लिए।ACTION_MANAGE_WRITE_SETTINGS

दूसरे शब्दों में, सेटिंग्स में लिखना अब एक डबल-ऑप्ट-इन (इंस्टॉल करने के लिए सहमत होना, सेटिंग्स में अलग से अनुमति देना), डिवाइस एडमिन एपीआई, एक्सेसिबिलिटी सर्विसेज, आदि के समान है।

यह भी ध्यान दें कि मैंने अभी तक इनका उपयोग करने की कोशिश नहीं की है - यह शोध पर आधारित है जो मैंने कल एंड्रॉइड 6.0 परिवर्तनों पर किया था


धन्यवाद मार्क! एक जादू की तरह काम किया। अगर हम अनुमतियों का अनुरोध करने के लिए कई नए तरीके करने जा रहे हैं, तो developer.android.com/preview/features/runtime-permissions.html को कुछ अपडेट करने की आवश्यकता है। (मैंने पोस्ट करने से पहले ही आपके ब्लॉग को पढ़ लिया था, लेकिन जाहिर है कि जब मुझे इसकी आवश्यकता हुई तो मैं उस जानकारी को नहीं रख पाया)
जस्टिन

यह काम किया, वास्तव में। लेकिन अंत उपयोगकर्ता के लिए यह एक बुरा तरीका है। Google का कोई भी संकेत इस व्यवहार को बदल रहा है?
फलां

2
@फल: मुझे नहीं पता कि वे नियमित dangerousरनटाइम अनुमति दृष्टिकोण के बजाय इस मार्ग पर क्यों गए, वे एंड्रॉइड 6.0 में अन्य चीजों के साथ गए थे। अगर जल्द ही इसमें कोई बदलाव होता है तो मुझे आश्चर्य होगा।
कॉमन्सवेयर

2
आप इस तरह से इरादे में अपने एप्लिकेशन को निर्दिष्ट कर सकते हैं:intent.setData(Uri.parse("package:" + Context.getPackageName()));
Olegas Gončarovas

8
ध्यान देने वाली एक और बात है कि एंड्रॉइड में एक बग प्रतीत होता है जो एक ऐप का कारण बनता है जो पहले स्थापित किया गया था जहां उपयोगकर्ता ने ऊपर वर्णित संवाद में लिखित अनुमति दी थी, जहां टॉगल स्विच को सक्षम स्थिति में रखा जाएगा, फिर भी गलत रिटर्न प्राप्त हो सकती है .. कैनव्रेइट () विधि को सही तरीके से प्राप्त करने के लिए उपयोगकर्ता को स्विच ऑफ और बैक को चालू करना होगा ... मैं इसे विकास में देखता हूं, लेकिन उम्मीद है कि यह कुछ ग्राहक नहीं होगा।
मैट वोल्फ

45

कॉमन्सवेयर के जवाब और ओगिक्स की टिप्पणी के अलावा, यहां कुछ डमी कोड हैं:

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 तब एक विंडो देता है जहां स्थिति को समझाया गया है। ओके बटन पर क्लिक करने पर एंड्रॉइड सिस्टम मेनू खुल जाएगा जहां अनुमति दी जा सकती है:

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

40

पिछले उत्तर बहुत अच्छे हैं, मेरे पास अनुमति मांगने के परिणाम को प्राप्त करने के लिए अभी बहुत कम है।

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

और फिर में 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
        }
    }

मैंने आपका कोड डाल दिया है, और यह ठीक काम करता है, यहां तक ​​कि अनुमति भी दी गई है, लेकिन फिर भी कस्टम रिंगटोन असाइन नहीं हो रही है और अभी भी Write_Setting अनुमति अस्वीकृत समस्या है।
जिया उर रहमान

4
ActivityCompat.requestPims (संदर्भ, नया स्ट्रिंग [] {घोषणापत्र। प्रविष्टि .RITE_SETTINGS}, ....); उपयोग नहीं किया जा सकता। इसकी विशेष अनुमति है। हम केवल इस आशय का अनुरोध एक अनुरोध के साथ कर सकते हैं जैसा कि प्रलेखन में कहा गया है। मार्शमेलो से पहले भी अनुमति स्थापित समय पर अनुमति दी गई है
अनाम

2
@ वैशाख आपका चर क्या है MainActivity.CODE_WRITE_SETTINGS_PERMISSION?
ब्रूनो बीरी

@BrunoBieri हाँ तुम सही हो, मैंने छोड़ दिया। मैं अपने उत्तर को संपादित करूँगा इसलिए यह क्रिया होगी।
यशक

तो क्या है MainActivity.CODE_WRITE_SETTINGS_PERMISSION?
ब्रैकेट्स

12

यह एक पूर्ण उदाहरण है:

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

आशय.सेटडाटा (उड़ी.पारसी ("पैकेज:" + गेटएक्टिविटी) (। getPackageName ()));
ओले के

7

एंड्रॉइड मार्शमॉलो के रूप में, आपको रनटाइम अनुमतियों का उपयोग करने की आवश्यकता होती है जो कि अधिक सुरक्षा के उद्देश्य से होती है, या यहां डॉक्यूमेंटेशन की आवश्यकता होने पर अनुमति का उपयोग करते हैं

और लिखने के लिए सेटिंग्स प्रलेखन यहाँ है

प्रकट जोड़ में

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

आपकी कक्षा में

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

और इसे इस तरह से उपयोग करें

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

अनुमति android.permission.WRITE_SETTINGSअब समूह की signature|appop|pre23|preinstalledतरह है android.permission.CHANGE_NETWORK_STATEऔरandroid.permission.SYSTEM_ALERT_WINDOW

इसका मतलब है कि आप इसे 22 और उससे नीचे के sdk पर प्राप्त करेंगे। नए संस्करण पर आपको एक ऐप ऑपरेटर बनना होगा।


4

मैं जैसे bellow इस्तेमाल किया है ..

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

प्रकट अनुमति

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

2

AndroidManifest.xml में अनुमति से नीचे उल्लेख करें

गतिविधि में नीचे अगर सेटिंग बदलने के लिए उपयोग करें।

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

कृपया इस अनुमति का उपयोग करें। <उपयोग-अनुमति android: नाम = "android.permission.WRITE_SETTINGS" />
सौरभ तेजराज

1

Kotlin Version in Simple Steps

इन कदमों का अनुसरण करें:

1. अनुमति के उपयोग तत्व को manifest.xmlसामान्य रूप से जोड़ें:

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

2. जहां आप सेटिंग बदलना चाहते हैं, लेखन पहुंच की जांच करें:

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

3. अनुमति के अनुरोध के मामले में कोड की इन पंक्तियों को भी जोड़ें:

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
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.