2014-05-07 10 views
16

हम सिर्फ नई अनुमतियां कि Android 4.4 पर एसडी कार्ड (बाह्य भंडारण) करने के लिए फ़ाइलों लेखन (EACCES अनुमति अस्वीकृत)एंड्रॉयड किटकैट

किटकैट से पहले हम स्थापित करने के लिए लागू की बेईमानी से गिर गया है एसडी कार्ड पर 4.4 फ़ोल्डर हमारे इस तरह लिखने योग्य फ़ोल्डर:

mfolder = Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.xyz.abc/appfiles"; 
:

mfolder = Environment.getExternalStorageDirectory().getPath() + "/appfiles"; 
हालांकि फ़ाइलें इस जरूरत के लेखन सक्षम करने के लिए 4.4 उपकरणों पर खोज कर रहा निष्कर्ष पर आए हैं, ठीक ही हो या गलत है कि घंटों के बाद

को परिवर्तित करने की

तो mfolder कुछ ऐसा होगा: /mnt/sdcard/Android/data/com.xyz.abc/appfiles

क्या यह सही है, क्या हम एसडीकार्ड पर ऊपर दिए गए फ़ोल्डर की तरह एक फ़ोल्डर बनाते हैं ताकि 4.4 डिवाइस सक्षम हो सकें फाइलें लिखो?

mfolder एक स्ट्रिंग है जिसे हम साझा प्राथमिकताओं में सहेजते हैं।

फिर हमारे पास यह कोड है जो एक बार चलाता है यदि API> = 19 जो mfolder स्ट्रिंग को बदलता है और फिर पुरानी फ़ोल्डर से सभी फ़ाइलों को नए 'किटकैट' फ़ोल्डर में कॉपी करता है।

