2016-04-26 6 views
1

мне нужно прочитать файл, выбранный пользователем, поэтому я использую этот код:Android Не удались открыть: EACCES (Отказано в) при попытке чтения файла в данных/данных

//This code is called by a button to ask the permission 
private void startUpload(){ 

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { 
     if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { 

      ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_PERMISSION_GRANTED); 

     } else { 
      ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_PERMISSION_GRANTED); 
     } 
    } 

}//startUpload 

Я кладу относительное разрешения в манифесте тоже:

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

Я прочитал файл следующим образом:

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case WRITE_PERMISSION_GRANTED: { 
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

       try { 
        FileInputStream stream = new FileInputStream(toUpload.getCanonicalFile()); 
        byte[] data = new byte[(int) toUpload.length()]; 
        stream.read(data); 
        stream.close(); 
        Log.e("FUNZIONA!!!!", "OK!"); 
       }catch (Exception e){ 
        Log.e("ECCEZIONE", e.getMessage()); 
       } 
      } else { 
       Log.e("PERMISSION", "DEINED"); 
      } 
      return; 
     } 

     // other 'case' lines to check for other 
     // permissions this app might request 
    } 
} 

(toUpload файл, выбранный пользователем с файловым менеджером, в этом случае загруженное изображение) С кодом я получаю это исключение:

/data/data/com.android.browser/cache/2016-04-25-17-17-49-1205395195.jpg: open failed: EACCES (Permission denied) 

Я не знаю, в чем проблема.

добавить некоторые детали:

//this code opens the defualt file manager 
private void showFileChooser() { 

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
    intent.setType("*/*"); 
    intent.addCategory(Intent.CATEGORY_OPENABLE); 

    try { 
     startActivityForResult(
       Intent.createChooser(intent, "Select a File to Upload"), 
       FILE_SELECT_CODE); 
    } catch (android.content.ActivityNotFoundException ex) { 

     Snackbar.make(uploadView, "Nessun file manager trovato!", Snackbar.LENGTH_LONG).setAction("Response", null).show(); 
    } 

}//showFileChooser 

//this is for getting the selected file 
@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

    switch (requestCode) { 
     case FILE_SELECT_CODE: 
      if (resultCode == RESULT_OK) { 
       Uri uri = data.getData(); 
       String path = getPath(this, uri); 
       toUpload = new File(path); 
       //Log.d("LOG", "File Path: " + path); 
      } 
      break; 
    } 
    super.onActivityResult(requestCode, resultCode, data); 

}//onActivityResult 

И это код, чтобы получить путь:

private String getPath(final Context context, final Uri uri) { 

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 

    // DocumentProvider 
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { 
     // ExternalStorageProvider 
     if (isExternalStorageDocument(uri)) { 
      final String docId = DocumentsContract.getDocumentId(uri); 
      final String[] split = docId.split(":"); 
      final String type = split[0]; 

      if ("primary".equalsIgnoreCase(type)) { 
       return Environment.getExternalStorageDirectory() + "/" + split[1]; 
      } 
     } 
     // DownloadsProvider 
     else if (isDownloadsDocument(uri)) { 

      final String id = DocumentsContract.getDocumentId(uri); 
      final Uri contentUri = ContentUris.withAppendedId(
        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); 

      return getDataColumn(context, contentUri, null, null); 
     } 
     // MediaProvider 
     else if (isMediaDocument(uri)) { 
      final String docId = DocumentsContract.getDocumentId(uri); 
      final String[] split = docId.split(":"); 
      final String type = split[0]; 

      Uri contentUri = null; 
      if ("image".equals(type)) { 
       contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 
      } else if ("video".equals(type)) { 
       contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 
      } else if ("audio".equals(type)) { 
       contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
      } 

      final String selection = "_id=?"; 
      final String[] selectionArgs = new String[]{ 
        split[1] 
      }; 

      return getDataColumn(context, contentUri, selection, selectionArgs); 
     } 
    } 
    // MediaStore (and general) 
    else if ("content".equalsIgnoreCase(uri.getScheme())) { 

     // Return the remote address 
     if (isGooglePhotosUri(uri)) 
      return uri.getLastPathSegment(); 

     return getDataColumn(context, uri, null, null); 
    } 
    // File 
    else if ("file".equalsIgnoreCase(uri.getScheme())) { 
     return uri.getPath(); 
    } 

    return null; 

}//getPath 

