23

पर कोई प्रभाव नहीं पड़ता है यह के नए मॉडल के संबंध में Manifest.permission.WRITE_EXTERNAL_STORAGE अनुमति का अनुरोध करते समय है।रनटाइम पर WRITE_EXTERNAL_STORAGE अनुमति का अनुरोध करने और अनुमति देने से वर्तमान सत्र

संक्षेप में, मैं क्या अनुभव कर रहा हूँ कि अगर मैं अनुरोध करता हूँ (और उपयोगकर्ता की अनुमति देता है) Manifest.permission.WRITE_EXTERNAL_STORAGE अनुमति एप्लिकेशन को पढ़ सकते हैं और बाह्य भंडारण निर्देशिका से लिखना जब तक मैं को नष्ट करने और एप्लिकेशन को पुनः आरंभ करने में सक्षम नहीं होगा है

यह मैं क्या कर रहा हूँ/का सामना कर रहा है:

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

यह वह जगह है, मैं बाहरी संग्रहण तक पहुंचने के लिए अनुमति नहीं है:

मेरा ऐप एक राज्य है जहां से शुरू होता है।

फिर, मैं Manifest.permission.WRITE_EXTERNAL_STORAGE की अनुमति का अनुरोध गूगल बताते

private void requestWriteExternalStoragePermission() { 
    // Should we show an explanation? 
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { 
     new AlertDialog.Builder(this) 
       .setTitle("Inform and request") 
       .setMessage("You need to enable permissions, bla bla bla") 
       .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         ActivityCompat.requestPermissions(MendeleyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_PERMISSION_WRITE_EXTERNAL_STORAGE); 
        } 
       }) 
       .show(); 
    } else { 
     ActivityCompat.requestPermissions(MendeleyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_PERMISSION_WRITE_EXTERNAL_STORAGE); 
    } 
} 

एक बार उपयोगकर्ता की अनुमति की अनुमति देता है बस के रूप में, onRequestPermissionsResult लागू हो जाता है।

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case RC_PERMISSION_WRITE_EXTERNAL_STORAGE: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 && PackageManager.PERMISSION_GRANTED 
       // allowed 
      } else { 
       // denied 
      } 
      break; 
     } 
    } 
} 

allowed ब्लॉक निष्पादित किया जाता है, इस बात की पुष्टि उपयोगकर्ता अनुमति दे दी है।

इसके बाद तुरंत, यदि मैं फिर से ऐप को नष्ट नहीं करता और खोलता हूं, तो मुझे अभी भी बाहरी संग्रहण के लिए कोई एक्सेस अनुमति नहीं है। अधिक विशेष रूप से:

hasWriteExternalStoragePermission();     // returns true 
Environment.getExternalStorageDirectory().canRead(); // RETURNS FALSE!! 
Environment.getExternalStorageDirectory().canWrite(); // RETURNS FALSE!! 

इसलिए, यह एंड्रॉयड क्रम सोचता है कि मैं अनुमतियाँ लगता है, लेकिन फाइल सिस्टम Environment.getExternalStorageDirectory() तक पहुँचने का प्रयास वास्तव में नहीं है ... , अपवाद फेंकता है:

android.system.ErrnoException: open failed: EACCES (Permission denied) 
at libcore.io.Posix.open(Native Method) 
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) 
at libcore.io.IoBridge.open(IoBridge.java:438) 
at java.io.FileOutputStream.<init>(FileOutputStream.java:87)  
at java.io.FileOutputStream.<init>(FileOutputStream.java:72)  

अगर अब मैं ऐप को नष्ट कर देता हूं और इसे फिर से खोलता हूं, व्यवहार को बाहरी भंडारण फ़ोल्डर में पढ़ने और लिखने में सक्षम होने के कारण बनना चाहिए।

क्या कोई इसका अनुभव कर रहा है?

मैं के साथ एक आधिकारिक एमुलेटर उपयोग कर रहा हूँ:

  • नवीनतम एंड्रॉयड 6.0 (एपीआई 23) एपीआई 23, रेव 1.
  • एम्यूलेटर चल इंटेल x86 एटम सिस्टम छवि, एपीआई 23, रेव 1.
  • android { 
        compileSdkVersion 23 
        buildToolsVersion "22.0.1" 
    
        defaultConfig { 
         minSdkVersion 16 
         targetSdkVersion 23 
        } 
    ... 
    } 
    

    कोई इस बात की पुष्टि करता है और मैं न केवल पर हूँ, तो:

मैं के साथ ऐप्लिकेशन का निर्माण मुझे लगता है कि हमें एक बग खोलने की आवश्यकता होगी, लेकिन मुझे आशा है कि मैं कुछ गलत कर रहा हूं, क्योंकि मुझे लगता है कि इस तरह की कोर फीचर एसडीके में छोटी गाड़ी होने की संभावना नहीं है।

+2

"क्या कोई इसका अनुभव कर रहा है?" - मैं नहीं हूं, लेकिन मैंने इसे एक एमुलेटर पर नहीं देखा है। मैं हार्डवेयर का उपयोग कर रहा हूँ। – CommonsWare

+0

फिर यह केवल एमुलेटर पर होने की संभावना है ... एक बार जब मैं एंड्रॉइड एम अपडेट प्राप्त करता हूं तो मैं अपडेट करूंगा। – GaRRaPeTa