if (android.os.Build.VERSION.SDK_INT>=19){ 
     if (!mfolder.contains("/Android/data/com.xyz.abc/appfiles")){ 
      if (prefs.getBoolean("kitkatcheck", false)==false){ 

       //update mfolder from 
         // /mnt/sdcard/appfiles 
         // to 
         // /mnt/sdcard/Android/data/com.xyz.abc/appfiles 
       String prekitkatfolder = mfolder; 
       String kitkatfolder = mfolder.replace("/appfiles", "/Android/data/com.xyz.abc/appfiles"); 
       mfolder = kitkatfolder; 
       try { 
        File sd = new File(mfolder); 
        if(!sd.exists() || !sd.isDirectory()) { 
         sd.mkdirs(); 
        } 
       } catch (Exception e) { 
        Toast.makeText(getBaseContext(), "Error creating Kitkat folder!\n" + e.toString(), Toast.LENGTH_LONG).show(); 
        return; 
       } 
       prefEditor.putString("patternfolder", mfolder); 
       prefEditor.putBoolean("kitkatcheck", true); 
       prefEditor.commit(); 

       //copy files and folder from old appfiles folder to new. 
       AllFiles.clear(); 
       listFilesAndFilesSubDirectories(prekitkatfolder); 
       if (AllFiles.size()>0){ 
        for (File child : AllFiles) { 
         try { 

          File dest = new File(child.toString().replace(prekitkatfolder, kitkatfolder)); 


          try { 
           String filePath = dest.getPath().substring(0, dest.getPath().lastIndexOf(File.separator)); 
           File subfolder = new File(filePath); 
           if(!subfolder.exists() || !subfolder.isDirectory()) { 
            subfolder.mkdirs(); 
           } 
          } catch (Exception ex) { 
          } 

          copyFile(child, dest); 

         } catch (Throwable t) { 

         } 
        } 

       } 


      } 

     } 

मैं तो उपयोगकर्ता है कि उनके फ़ाइलों को नए फ़ोल्डर में कॉपी किया गया है और कहा कि नई अनुमतियों के कारण वे मैन्युअल रूप से पुराने prekitkatfolder फ़ोल्डर हटाना होगा सूचित करें। मुझे लगता है कि अगर वे एक स्टॉक फाइल मैनेजर हैं या यदि वे नई 4.4 अनुमतियों के कारण एसडी कार्ड को अनमाउंट करते हैं और इसे पीसी में रखते हैं तो वे केवल ऐसा करने में सक्षम होंगे?

इसके अलावा, हमारे लिए ऐसा लगता है कि ये 4.4 अनुमतियां किटकैट के साथ हमारे सभी उपयोगकर्ताओं को प्रभावित नहीं कर रही हैं। कुछ अभी भी अपने बाहरी भंडारण पर मूल फ़ोल्डर स्थान पर लिख सकते हैं और कुछ को EACCES (अनुमति अस्वीकृत) त्रुटि मिलती है। क्या कोई भी इस पर प्रकाश डाल सकता है कि यह क्यों हो सकता है, कोई सोचता है कि यह बाहरी भंडारण का उपयोग कर सभी 4.4 उपकरणों पर लागू होगा?

चूंकि हमारे पास कोई वास्तविक 4.4 डिवाइस नहीं है, इसलिए हमें एमुलेटर (एपीआई 1 9) का उपयोग करके इस कोड का परीक्षण करना होगा, लेकिन हमें ईएसीसीईएस अनुमति अस्वीकृत त्रुटि नहीं मिलती है। इसलिए हमने ऊपर दिए गए कोड के साथ बीटा संस्करण जारी किया है और बताया गया है कि कॉपी की गई फाइलें आंतरिक स्टोरेज में समाप्त हो गईं, यह कैसे हो सकती है?

कोई भी विचार है कि हम गलत क्या कर रहे हैं, अग्रिम

+0

हाय ज़ोरैक, मैं कुछ डिवाइसों पर एक समान स्थिति में हूं, यह पथ में पैकेज नाम के बिना काम करता है और कुछ लोगों को आपको /Android/data/com.xyz.abc/appfiles जैसे लंबे पथ की आवश्यकता होती है, यह सुनिश्चित नहीं है कि क्या हो रहा है । क्या आपको अभी तक कोई समाधान मिला है? – Ahmed

उत्तर

7

अपडेट किया गया समाधान।

यह सेट

और भी किटकैट के लिए सही जगह में फ़ोल्डर बनाता है।

mfolder = this.getExternalFilesDir("asubfoldername").getAbsolutePath(); 

हालांकि, इस पूरे सबूत नहीं है, अगर एंड्रॉयड डिवाइस में एक आंतरिक और बाहरी माध्यमिक भंडारण स्थान दोनों हैं, उपर्युक्त आंतरिक का उपयोग करेंगे। वास्तव में हम जो चाहते हैं, उसे हटाने योग्य एसडीकार्ड के पथ की आवश्यकता नहीं है या फिर भी सबसे अधिक उपलब्ध स्थान के साथ द्वितीयक स्टोरागेलोकेशन का मार्ग बेहतर है।

File[] possible_kitkat_mounts = getExternalFilesDirs(null); 

getExternalFilesDirs के अंत में "एस" पर ध्यान दें। यह माध्यमिक बाहरी भंडारण स्थानों की एक सरणी बनाता है।

for (int x = 0; x < possible_kitkat_mounts.length; x++) { 
    //Log.d("test", "possible_kitkat_mounts " + possible_kitkat_mounts[x].toString()); 
    boolean isgood=false; 
    if (possible_kitkat_mounts[x] != null){ 
     isgood = test_mount(possible_kitkat_mounts[x].toString()); 
     if (isgood==true){ 
      arrMyMounts.add(newymounts(Device_get_device_info(possible_kitkat_mounts[x].toString()), possible_kitkat_mounts[x].toString())); 
     } 
    } 
}       

//sort arrMyMounts size so we can use largest 
Collections.sort(arrMyMounts, new Comparator<mymounts>(){ 
    public int compare(mymounts obj1, mymounts obj2){ 
     return (obj1.avaliablesize > obj2.avaliablesize) ? -1: (obj1.avaliablesize > obj2.avaliablesize) ? 1:0 ; 
    } 
}); 


if (arrMyMounts.size()>0){ 
    mfolder = arrMyMounts.get(0).name + "/asubfoldername"; 
    //Log.d("test", "selected kitkat mount " + kitkatfolder); 
}else{ 
    //do something else... 
} 

possible_kitkat_mounts हम test_mount के माध्यम से जांच लें कि क्या हम वास्तव में चयनित स्थान पर लिख सकते हैं देखने के लिए की सरणी से है और यदि सफल हम arrMyMounts को उस स्थान जोड़ें।

arrMyMounts को सॉर्ट करके हम सबसे अधिक उपलब्ध खाली स्थान के साथ स्थान प्राप्त कर सकते हैं।

अरे प्रतिष्ठा, arrMyMounts.get (0) .name सबसे खाली स्थान के साथ एक किटकैट माध्यमिक भंडारण स्थान है।

+0

नहीं कर सकता हूं मेरे पास सैमसंग गैलेक्सी नोट 10.1 पर एक एप्लिकेशन इंस्टॉल है जो एक अंतर्निहित बाहरी स्टोरेज और हटाने योग्य एसडी कार्ड विकल्प प्रदान करता है। मैंने उपरोक्त वर्णित विधि का उपयोग कर हटाने योग्य एसडी कार्ड के लिए पथ पुनर्प्राप्त करने का प्रयास किया (यानी getExternalFilesDirs (शून्य)) लेकिन संदर्भ में ऐसी कोई विधि मौजूद नहीं है। मुझे बस एसडी कार्ड के लिए रास्ता प्राप्त करना है, इसलिए मैं ऐप फ़ाइलों को पढ़ने/लिखने के लिए पैकेज विशिष्ट निर्देशिका बना सकता हूं। मैंने हार्डकोडेड पथ का उपयोग करके इस निर्देशिका को बनाने का भी प्रयास किया लेकिन इसे अनुमति नहीं देता है। क्या आप इसके बारे में मदद कर सकते हैं? धन्यवाद –

+0

'यह' क्या है? यह कौन सी कक्षा है? –

5

में धन्यवाद गूगल एंड्रॉयड 4.4 में बाहरी मेमोरी डिवाइस के लिए लेखन पहुँच अवरोधित किया है। जब तक वे इसे बदल नहीं लेते हैं, तब तक रूट के बिना इसे वापस करने का कोई तरीका नहीं है।

और जानकारी: https://groups.google.com/forum/#!msg/android-platform/14VUiIgwUjY/UsxMYwu02z0J

यह Kitkat के साथ कुछ उपकरणों जो कार्ड स्लॉट miniSD है पर काम कर रहा हो सकता है। यह भ्रामक :(

+2

लेकिन एएस फाइल एक्सप्लोरर मेरे किटकैट डिवाइस में फ़ोल्डर बना सकता है! मैं –

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