2012-10-12 25 views
7

外部SDカードにファイルを書き込んでいるうちに、EACCESS権限が拒否されました。私は許可を設定しました <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> しかし、私がファイルを読むと、私はそれを読むことに成功しましたが、ファイルを書き込めませんでした。私はSDカード内のファイルを書き込むために使用していたコードは次のとおりです。EACCESS 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()); 
       } 
      } 

外部ストレージカードのパスはmnt/extsd/です。私がmnt/sdcardのパスを与えているEnvironment.getExternalStorageDirectory().getAbsolutePath()を使用することができず、このパスは私のタブレットの内部ストレージパス用です。これを解決する方法を教えてください

答えて

13

AndroidはHoneycombとプライマリストレージ(これは通常、内部eMMCの一部であるEnvironment.getExternalStorageDirectoryから取得したものです)カード)はまだ許可WRITE_EXTERNAL_STORAGEで保護されていますが、実際のリムーバブルSDカードのようなセカンダリストレージは新しいアクセス許可android.permission.WRITE_MEDIA_STORAGEで保護されており、保護レベルはsignatureOrSystemです(this articleの説明も参照してください)。 APIレベル19、Google has added APIから、このような場合は、通常のアプリは、プラットフォームの署名なしで実際の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

  • 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-permissionandroid:maxSdkVersion="18"を削除することによってこの問題を解決しました。 すなわち、

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

の代わり:

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

チェック、ユーザが外部ストレージ権限を有するかまたはされていない場合は、これを使用しています。そうでない場合は、ファイルを保存するためにcache dirを使用します。

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); 
      } 
関連する問題