Reputation: 31
I need to read a file selected by user, so I use this code:
//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
I put the relative permission in the manifest too:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I read the file in this way:
@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 is a file selected by the user with the file manager, in this case a downloaded image) With the code I get this exception:
/data/data/com.android.browser/cache/2016-04-25-17-17-49-1205395195.jpg: open failed: EACCES (Permission denied)
I don't know what the problem is.
I add some details:
//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
And this is the code to get the path:
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
What is wrong?
Upvotes: 3
Views: 2750
Reputation: 31
ok, I solved it! The problem was in part the emulator ... I post the code for those who had the same problem (thanks to CommonsWare for help):
//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
Upvotes: 0
Reputation: 1006644
You are not the author of the com.android.browser
app. You cannot access that app's files on internal storage. Your permissions are for external storage.
Upvotes: 1