2016-08-17 15 views
1

Android 6.0の外付けSDカードに書き込もうとしましたが、書き込めません。Android 6.0外付けSDカードに書き込む

私はstackoverflowに関する研究を行い、多くのことを見つけましたが、何も動作しません。ここに私のコードです

String extPath = System.getenv("SECONDARY_STORAGE") + "/Android/data/com.gvm.externalstorage.externalstoragetest/"; 
File file = new File(extPath,"myFiles"); 

      if (!file.exists()) { 
       boolean dirResult = file.mkdirs(); 
       Log.e("Directory Exist", dirResult + " Directory created"); 
      } else { 
       Log.e("Directory Exist", "Exist"); 
       Log.e("Direcotry Path",file.getAbsolutePath()); 
      } 
      //String displayname = fileName.replace("%20", " "); 
      File outputFile = new File(file, "mytest5.txt"); 
      outputFile.createNewFile(); 

このコードはAndroid 5.0では動作しますが、Android 6.0では動作しません。

私はこのパスも試してみましたが、それは私に許可エラーを与えます、私はすべてのアクセス許可と管理されたコードを実行時の許可にも設定しました。

/mnt/media_rw/6AC9-083B 

File write failed: java.io.IOException: open failed: EACCES (Permission denied) 

誰かが私を助けることができれば私が最後の3日以来これを試しているので素晴らしいだろう。

おかげで、 Anvesh

+0

はあなたの許可コードを投稿...問題は、あなたの許可側から '' System.getenv( "SECONDARY_STORAGE")のみ –

+1

は何ですか? 'Environment.getExternalStoragePublicDirectory'を使用してください。 –

+0

答えをありがとう、私は考え出し、この質問に私の答えを投稿しました。誰かを助けるかもしれない。 – Anvesh

答えて

8

私は長年の努力の結果、解決策を見つけました。だから私はこの

File[] fs = context.getExternalFilesDirs(null); 
      String extPath = ""; 
      // at index 0 you have the internal storage and at index 1 the real external... 
      if (fs != null && fs.length >= 2) 
      { 
       extPath = fs[1].getAbsolutePath(); 
       Log.e("SD Path",fs[1].getAbsolutePath()); 
      } 

休憩にすべてを使用して外部SDカードのパスを取得し

System.getenv("SECONDARY_STORAGE") 

またはこの

Environment.getExternalStorageDirectory() 

:アンドロイド6.0で、常にこれを使用してSDにカードのパスをあなたを与えることはないだろう許可と全員が同じままです。

私を助けてくれたおかげです。

+0

残念ながら、上記の解決策は、APIレベル19以上でのみ機能します – Theo

4

APIから23+(6.0)、あなたは彼らがRequesting Permissions at Run Timeとして知られているマニフェストに既にある場合でも、読み取り/書き込み権限を要求する必要があります。アンドロイド6.0(APIレベル23)で始まりドキュメント

から

彼らはアプリをインストールするときにアプリがなく、実行されている間、ユーザーは アプリケーションに権限を付与します。この アプローチは、ユーザーが がアプリをインストールまたは更新する際に許可を与える必要がないため、アプリのインストールプロセスを合理化します。また は、ユーザーにアプリの機能をより詳細に制御できるようにします。例えば、 ユーザは、カメラへのカメラアプリケーションへのアクセスを許可することができるが、デバイスの位置には を指定することはできない。ユーザーは、 時間のアクセス許可を取り消すには、アプリの[設定]画面に移動します。

javaの

// Storage Permissions 
private static final int REQUEST_EXTERNAL_STORAGE = 1; 
private static String[] PERMISSIONS_STORAGE = { 
     Manifest.permission.READ_EXTERNAL_STORAGE, 
     Manifest.permission.WRITE_EXTERNAL_STORAGE 
}; 

/** 
* Checks if the app has permission to write to device storage 
* 
* If the app does not has permission then the user will be prompted to grant permissions 
* 
* @param activity 
*/ 
public static void verifyStoragePermissions(Activity activity) { 
    // Check if we have write permission 
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); 

    if (permission != PackageManager.PERMISSION_GRANTED) { 
     // We don't have permission so prompt the user 
     ActivityCompat.requestPermissions(
       activity, 
       PERMISSIONS_STORAGE, 
       REQUEST_EXTERNAL_STORAGE 
     ); 
    } 
} 

のAndroidManifest.xml

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

助けてくれてありがとう、はい私はすべての文書を読むが、問題は異なっていた。下の私の答えを見てください。 – Anvesh

+1

上記のすべてを行った後でも、fopen(path、 "wb")がerrno 13で失敗する原因は何ですか?同じファイルパスをadbシェルから作成することはできますが、問題はありません。 – bparker

0

私はuはあなたの記憶許可がオンになっていることを確認するために、最初のアプリの権限を確認するべきだと思います。

全く記憶許可がない場合: あなたAndroidManifest

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

に記憶許可がオフになっている場合にuがこの権限を使用するかどうかを確認してください: あなたのランタイム許可を確認してください多分uはこれを参照することができますが、コード

