2016-01-18 4 views
-1

В моем приложении мне нужно загрузить некоторые файлы mp4 на память. Существует меню опций для выбора местоположения файлов mp4 (хранилище телефона или хранилище sdcard). я получаю путь для хранения телефона и путь для хранения SDCard на андроид отражают SDK.as ниже:Android: у вас нет разрешения на запись данных на SDCard

public class StorageUtils { 

    private static final String TAG = "===StorageUtil==="; 

    public static String getPrimaryStoragePath(Context context) { 
     try { 
      StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); 
      Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", null); 
      String[] paths = (String[]) getVolumePathsMethod.invoke(sm, null); 
      // first element in paths[] is primary storage path 
      return paths[0]; 
     } catch (Exception e) { 
      Log.e(TAG, "getPrimaryStoragePath() failed", e); 
     } 
     return null; 
    } 

    public static String getSecondaryStoragePath(Context context) { 
     try { 
      StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); 
      Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", null); 
      String[] paths = (String[]) getVolumePathsMethod.invoke(sm, null); 
      // second element in paths[] is secondary storage path 
      return paths[1]; 
     } catch (Exception e) { 
      Log.e(TAG, "getSecondaryStoragePath() failed", e); 
     } 
     return null; 
    } 

    public static String getStorageState(Context context, String path) { 

     try { 
      StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); 
      Method getVolumeStateMethod = StorageManager.class.getMethod("getVolumeState", new Class[]{String.class}); 
      String state = (String) getVolumeStateMethod.invoke(sm, path); 
      return state; 
     } catch (Exception e) { 
      Log.e(TAG, "getStorageState() failed", e); 
     } 
     return null; 
    } 
} 

И мой тестовый код, как показано ниже:

public class StorageTestActivity extends AppCompatActivity { 

    private TextView primaryStoragePath; 
    private TextView slaveStoragePath, tvStatus; 
    private Button btn1, btn2; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_storage_test); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 
         .setAction("Action", null).show(); 
      } 
     }); 

     primaryStoragePath = (TextView) findViewById(R.id.primaryStoragePath); 
     slaveStoragePath = (TextView) findViewById(R.id.slaveStoragePath); 

     //state: mounted, shared, removed 
     final String path1 = StorageUtils.getPrimaryStoragePath(this); 
     String state1 = StorageUtils.getStorageState(this, path1); 
     StringBuilder sb1 = new StringBuilder().append("path1:").append(path1).append("\n").append("state1=").append(state1); 
     primaryStoragePath.setText(sb1.toString()); 

     final String path2 = StorageUtils.getSecondaryStoragePath(this); 
     String state2 = StorageUtils.getStorageState(this, path2); 
     StringBuilder sb2 = new StringBuilder().append("path2:").append(path2).append("\n").append("state2=").append(state2); 
     slaveStoragePath.setText(sb2.toString()); 

     btn1 = (Button) findViewById(R.id.btnWriteToPrimaryStorage); 
     btn1.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       currentType = 0; 
       writeData(path1); 
      } 
     }); 

     btn2 = (Button) findViewById(R.id.btnWriteToSDCard); 
     btn2.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       currentType = 1; 
       writeData(path2); 
      } 
     }); 

     tvStatus = (TextView) findViewById(R.id.tvStatus); 



    } 

    private int currentType = 0; 
    private void writeData(final String path) { 

     Runnable runnable = new Runnable() { 
      @Override 
      public void run() { 
       String state = StorageUtils.getStorageState(StorageTestActivity.this, path); 
       if(!"mounted".equals(state)) { 
        Snackbar.make(slaveStoragePath, "state is " + state, Snackbar.LENGTH_LONG).show(); 
        return; 
       } 



       String tmpPath = path+File.separator+"Android/data/com.example.fjz.myapplication/"; 
       File directory = new File(tmpPath); 

       if (!directory.exists()) { 
        Log.e("========", "create directories."); 
        directory.mkdirs(); 
       } 

       File file = new File(tmpPath + "abcdefg.txt"); 
       if (file.exists()) { 
        file.delete(); 
       } 

       try { 
        file.createNewFile(); 
        handler.sendEmptyMessage(currentType); 
       } catch (IOException e) { 
        e.printStackTrace(); 
        handler.sendEmptyMessage(3); 
       } 

       Log.e("storage test activity:", file.getAbsolutePath()); 

      } 
     }; 

     new Thread(runnable).start(); 
    } 

    private Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 

      if(msg.what == 0) { 
       tvStatus.setText("Write primary success"); 
      } else if(msg.what == 1) { 
       tvStatus.setText("Write SD card success"); 
      } else { 
       tvStatus.setText("Write failed."); 
      } 
     } 
    }; 

Тогда ошибка:

01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: java.io.IOException: open failed: EACCES (Permission denied) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err:
at java.io.File.createNewFile(File.java:978) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: at com.example.fjz.demo.StorageTestActivity$4.run(StorageTestActivity.java:108) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: at java.lang.Thread.run(Thread.java:841) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: at libcore.io.Posix.open(Native Method) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: at java.io.File.createNewFile(File.java:971) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: ... 2 more

В файле манифеста я прописал разрешения:


помочь мне, спасибо очень

+0

Эта проблема часто возникает из-за того, что разрешение объявлено не в том месте .... оно должно быть вне тега приложения ... – Opiatefuchs

ответ

0

Вам нужно добавить разрешение на запись в вашем AndroidManifest.xml

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

Фрэнк написал, что он объявил разрешения в манифесте ...... – Opiatefuchs

+0

So , ваш может проверить с этим Файл sd = Environment.getExternalStorageDirectory(); Log.e ("CHECK WRITE", sd.canWrite() + ""); –

0

Я объявил разрешения, как показано ниже:

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

К счастью, я понял.

1) Я получаю sdcard путь как /storaget/sdcard1 2) Тогда я сделать путь /storaget/sdcard1/Android/data/com.example.sdcard.demo

3) Попробуйте mkdirs(path), а затем вернуться ложным, поэтому у меня нет разрешения на создание 'Android/data/com.example.sdcard.demo' каталога.

4) Я могу позвонить api:getExternalCacheDir, который может создать этот успех каталога.

+0

" " –