2012-10-12 100 views
7

在外部SD卡中写入文件时,我收到错误的EACCESS权限被拒绝。我已经设置了许可 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 但是当我读取文件时,我成功地能够读取它,但无法写入文件。我使用了SD卡写入文件的代码是:Android中的EACCESS权限被拒绝

String path="mnt/extsd/Test"; 

       try{ 
        File myFile = new File(path, "Hello.txt");    //device.txt 
        myFile.createNewFile(); 
        FileOutputStream fOut = new FileOutputStream(myFile); 

        OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut); 
        myOutWriter.append(txtData.getText()); 
        myOutWriter.close(); 
        fOut.close(); 
        Toast.makeText(getBaseContext(),"Done writing SD "+myFile.getPath(),Toast.LENGTH_SHORT).show(); 
       } catch (Exception e) { 
        Toast.makeText(getBaseContext(), e.getMessage(),Toast.LENGTH_SHORT).show(); 
        System.out.println("Hello"+e.getMessage()); 
       } 
      } 

用于外部存储卡的路径是mnt/extsd/。这就是为什么我无法使用Environment.getExternalStorageDirectory().getAbsolutePath()这是给我一个路径mnt/sdcard和此路径是我的平板电脑的内部存储路径。请告诉我为什么这是如此n我该如何解决这个问题

回答

13

我记得Android自Honeycomb以来获得了部分多存储支持,并且主存储器(您从Environment.getExternalStorageDirectory获得的存储器,通常是内部eMMC的一部分卡)仍受许可WRITE_EXTERNAL_STORAGE的保护,但辅助存储(如真正的可移动SD卡)受新的权限android.permission.WRITE_MEDIA_STORAGE的保护,保护级别为signatureOrSystem,另请参阅this article中的讨论。

如果是这种情况,那么这似乎是不可能一个正常的应用程序写什么真正的SD卡没有签名的平台...

+0

ok ..那么是否有其他书写方式? – CodingDecoding

+0

你有平板电脑的root权限吗?如果你还可以做这样的测试:1)让你的应用使用WRITE_MEDIA_STORAGE权限,然后重建它; 2)卸载你的应用程序,如果它已经安装,然后运行“adb root”,“adb remount”,“adb push YouApp.apk /system/app/YouApp.apk”这将使你的应用程序成为系统应用程序; 3)启动您的应用程序并检查测试代码是否正常工作。如果是的话,除了通过平台证书签署应用程序或使其成为系统应用程序,似乎没有其他办法。或者你可以等待看看其他人是否有更好的主意。 –

+0

感谢您的信息。它真的帮助:) – CodingDecoding

7

从API级别19,Google has added API

  • Context.getExternalFilesDirs()
  • Context.getExternalCacheDirs()
  • Context.getObbDirs()

应用不得被允许所允许的合成权限写入到第二外部存储装置,除了在它们的特定包的目录。以这种方式限制写入可确保系统在卸载应用程序时清理文件。

以下是使用绝对路径获取外部SD卡上应用程序特定目录的方法。从上面

Context _context = this.getApplicationContext(); 

File fileList2[] = _context.getExternalFilesDirs(Environment.DIRECTORY_DOWNLOADS); 

if(fileList2.length == 1) { 
    Log.d(TAG, "external device is not mounted."); 
    return; 
} else { 
    Log.d(TAG, "external device is mounted."); 
    File extFile = fileList2[1]; 
    String absPath = extFile.getAbsolutePath(); 
    Log.d(TAG, "external device download : "+absPath); 
    appPath = absPath.split("Download")[0]; 
    Log.d(TAG, "external device app path: "+appPath); 

    File file = new File(appPath, "DemoFile.png"); 

    try { 
     // Very simple code to copy a picture from the application's 
     // resource into the external file. Note that this code does 
     // no error checking, and assumes the picture is small (does not 
     // try to copy it in chunks). Note that if external storage is 
     // not currently mounted this will silently fail. 
     InputStream is = getResources().openRawResource(R.drawable.ic_launcher); 
     Log.d(TAG, "file bytes : "+is.available()); 

     OutputStream os = new FileOutputStream(file); 
     byte[] data = new byte[is.available()]; 
     is.read(data); 
     os.write(data); 
     is.close(); 
     os.close(); 
    } catch (IOException e) { 
     // Unable to create file, likely because external storage is 
     // not currently mounted. 
     Log.d("ExternalStorage", "Error writing " + file, e); 
    } 
} 

输出日志是这样的:

context.getExternalFilesDirs() : /storage/extSdCard/Android/data/com.example.remote.services/files/Download 

external device is mounted. 

external device download : /storage/extSdCard/Android/data/com.example.remote.services/files/Download 

external device app path: /storage/extSdCard/Android/data/com.example.remote.services/files/ 
0

我在uses-permission 在清单文件中删除android:maxSdkVersion="18"解决了这个问题。 也就是说如果用户是有外部存储许可或不

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 
       android:maxSdkVersion="18" /> 
0

检查:使用此:中

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

代替。如果不是,则使用缓存目录保存文件。

final boolean extStoragePermission = ContextCompat.checkSelfPermission(
       context, Manifest.permission.WRITE_EXTERNAL_STORAGE) 
       == PackageManager.PERMISSION_GRANTED; 

      if (extStoragePermission && 
     Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) { 
       parentFile = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
      } 
      else{ 
       parentFile = new File(context.getCacheDir(), Environment.DIRECTORY_PICTURES); 
      }