private void checkPermissions() { 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
     return; 
    } 

    final List<String> permissionsList = new ArrayList<String>(); 
    permissionsList.add(Manifest.permission.ACCESS_COARSE_LOCATION); 
    permissionsList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); 
    permissionsList.add(Manifest.permission.WRITE_CALENDAR); 
    permissionsList.add(Manifest.permission.READ_PHONE_STATE); 

    int permissionCheckLocation = ContextCompat.checkSelfPermission(IntroductionActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION); 
    int permissionCheckStorage = ContextCompat.checkSelfPermission(IntroductionActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE); 
    int permissionCheckCalendar = ContextCompat.checkSelfPermission(IntroductionActivity.this, Manifest.permission.WRITE_CALENDAR); 
    int permissionCheckPhoneState = ContextCompat.checkSelfPermission(IntroductionActivity.this, Manifest.permission.READ_PHONE_STATE); 

    boolean locationPermission=permissionCheckLocation == PackageManager.PERMISSION_GRANTED?true:false; 
    boolean storagePermission=permissionCheckStorage == PackageManager.PERMISSION_GRANTED?true:false; 
    boolean calendarPermission=permissionCheckCalendar == PackageManager.PERMISSION_GRANTED?true:false; 
    boolean phoneStatePermission=permissionCheckPhoneState == PackageManager.PERMISSION_GRANTED?true:false; 


    boolean shouldShowLocationPermission=ActivityCompat.shouldShowRequestPermissionRationale(IntroductionActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION); 
    boolean shouldShowStoragePermission=ActivityCompat.shouldShowRequestPermissionRationale(IntroductionActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE); 
    boolean shouldShowCalendarPermission=ActivityCompat.shouldShowRequestPermissionRationale(IntroductionActivity.this, Manifest.permission.WRITE_CALENDAR); 
    boolean shouldShowPhoneStatePermission=ActivityCompat.shouldShowRequestPermissionRationale(IntroductionActivity.this, Manifest.permission.READ_PHONE_STATE); 

    if (permissionCheckLocation == PackageManager.PERMISSION_GRANTED && permissionCheckStorage == PackageManager.PERMISSION_GRANTED 
      && permissionCheckCalendar == PackageManager.PERMISSION_GRANTED && permissionCheckPhoneState == PackageManager.PERMISSION_GRANTED){ 
     return; 
    }else if(((!locationPermission&&!shouldShowLocationPermission)||(!storagePermission&&!shouldShowStoragePermission) 
      ||(!calendarPermission&&!shouldShowCalendarPermission)||(!phoneStatePermission&&!shouldShowPhoneStatePermission))&&appContext.localCheckPermission){ 
     showMessageOKCancel("You need to allow access these permissions", 
       new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName())); 
         startActivityForResult(intent, 1); 
        } 
       }); 
    }else{ 
     ActivityCompat.requestPermissions(IntroductionActivity.this, permissionsList.toArray(new String[permissionsList.size()]), 0); 

    } 
} 

まだ問題がある場合は、ファイルのパスを変更してみてください。

String fileName="mytest5.txt"; 
File folder = new File(Environment.getExternalStorageDirectory().getPath() + "/com.gvm.externalstorage.externalstoragetest/"); 

    if (!folder.exists()) { 
     try { 
      folder.mkdirs(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      System.out.println("Default Save Path Creation Error:" + folder); 
     } 
    } 

    File logFile = new File(folder, fileName); 
    if (!logFile.exists()) { 
     try { 
      logFile.createNewFile(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      System.out.println("Default Save Path Creation Error:" + logFile); 

     } 
    } 

よろしくお願いいたします。私がこれが助けてくれることを願っています

+0

助けてくれてありがとう、下の私の答えを参照してください、それは本当のSDカードのパスを与えるつもりです。それもあなたを助けるかもしれません。 – Anvesh

0

@Anvesh別の信頼性の高い方法で私が使用している:

/** 
* Get external storage path use reflect on android 6.0 device. 
* Source code: 
* https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/storage/StorageVolume.java 
* 
* @param removable the sdcard can remove or not, true means external sdcard, false means 
*     internal sdcard. 
* @return path of sdcard we want 
*/ 
public static String getStoragePath(boolean removable) { 
    WinZipApplication application = WinZipApplication.getInstance(); 
    Context mContext = application.getApplicationContext(); 
    StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); 
    Class<?> storageVolumeClazz = null; 
    try { 
     storageVolumeClazz = Class.forName("android.os.storage.StorageVolume"); 
     Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList"); 
     Method getPath = storageVolumeClazz.getMethod("getPath"); 
     Method isRemovable = storageVolumeClazz.getMethod("isRemovable"); 
     Object result = getVolumeList.invoke(mStorageManager); 
     final int length = Array.getLength(result); 
     for (int i = 0; i < length; i++) { 
      Object storageVolumeElement = Array.get(result, i); 
      String path = (String) getPath.invoke(storageVolumeElement); 
      boolean mRemovable = (Boolean) isRemovable.invoke(storageVolumeElement); 
      if (removable == mRemovable) { 
       return path; 
      } 
     } 
    } catch (Exception e) { 
     return null; 
    } 
    return null; 
} 
+0

L.Mengありがとうございました。 – Anvesh

0

私は絶対的な解決策を見つけた多くの研究の後。できます。

public boolean checkStorage() { 
    File[] fs = con.getExternalFilesDirs(null); 
    if (fs.length == 2) 
     return true; 
    else 
     return false; 
} 
関連する問題