public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { 

    Cursor cursor = null; 
    final String column = "_data"; 
    final String[] projection = {column}; 

    try { 
     cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, 
       null); 
     if (cursor != null && cursor.moveToFirst()) { 
      final int index = cursor.getColumnIndexOrThrow(column); 
      return cursor.getString(index); 
     } 
    } finally { 
     if (cursor != null) 
      cursor.close(); 
    } 
    return null; 

}//getDataColumn 

public static boolean isExternalStorageDocument(Uri uri) { 

    return "com.android.externalstorage.documents".equals(uri.getAuthority()); 

}//isExternalStorageDocument 

public static boolean isDownloadsDocument(Uri uri) { 

    return "com.android.providers.downloads.documents".equals(uri.getAuthority()); 

}//isDownloadsDocument 

public static boolean isMediaDocument(Uri uri) { 

    return "com.android.providers.media.documents".equals(uri.getAuthority()); 

}//isMediaDocument 

public static boolean isGooglePhotosUri(Uri uri) { 

    return "com.google.android.apps.photos.content".equals(uri.getAuthority()); 

}//isMediaDocument 

Что не так?

+0

'с файловым менеджером'. Какое приложение файлового менеджера позволяет пользователям выбирать из внутренней памяти? Версия для Android? – greenapps

+0

Я бы ожидал 'FileNotFoundException'. – greenapps

+0

Да, является файловым менеджером по умолчанию. – M3M3X

ответ

0

ОК, я решил! Проблема была частично в эмуляторе ... Я размещаю код для тех, у кого была такая же проблема (спасибо CommonsWare за помощь):

//It requires a file manager installed 
private void showFileChooser() { 
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
    intent.setType("file/*"); 
    try { 
     startActivityForResult(intent, FILE_SELECT_CODE); 
    } catch (android.content.ActivityNotFoundException ex) { 
     Snackbar.make(uploadView, "No file manager founded!", Snackbar.LENGTH_LONG).setAction("Response", null).show(); 
    } 

}//showFileChooser 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

    switch (requestCode) { 
     case FILE_SELECT_CODE: 
      if (resultCode == RESULT_OK) { 
       Uri uri = data.getData(); 
       uriToUpload = uri; 
      } 
      break; 
    } 
    super.onActivityResult(requestCode, resultCode, data); 

}//onActivityResult 

private byte[] getFileData() throws IOException{ 

    Cursor cursor = getContentResolver().query(uriToUpload, null, null, null, null); 
    cursor.moveToFirst(); 
    long size = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE)); 
    cursor.close(); 
    InputStream stream = getContentResolver().openInputStream(uriToUpload); 
    byte[] data = new byte[(int)size]; 
    stream.read(data); 
    stream.close(); 

    return data; 

}//getFileData 
1

Вы не являетесь автором приложения com.android.browser. Вы не можете получить доступ к файлам этого приложения по адресу internal storage. Ваши разрешения: external storage.

+0

Хорошо, но как я могу это сделать? Я думаю, что это возможно, потому что приложения для файлового менеджера позволяют копировать, перемещать файлы и т. Д. – M3M3X

+0

@ M3M3X: только «приложения для файлового менеджера», которые позволяют вам прокручивать содержимое файлов других приложений на внутреннем хранилище, требуют укоренившихся устройств. – CommonsWare

+0

Я объясню лучше: я загрузил изображение в эмулятор для тестирования (но это мог быть любой файл), после этого я хотел бы получить этот файл, чтобы я сделал это: «Intent intent = new Intent (Intent) .ACTION_GET_CONTENT); intent.setType ("*/*"); aim.addCategory (Intent.CATEGORY_OPENABLE); 'для открытия файлового менеджера по умолчанию и, наконец, я выбрал загруженный файл. Чтобы получить файл, мне нужен его путь, поэтому я получил его и файл, infact, существует; Теперь я просто хочу прочитать его. Что я делаю не так? – M3M3X