2017-08-23 11 views
0

Androidストレージ内のデバイスストレージからSDカードにファイルを移動するための外部ディレクトリ構造を作成しようとしています。私はhttps://developer.android.com/training/permissions/requesting.htmlと複数のstackoverflow答えで与えられた手順に従ってきました。しかし、ディレクトリを作成しようとするとプログラムが失敗します。Android 6.0:SDカードの作成に失敗しました。

マイAndroidManifest.xmlファイルに次の行が含まれます。

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

次のように関連するコードは次のとおりです。ここで

public int mkFolder(String folderName){ 
     String state = Environment.getExternalStorageState(); 
     if (!Environment.MEDIA_MOUNTED.equals(state)){ 
      Log.d(TAG, "Error: external storage is unavailable"); 
      return 0; 
     } 
     if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { 
      Log.d(TAG, "Error: external storage is read only."); 
      return 0; 
     } 
     Log.d(TAG, "External storage is not read only or unavailable"); 

     boolean writePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED; 
     boolean readPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED; 
     final boolean permissionNotGranted = writePermission|| readPermission; 
     if (permissionNotGranted) { 
      Log.i(TAG, "STORAGE permissions NOT granted"); 
      // Should we show an explanation? 
      boolean shouldShowRationaleForWritePermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); 
      boolean shouldShowRationaleForReadPermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE); 
      if (shouldShowRationaleForWritePermssion || shouldShowRationaleForReadPermssion) { 

       // Show an explanation to the user *asynchronously* -- don't block 
       // this thread waiting for the user's response! After the user 
       // sees the explanation, try again to request the permission. 

      } else { 
       ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); 
      } 
     } else { 
      Log.i(TAG, "STORAGE permissions granted"); 
     } 

//  File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),folderName); 
     File folder = new File(folderName); 
     int result = 0; 
     if (folder.exists()) { 
      Log.d(TAG,"folder exist:"+folder.toString()); 
      result = 2; // folder exist 
     }else{ 
      try { 
       if (folder.mkdirs()) { 
        Log.d(TAG, "folder created:" + folder.toString()); 
        result = 0; // folder created 
       } else { 
        Log.d(TAG, "create folder fails:" + folder.toString()); 
        result = 1; // create folder fails 
       } 
      }catch (Exception ecp){ 
       ecp.printStackTrace(); 
      } 
     } 
     return result; 
    } 

    public static final int REQUEST_EXTERNAL_STORAGE = 112; 
    private static String[] PERMISSIONS_STORAGE = { 
      Manifest.permission.READ_EXTERNAL_STORAGE, 
      Manifest.permission.WRITE_EXTERNAL_STORAGE 
    }; 

    @Override 
    public void onRequestPermissionsResult(int requestCode, 
              @NonNull String permissions[], @NonNull int[] grantResults) { 
     Log.e(TAG, "onRequestPermissionsResult invoked"); 
     switch (requestCode) { 
      case REQUEST_EXTERNAL_STORAGE: { 
       // If request is cancelled, the result arrays are empty. 
       if (grantResults.length > 0 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

        // permission was granted, yay! Do the 
        // contacts-related task you need to do. 
        Log.i(TAG, "Permission to write to external storage granted"); 
        Toast.makeText(this, "Permission to write to external storage granted", Toast.LENGTH_LONG).show(); 
       } else { 
        // permission denied, boo! Disable the 
        // functionality that depends on this permission. 
        Log.e(TAG, "Permission to write to external storage NOT granted"); 
        Toast.makeText(this, "Permission to write to external storage NOT granted", Toast.LENGTH_LONG).show(); 
       } 
      } 
      // other 'case' lines to check for other 
      // permissions this app might request 
     } 
    } 

は、ログからの抜粋です:

MainActivity: /storage/0000-0000 false true 
MainActivity: /storage/0000-0000/MyDir does not exist. Creating target parent directory 
MainActivity: STORAGE permissions granted 
MainActivity: Creation of directory /storage/0000-0000/MyDir failed with return value 1. Aborting... 

できる人を私のコードで間違いが何であるのか理解してもらえますか?

答えて

1

あなたは、Android 4.4から、removable storageの任意の場所に直接ファイルシステムアクセスする必要はありません。 WRITE_EXTERNAL_STORAGEは意味がありません。external storageはリムーバブルストレージではありません。

ストレージアクセスフレームワーク(ACTION_OPEN_DOCUMENT_TREEとkin)を代わりに使用してください。または、getExternalFilesDirs()getExternalCacheDirs()getExternalMediaDirs()(すべての方法はContext)の一部として返されたリムーバブルストレージの場所に作業を制限します。

+0

お返事ありがとうございます。 SDカードのルートにディレクトリを作成できないということですか?私は、SDカードの「ルート」にディレクトリを作成する他のアプリ(SMSバックアップや種類の復元など)を見てきました。あなたはそれを行う他の方法を知っていますか? –

+1

@ KarthickS:ストレージアクセスフレームワークを使用して、*ユーザ*はドキュメントツリー(ディレクトリ)を作成する場所を選択できます。これは、リムーバブルストレージボリュームの根源になるかもしれません。リムーバブルストレージボリュームのいくつかのサブディレクトリにある可能性があります。他のストレージプロバイダを使用している可能性があります(Googleドライブなど)。ストレージアクセスフレームワークの美しさは、あなたのアプリが気にする必要がないということです。 'Uri'を使用して、' DocumentFile'のようなサポートクラスと一緒に戻ってくるだけで、あなたが置いた場所にコンテンツを置きます。 – CommonsWare

+0

ありがとうございました。それはまさに私が望んでいたものです。 Androidプログラミングの比較的新しい初心者として、私はStorage Access Frameworkがまったく存在しないことを認識しませんでした。 –

関連する問題