+1

https://code.google.com/p/android-developer-preview/issues/detail?id=2982 – greywolf82

उत्तर

7

http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE:

एपीआई स्तर 19 में शुरू, इस अनुमति के अपना एप्लिकेशन-विशिष्ट निर्देशिका getExternalFilesDir (स्ट्रिंग) और getExternalCacheDir द्वारा लौटाए में पढ़ने के लिए/फ़ाइलें लिखने की आवश्यकता नहीं है()।

"रनटाइम अनुमति देने का अनुरोध" एपीआई स्तर 23 पर शुरू होता है, स्पष्ट रूप से 19 से ऊपर है, तो जब तक आप() फ़ोल्डर getExternalFilesDir द्वारा बताया के बाहर डेटा तक पहुँच रहे हैं अनुमति अब और आवश्यकता नहीं है,। तो मुझे विश्वास है कि यह एमुलेटर की एक बग है।

स्तर 1 के नीचे निचले लक्ष्य पर, जो रनटाइम पर अनुरोध अनुमति का समर्थन नहीं करता है, बस मैनिफेस्ट में अनुमति को कैलिम करें और यह काम करेगा।

+0

यह केवल आधा सच है। दुर्भाग्यवश लॉलीपॉप पर कुछ उपकरणों को अभी भी विशिष्ट अनुमतियों की आवश्यकता है, ताकि आपको एपीआई स्तर 1 9 और उससे ऊपर की अनुमति को हटाने से बचना चाहिए (मैंने ऐसा किया और अब मुझे इसे पुन: पेश करना होगा)। Http://stackoverflow.com/questions/27016647/why-do-i-need-the-write-external-storage-permission-with-getexternalcachedir-o?sgp=2 – sven

+0

@sven true देखें।लेकिन डॉक्टर के अनुसार, मैं अभी भी इसे एक बग के रूप में मानता हूं, भले ही मैं अभ्यास में भंडारण अनुमति का अनुरोध कर रहा हूं। – crazii

+0

@ क्राज़िल: 100% सहमत हैं। बस यह इंगित करने के लिए यहां क्लिक करें कि अन्य डेवलपर्स केवल यह पहचानने के लिए अनुमति को हटा दें कि उन्हें इसे फिर से जोड़ना होगा ... – sven

4

मुझे एक ही समस्या थी। यह एक बड़ा मुद्दा लगता है बाहर निकलता है। बाहरी भंडारण को लिखने की अनुमति को बदलने से इस प्रक्रिया के लिए जीआईडी ​​बदल जाता है (लिनक्स पक्ष पर)। आईडी बदलने के लिए प्रक्रिया को पुनरारंभ करना होगा। अगली बार जब आप ऐप खोलेंगे, तो नया समूह आईडी सेट होगा और अनुमति दी जाएगी।

लंबी कहानी छोटी, मुझे डर है यह एमुलेटर में एक बग नहीं है बल्कि वास्तव में लिनक्स और एंड्रॉइड के साथ एक बड़ा मुद्दा है।

मैं "हल" इस अनुमति के लिए पहली बार एप्लिकेशन निष्पादित किया जाता है पूछ और यह पुन: प्रारंभ जब अनुमति इस तरह दिया जाता है द्वारा:

PackageManager packageManager = getPackageManager(); 
        Intent intent = packageManager.getLaunchIntentForPackage(getPackageName()); 
        ComponentName componentName = intent.getComponent(); 
        Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName); 
        startActivity(mainIntent); 
        System.exit(0); 

आप एक ऐसी सेवा पृष्ठभूमि में चल रहा बनाने के लिए कोशिश कर सकते हैं (एक और प्रक्रिया आईडी है) और इसे अनुमति दे रहा है। इस तरह आपको केवल सेवा को पुनरारंभ करने की आवश्यकता होगी, न कि संपूर्ण ऐप। नीचे की ओर यह आपके लिए और अधिक काम कर सकता है।

उम्मीद है कि इससे मदद मिलती है।

--- संपादित करें ---

उपयोगकर्ता M66B (https://stackoverflow.com/a/32473449/1565635) संबंधित GIDs की एक सूची मिल गया। अधिक जानकारी यहां मिल सकती है: https://android.googlesource.com/platform/frameworks/base/+/master/data/etc/platform.xml

+0

हां, मुझे लगता है कि यह काम करता है और इसे स्वीकार किया जाना चाहिए – user755499

+0

सुनकर खुशी हुई! :) –

+1

कृपया एक नमूना परियोजना प्रदान करें जो इस समस्या को दर्शाती है। फिर, [एक मुद्दा दर्ज करना] पर विचार करें (http://b.android.com)। मुझे इससे कोई समस्या रिपोर्ट नहीं मिली है, और मैंने कभी भी इस व्यवहार को ऐप की उचित संख्या में नहीं देखा है। यदि समस्या 'canRead() '/' canWrite() 'तक सीमित है, तो शायद मैं कोई समस्या हो सकता हूं। लेकिन, वास्तव में पढ़ने और लिखने के लिए, आपको अनुमति अनुमति प्रभावी होने के लिए प्रक्रिया को पुनरारंभ करने की आवश्यकता नहीं है। – CommonsWare

संबंधित मुद्दे