2012-10-12 54 views
7

Trong khi ghi tệp trong thẻ SD bên ngoài Tôi nhận được lỗi EACCESS cho phép bị từ chối. Tôi đã đặt quyền cho phép <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> Nhưng khi tôi đọc tệp, tôi có thể đọc thành công tệp nhưng không thể ghi tệp. Mã mà tôi đang sử dụng để ghi tệp trong thẻ SD là:Quyền EACCESS bị từ chối trong Android

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

Đường dẫn cho thẻ lưu trữ ngoài là mnt/extsd/. Đó là lý do tại sao tôi không thể sử dụng Environment.getExternalStorageDirectory().getAbsolutePath(), cho tôi đường dẫn mnt/sdcard và đường dẫn này dành cho đường dẫn lưu trữ nội bộ trong máy tính bảng của tôi. Vui lòng đề xuất lý do vì sao tôi có thể giải quyết vấn đề này

Trả lời

13

Vì tôi nhớ Android đã nhận được hỗ trợ đa bộ nhớ một phần vì Honeycomb và bộ nhớ chính (bộ nhớ bạn nhận được từ Environment.getExternalStorageDirectory, thường là một phần của eMMC nội bộ thẻ) vẫn được bảo vệ bởi sự cho phép WRITE_EXTERNAL_STORAGE, nhưng kho thứ cấp (giống như thẻ SD có thể tháo rời thực) được bảo vệ bởi sự cho phép mới android.permission.WRITE_MEDIA_STORAGE và mức bảo vệ là signatureOrSystem, xem thêm phần thảo luận trong this article.

Nếu đây là trường hợp sau đó có vẻ như không thể đối với một ứng dụng bình thường để viết bất cứ điều gì đến sdcard thực mà ko cần signature nền tảng ...

+0

ok..Khi nào là cách viết khác? – CodingDecoding

+0

Bạn có quyền truy cập root vào máy tính bảng của mình không? Nếu chưa thì bạn có thể làm một thử nghiệm như thế này: 1) cho phép ứng dụng của bạn sử dụng quyền WRITE_MEDIA_STORAGE và sau đó xây dựng lại nó; 2) gỡ bỏ cài đặt ứng dụng của bạn nếu nó đã được cài đặt, sau đó chạy "adb root", "adb remount", "adb push YouApp.apk /system/app/YouApp.apk" điều này sẽ làm cho ứng dụng của bạn trở thành ứng dụng hệ thống; 3) khởi động ứng dụng của bạn và kiểm tra xem mã thử nghiệm có đang hoạt động hay không.Nếu có, dường như không có cách nào khác ngoại trừ việc ký ứng dụng bằng chứng chỉ nền tảng hoặc biến nó thành ứng dụng hệ thống. Hoặc bạn có thể chờ xem liệu có ai khác có ý tưởng hay hơn không. –

+0

Cảm ơn thông tin. Nó thực sự giúp :) – CodingDecoding

7

Từ mức API 19, Google has added API.

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

Apps không được phép viết thư cho các thiết bị lưu trữ bên ngoài thứ, ngoại trừ trong các thư mục gói cụ thể của họ như được cho phép bởi điều khoản tổng hợp. Hạn chế ghi theo cách này đảm bảo hệ thống có thể xóa các tệp khi các ứng dụng được gỡ cài đặt.

Sau đây là cách tiếp cận để nhận thư mục ứng dụng cụ thể trên thẻ SD bên ngoài với đường dẫn tuyệt đối.

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

Đăng sản lượng từ trên cao trông giống như:

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

tôi giải quyết vấn đề này bằng cách loại bỏ các android:maxSdkVersion="18" trong uses-permission trong file manifest. I.e. sử dụng này:

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

thay vì:

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

Kiểm tra nếu người dùng đang có sự cho phép lưu trữ bên ngoài hay không. Nếu không thì sử dụng bộ đệm ẩn để lưu tệp.

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); 
      } 
Các vấn đề liên quan