Crash when selecting file from downloads - java

I'm using this fileutils class when selecting a file from the device:
public class FileUtils {
private FileUtils() {
}
private static final String TAG = "FileUtils";
private static final boolean DEBUG = false;
private static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
private 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()) {
if (DEBUG)
DatabaseUtils.dumpCursor(cursor);
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {
if (DEBUG)
Log.d(TAG + " File -",
"Authority: " + uri.getAuthority() +
", Fragment: " + uri.getFragment() +
", Port: " + uri.getPort() +
", Query: " + uri.getQuery() +
", Scheme: " + uri.getScheme() +
", Host: " + uri.getHost() +
", Segments: " + uri.getPathSegments().toString()
);
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];
// This is for checking Main Memory
if ("primary".equalsIgnoreCase(type)) {
if (split.length > 1) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else {
return Environment.getExternalStorageDirectory() + "/";
}
// This is for checking SD Card
} else {
return "storage" + "/" + docId.replace(":", "/");
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
if (id.startsWith("raw:")) {
String[] data = new String[2];
data[0] = id.replaceFirst("raw:", "");
data[1] = null;
return data[0];
}
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;
}
I call this class in onActivityResult like this:
String sourcePath = FileUtils.getPath(this, data.getData());
For some reason I'm getting the following crash:
Caused by java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/230
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:165)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
at android.content.ContentResolver.query(ContentResolver.java:760)
at android.content.ContentResolver.query(ContentResolver.java:710)
at android.content.ContentResolver.query(ContentResolver.java:668)
at com.HBiSoft.ProGolf.Utils.FileUtils.getDataColumn(FileUtils.java:50)
at com.HBiSoft.ProGolf.Utils.FileUtils.getPath(FileUtils.java:116)
at com.HBiSoft.ProGolf.MainActivity.onActivityResult(MainActivity.java:652)
at android.app.Activity.dispatchActivityResult(Activity.java:7638)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4515)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4563)
at android.app.ActivityThread.-wrap21(Unknown Source)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1779)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
the crash only happens when selecting a file from the downloads folder.
Can someone please help me resolve this?

I have created a gist that solves this issue, here is the link.
IMPORTANT!!
When you select a file from Google Drive or Dropbox then you will get the following error:
Caused by java.lang.IllegalArgumentException: column '_data' does not exist
To resolve this you actually have to make a temporary copy of the file you are trying select.
First you have to check if the content:// uri is from Google Drive, you can do this by doing the following:
public boolean isGoogleDrive(Uri uri) {
return String.valueOf(uri).toLowerCase().contains("com.google.android.apps");
}
This will return true if it is a file from Google Drive. If it is, I will call a AsyncTask, as shown below:
//The data.getData() below refers to the uri you get in onActivityResult
if (isGoogleDrive(data.getData())) {
DownloadAsyncTask asyntask = new DownloadAsyncTask(data.getData(), this);
asyntask.execute();
asyntask.callback = this;
}
In the AsyncTask we will use the Uri to open a InputStream and get the byte data back which we will use to make a copy of the file.
Here is the AsyncTask class (I've added comments to make it more understandable):
class DownloadAsyncTask extends AsyncTask<Uri, Void, String> {
private Uri mUri;
CallBackTask callback;
Context mContext;
private AlertDialog mdialog;
DownloadAsyncTask(Uri uri, Context context) {
this.mUri = uri;
mContext = context;
}
// In the onPreExecute() I'm displaying a custom dialog, this is not necessary, but recommended for when the user selects a large file
#Override
protected void onPreExecute() {
final AlertDialog.Builder mPro = new AlertDialog.Builder(new ContextThemeWrapper(mContext, R.style.myDialog));
#SuppressLint("InflateParams")
//Get reference to dialog layout
final View mPView = LayoutInflater.from(mContext).inflate(R.layout.dialog, null);
//Get reference to dialog title
final TextView title = mPView.findViewById(R.id.txtTitle);
//Get reference to dialog description
final TextView desc = mPView.findViewById(R.id.txtDesc);
//Set title text
title.setText("Please wait..");
//Set description text
desc.setText("Drive files needs to be imported, this might take some time depending on the file size.");
mPro.setView(mPView);
mdialog = mPro.create();
mdialog.show();
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected String doInBackground(Uri... params) {
//This will be the file we will use (the one that will be copied)
File file = null;
try {
//Create a temporary folder where the copy will be saved to
File temp_folder = mContext.getExternalFilesDir("TempFolder");
//Use ContentResolver to get the name of the original name
//Create a cursor and pass the Uri to it
Cursor cursor = mContext.getContentResolver().query(mUri, null, null, null, null);
//Check that the cursor is not null
assert cursor != null;
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
cursor.moveToFirst();
//Get the file name
String filename = cursor.getString(nameIndex);
//Close the cursor
cursor.close();
//open a InputStream by passing it the Uri
//We have to do this in a try/catch
InputStream is = null;
try {
is = mContext.getContentResolver().openInputStream(mUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//We now have a folder and a file name, now we can create a file
file = new File(temp_folder + "/" + filename);
//We can now use a BufferedInputStream to pass the InputStream we opened above to it
BufferedInputStream bis = new BufferedInputStream(is);
//We will write the byte data to the FileOutputStream, but we first have to create it
FileOutputStream fos = new FileOutputStream(file);
byte data[] = new byte[1024];
long total = 0;
int count;
//Below we will read all the byte data and write it to the FileOutputStream
while ((count = bis.read(data)) != -1) {
total += count;
fos.write(data, 0, count);
}
//The FileOutputStream is done and the file is created and we can clean and close it
fos.flush();
fos.close();
} catch (IOException e) {
Log.e("IOException = ", String.valueOf(e));
}
//Finally we can pass the path of the file we have copied
return file.getAbsolutePath();
}
protected void onPostExecute(String result) {
//We are done and can cancel the dialog
if (mdialog != null && mdialog.isShowing()) {
mdialog.cancel();
}
//I'm using a callback to let my Activity know that the AsyncTask is done. I pass the path along.
callback.getResultFromAsynTask(result);
}
}
You will see that in the onPostExecute() above I have callback.getResultFromAsynTask(result);. As I mentioned in the comment, I'm using a callback method to let the Activity know that I'm done and I pass the path to the callback.
In you Activity you have to implement the callback, like this:
public class MainActivity extends AppCompatActivity implements CallBackTask {
and the CallBackTask will look like this:
interface CallBackTask {
void getResultFromAsynTask(String result);
}
now you have to implement it in your Activity to get the result in your Activity:
#Override
public void getResultFromAsynTask(String result) {
// Do what you need with the result like starting your new Activity and passing the path
final Intent intent = new Intent();
intent.setClass(MainActivity.this, Player.class);
intent.putExtra("path", result);
startActivity(intent);
}
GREAT, you now have a Uri from a File://(instead of content://) that you have temporarily copied. But, don't forget to delete the file when you are done with it, otherwise your application size will keep growing bigger.
Below, I will delete the TempFolder we created earlier, I will be doing this in the Activities onBackPressed (this should be done in onDestroy() as well):
#Override
public void onBackPressed() {
super.onBackPressed();
File dir = getBaseContext().getExternalFilesDir("TempFolder");
deleteRecursive(dir);
}
void deleteRecursive(File fileOrDirectory) {
if (fileOrDirectory.isDirectory())
for (File child : fileOrDirectory.listFiles())
deleteRecursive(child);
fileOrDirectory.delete();
}
This is a lot read BUT...
By doing it this way, you will NEVER have issues with any content:// Uri's.

Related

Unable to pick file (pdf, doc, docx) from download folder in Android 11 and above

I'm using the File Picker library.
Permission code:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R || Environment.isExternalStorageManager()) {
//Toast.makeText(this, "We can access all files on external storage now", Toast.LENGTH_SHORT).show()
} else {
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, FILE_REQUEST_CODE);
}
Choose file:
Intent intent = new Intent(this, FilePickerActivity.class);
intent.putExtra(FilePickerActivity.CONFIGS, new Configurations.Builder()
.setCheckPermission(true)
.setSelectedMediaFiles(mediaFiles)
.setShowFiles(true)
.setShowImages(false)
.setShowAudios(false)
.setShowVideos(false)
.setIgnoreNoMedia(false)
.enableVideoCapture(false)
.enableImageCapture(false)
.setIgnoreHiddenFile(false)
.setMaxSelection(5)
.setSuffixes("pdf", "doc", "docx")
//.setTitle("Select a file")
.build());
startActivityForResult(intent, FILE_REQUEST_CODE);
onActivityResult:
if (requestCode == FILE_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
//ArrayList<MediaFile> files = data.getParcelableArrayListExtra(FilePickerActivity.MEDIA_FILES);
//Do something with files
List<MediaFile> mediaFiles = data.<MediaFile>getParcelableArrayListExtra(FilePickerActivity.MEDIA_FILES);
if (mediaFiles != null) {
System.out.println(mediaFiles.get(0).getUri());
setMediaFiles(mediaFiles);
} else {
Toast.makeText(ApplyLeaveActivity.this, "File not selected", Toast.LENGTH_SHORT).show();
}
}
Get file from selected location:
private void setMediaFiles(List<MediaFile> mediaFiles) {
this.mediaFiles.clear();
this.mediaFiles.addAll(mediaFiles);
for (int i = 0; i < mediaFiles.size(); i++) {
System.out.println(mediaFiles.get(i).getUri().getPath());
/*Uri fileUri = Uri.fromFile(selectedFile);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
fileUri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", selectedFile);
}*/
String path = RealPathUtil.getRealPath(this, mediaFiles.get(i).getUri());
//String path = getPath(mediaFiles.get(i).getUri());
if (path != null && !path.isEmpty()) {
File file = new File(path);
//String path = getPathFromURI(mediaFiles.get(i).getUri());
//String path = RealPathUtil.getRealPath(this, mediaFiles.get(i).getUri());
//System.out.println("Path: " + path);
///document/raw:/storage/emulated/0/Download/file-sample_150kB(1).pdf
LeaveDocBean leaveDocBean = new LeaveDocBean();
leaveDocBean.setId("");
leaveDocBean.setFile(file.getAbsolutePath());
//leaveDocBean.setFile(path);
leaveDocBean.setFileName(path.substring(path.lastIndexOf('/') + 1));
mLeaveDocBeanList.add(leaveDocBean);
} else {
Toast.makeText(this, "Unable to select file", Toast.LENGTH_LONG).show();
}
}
refreshDocAdapter();
//fileListAdapter.notifyDataSetChanged();
}
Get its real path:
public class RealPathUtil {
public static String getRealPath(Context context, Uri fileUri) {
String realPath;
// SDK < API11
if (Build.VERSION.SDK_INT < 11) {
realPath = RealPathUtil.getRealPathFromURI_BelowAPI11(context, fileUri);
}
// SDK >= 11 && SDK < 19
else if (Build.VERSION.SDK_INT < 19) {
realPath = RealPathUtil.getRealPathFromURI_API11to18(context, fileUri);
}
// SDK > 19 (Android 4.4) and up
else {
realPath = RealPathUtil.getRealPathFromURI_API19(context, fileUri);
}
return realPath;
}
#SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
String result = null;
CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
cursor.close();
}
return result;
}
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = 0;
String result = "";
if (cursor != null) {
column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
cursor.close();
return result;
}
return result;
}
/**
* Get a file path from a Uri. This will get the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #author paulburke
*/
#SuppressLint("NewApi")
public static String getRealPathFromURI_API19(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];
}*/
// This is for checking Main Memory
if ("primary".equalsIgnoreCase(type)) {
if (split.length > 1) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else {
return Environment.getExternalStorageDirectory() + "/";
}
// This is for checking SD Card
} else {
return "storage" + "/" + docId.replace(":", "/");
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
if (!TextUtils.isEmpty(id)) {
if (id.startsWith("raw:")) {
return id.replaceFirst("raw:", "");
}
}
//final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
//return getDataColumn(context, contentUri, null, null);
String[] contentUriPrefixesToTry = new String[]{
"content://downloads/public_downloads",
"content://downloads/my_downloads",
"content://downloads/all_downloads"
};
for (String contentUriPrefix : contentUriPrefixesToTry) {
try {
final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
/* final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));*/
return getDataColumn(context, contentUri, null, null);
} catch (NumberFormatException e) {
//In Android 8 and Android P the id is not a number
return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", "");
}
}
}
// 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;
} else if ("document".equals(type)) {
contentUri = MediaStore.Files.getContentUri("external", Long.valueOf(split[1]));
// return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getPath() + "/" + split[1];
// return "content://com.android.providers.media.documents/document/"+split[1];
}
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;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #param selection (Optional) Filter used in the query.
* #param selectionArgs (Optional) Selection arguments used in the query.
* #return The value of the _data column, which is typically a file path.
*/
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);
}
} catch (Exception e) {
return null;
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}
Issue: not able to get a file's real path in Android 11 and above; it's working fine up to Android 10. If I choose a file from another location (example: documents, internal storage), it's working in Android 11 and above, but not working if I choose a file from download folders.
Sample path:
Uri: content://com.android.providers.media.documents/document/document%3A36
ABS Path: /document/document:36 -->not able to get real path
Actual Path: storage/1216-330D/Documents/sample.pdf
I missed to do this (working fine after adding below code)
private String copyFileToInternal(Uri fileUri) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Cursor cursor = getContentResolver().query(fileUri, new String[]{OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null);
cursor.moveToFirst();
String displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
long size = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE));
File file = new File(getFilesDir() + "/" + displayName);
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
InputStream inputStream = getContentResolver().openInputStream(fileUri);
byte buffers[] = new byte[1024];
int read;
while ((read = inputStream.read(buffers)) != -1) {
fileOutputStream.write(buffers, 0, read);
}
inputStream.close();
fileOutputStream.close();
return file.getPath();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
Finally I got the answer, download PDF file and save using below path/code and get Uri from the path and share it, it is working fine upto Android 12
String dirPath;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
dirPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + "/" + getString(R.string.app_name) + "/";
} else {
dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getString(R.string.app_name) + "/";
}

How to choose pdf file from android storage

I'm trying to get a pdf file from my android storage, but everytime it returns null.
It already works with image files, but when i try to get a pdf file it always returns null.
I'm already able to select the pdf file. On onActivityResult i'm able to get the uri from data, but the path is wrong ("content://com.android.providers.media.documents/document/document%3A140"), so i'm trying to get the full path using getPath method, but like i said before, it always returns null.
This code must work with android version >= Android 6.0 (Sdk 23).
private void selecionarArquivo() {
boolean marshmallow = Build.VERSION.SDK_INT >= 22;
boolean validate;
if (marshmallow) {
String permissions[] = new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE };
validate = PermissionUtils.validate(getActivity(), 0, permissions);
} else {
validate = true;
}
if (validate) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// tipo can be application/pdf or image/*
intent.setType(tipo);
startActivityForResult(intent, Constantes.REQUEST_CODE_SELECIONAR_ARQUIVO);
} else {
AlertUtils.alert(getActivity(), R.string.necessario_aceitar_permissoes, new Runnable() {
#Override
public void run() {
getActivity().finish();
}
});
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
LogUtil.log(TAG, "onActivityResult(): requestCode[" + requestCode + "], resultCode[" + resultCode + "]");
if (requestCode == Constantes.REQUEST_CODE_SELECIONAR_ARQUIVO && resultCode == Activity.RESULT_OK && data != null) {
LogUtil.log(TAG, "onActivityResult(): SELECIONOU");
Uri selectedImageUri = data.getData();
final String path = FileUtils.getPath(getContext(), selectedImageUri);
// here path is always null if pdf file is selected
File f = null;
if (path != null) {
f = new File(path);
}
if (f != null) {
String fileExtension = FileUtils.getFileExtension(f.getName());
if (tipo.contains("pdf") && !fileExtension.equals("pdf")) {
alert(R.string.tipo_de_arquivo_invalido);
selecionarArquivo();
} else {
Bundle bundle = new Bundle();
foto.file = f;
bundle.putSerializable(Foto.KEY, foto);
showForResult(ExemploEFotoActivity.class, bundle, Constantes.REQUEST_CODE_CONFIRMAR_FOTO);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
alert(R.string.msg_error_foto);
getActivity().finish();
}
}
FileUtils.java
public class FileUtils {
public static String getPath(final Context context, final Uri uri) {
if (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;
} else if ("document".equals(type)) {
contentUri = 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;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
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 column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
}
I end up using this FileUtils, wich worked perfectly.
Thanks for the answers.

How to get a path of image (URI) and send it to database?

I have a code to get an image if I click the button, in my problem, I wanna get the URI/path of the image and send it into the database, after that I wanna show it in ImageView. And this is my code.
#Override
public void onActivityResult(int req, int res, Intent imageIntent) {
super.onActivityResult(req, res, imageIntent);
switch (req) {
case SELECT_ICON:
if (res == RESULT_OK) {
try {
final Uri iconUri = imageIntent.getData();
final String imgUri = iconUri.toString();
final InputStream iconStream = getContentResolver().openInputStream(iconUri);
final Bitmap selectedIcon = BitmapFactory.decodeStream(iconStream);
imageView.setImageBitmap(selectedIcon);
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
String tname = text1.getText().toString();
String date = textView.getText().toString();
String priority = spinner1.getSelectedItem().toString();
String notes = text2.getText().toString();
String path = imgUri;
dbHelper.addTask(new Task(tname, date, priority, notes, path));
Toast.makeText(getApplicationContext(), "Success!!!", Toast.LENGTH_LONG).show();
TaskListActivity.tasklist.RefreshList();
finish();
}
});
} catch (FileNotFoundException err) {
err.printStackTrace();
}
}
}
}
You can use String strUri = uri.toString() to convert Uri to String save this strUri to database and while retrieving from database you can use Uri uri = Uri.parse(strUri) for converting string back to Uri
I used these methods to get path from URI
private String getActualFilePath(Context context, Uri fileUri) throws URISyntaxException{
Uri uri = Uri.parse(fileUri);
final boolean needToCheckUri = Build.VERSION.SDK_INT >= 19;
String selection = null;
String[] selectionArgs = null;
// Uri is different in versions after KITKAT (Android 4.4), we need to
// deal with different Uris.
if (needToCheckUri && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
uri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("image".equals(type)) {
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
selection = "_id=?";
selectionArgs = new String[]{ split[1] };
}
}
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private void LogException(Exception ex){
if(ex != null){
try{
ex.printStackTrace(logPrintWriter);
String data = logStringWriter.toString();
AddErrorLogEntry(data);
}finally {
Log.d(TAG, "Logged exception in file");
}
}
}

Uploading a File shows Null using ion library

I am trying to upload a PDF file to server but am getting a Null toast according to my method , i tested the file path in a TextView is visible but when it comes to uplaoding it seems not seeing the PDF file , am using ion library. Below is my code sample.
public void uploadFile(final String selectedFilePath){
final ProgressDialog pd;
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Uploading ...");
pd.setCancelable(false);
pd.show();
//File file = new File(this.getFilesDir().getAbsolutePath() + "/thesubdirectory/the.zip");
File f = new File(getApplicationContext().getFilesDir().getAbsolutePath()+selectedFilePath);
try {
RandomAccessFile rf = new RandomAccessFile(f, "rw");
rf.setLength(1024 * 1024 * 2);
} catch (Exception e) {
System.err.println(e);
}
File echoedFile = getFileStreamPath("echo");
Ion.with(MainActivity.this)
.load(SERVER_URL)
.uploadProgressDialog(pd)
.setMultipartFile("uploaded_file",f)
.write(echoedFile)
.setCallback(new FutureCallback<File>() {
#Override
public void onCompleted(Exception e, File result) {
try {
Toast.makeText(MainActivity.this, " " + result, Toast.LENGTH_LONG).show();
System.out.println("Error " + result);
pd.dismiss();
} catch (Exception e1) {
System.out.println("Error " + e1);
}
pd.dismiss();
}
});
}
This is the rest of code.
public class MainActivity extends AppCompatActivity {
private static final int PICK_FILE_REQUEST = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private String selectedFilePath;
private String SERVER_URL = "http://192.168.43.104:8093/PoliceApp/FileUpload.aspx";
ImageView ivAttachment;
private ImageView imageView;
private EditText firstname_edt,lastname_edt,email_edt,jobtitle_edt,source_edt;
private TextView directory_txt,count_txt,upload_txt;
private Button button;
Future<File> uploading;
ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Enable global Ion logging
Ion.getDefault(this).configure().setLogging("ion-sample", Log.DEBUG);
setContentView(R.layout.activity_main);
imageView= (ImageView)findViewById(R.id.imageView);
firstname_edt=(EditText)findViewById(R.id.firstname_edt);
lastname_edt=(EditText)findViewById(R.id.lastname_edt);
email_edt=(EditText)findViewById(R.id.email_edt);
jobtitle_edt=(EditText)findViewById(R.id.jobtitle_edt);
source_edt=(EditText)findViewById(R.id.source_edt);
button=(Button)findViewById(R.id.button);
directory_txt=(TextView)findViewById(R.id.directory_txt);
count_txt=(TextView)findViewById(R.id.count_txt);
upload_txt=(TextView)findViewById(R.id.upload_txt);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showFileChooser();
}
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selectedFilePath != null){
// pd = ProgressDialog.show(MainActivity.this,"","Uploading File...",true);
uploadFile(selectedFilePath);
// OnSendFileInfo();
}else{
Toast.makeText(MainActivity.this,"Please choose a File First",Toast.LENGTH_SHORT).show();
}
}
});
}
// Gallery pick
private void showFileChooser() {
Intent intent = new Intent();
//sets the select file to all types of files
intent.setType("*/*");
//allows to select data and return it
intent.setAction(Intent.ACTION_GET_CONTENT);
//starts new activity to select file and return data
startActivityForResult(Intent.createChooser(intent,"Choose File to Upload.."),PICK_FILE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == Activity.RESULT_OK){
if(requestCode == PICK_FILE_REQUEST){
if(data == null){
//no data present
return;
}
Uri selectedFileUri = data.getData();
selectedFilePath = FilePath.getPath(this,selectedFileUri);
Log.i(TAG,"Selected File Path:" + selectedFilePath);
if(selectedFilePath != null && !selectedFilePath.equals("")){
directory_txt.setText(selectedFilePath);
}else{
Toast.makeText(this,"Cannot upload file to server",Toast.LENGTH_SHORT).show();
}
}
}
}
This is the filepath class which returns file path of Gallery image/ Document / Video / Audio
public class FilePath {
/**
* Method for return file path of Gallery image/ Document / Video / Audio
*
* #param context
* #param uri
* #return path of the selected image file from gallery
*/
#TargetApi(19)
public static String getPath(final Context context, final Uri uri) {
// check here to KITKAT or new version
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;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* #param context
* The context.
* #param uri
* The Uri to query.
* #param selection
* (Optional) Filter used in the query.
* #param selectionArgs
* (Optional) Selection arguments used in the query.
* #return The value of the _data column, which is typically a file path.
*/
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;
}
/**
* #param uri
* The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri
.getAuthority());
}
/**
* #param uri
* The Uri to check.
* #return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri
.getAuthority());
}
/**
* #param uri
* The Uri to check.
* #return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri
.getAuthority());
}
/**
* #param uri
* The Uri to check.
* #return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri
.getAuthority());
}
}
This is the filepath class which returns file path of Gallery image/ Document / Video / Audio
That class is a piece of junk. It will not work for many Uri values on any Android device, let alone those devices where the "rules" encoded in that class have changed, due to manufacturer alterations or OS updates.
Moreover, none of those locations are inside of getFilesDir().
Use the Uri properly: use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Either pass that InputStream to Ion (if it supports uploading from a stream), or use the stream to make a local copy of the content (e.g., into getCacheDir()), then upload the local copy.

Get filepath and filename of selected gallery image in Android

I am creating an app which uploads a selected image from the gallery and uploads it to a web service. The webservice requires the filename of selected image plus a base64 encoding of the file contents. I have managed to achieve this with a hardcoded file path. However, I am struggling to get the real filepath of the image. I have read around the web and have this code, but it does not work for me:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
String[] projection = {MediaStore.Images.Media.DATA};
try {
Cursor cursor = getContentResolver().query(selectedImageUri, projection, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Log.d("Picture Path", picturePath);
}
catch(Exception e) {
Log.e("Path Error", e.toString());
}
}
}
I get this error:
java.lang.NullPointerException
EDIT
Forgot to mention I am using Kitkat. It looks like my problem is KitKat related. I found this (see below) which helped me get my app working:
Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT
A little late to the party but here's my code, hope this helps.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData( );
String picturePath = getPath( getActivity( ).getApplicationContext( ), selectedImageUri );
Log.d("Picture Path", picturePath);
}
}
public static String getPath( Context context, Uri uri ) {
String result = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver( ).query( uri, proj, null, null, null );
if(cursor != null){
if ( cursor.moveToFirst( ) ) {
int column_index = cursor.getColumnIndexOrThrow( proj[0] );
result = cursor.getString( column_index );
}
cursor.close( );
}
if(result == null) {
result = "Not found";
}
return result;
}
Use below code,
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
String s = getRealPathFromURI(selectedImageUri);
editText1.setText(s);
}
}
and below is your getRealPathFromURI function,
public String getRealPathFromURI(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
#SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Try this:
Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));
And
private String getRealPathFromURI(Uri contentURI) {
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
return contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
}
public class RealFilePath {
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query
*/
public static 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];
}
// TODO handle non-primary volumes
}
// 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;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #param selection (Optional) Filter used in the query.
* #param selectionArgs (Optional) Selection arguments used in the query.
* #return The value of the _data column, which is typically a file path.
*/
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;
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}
If you are like me and you dont have a local file ready, for instance you want to give user a chance to take a picture and then upload the picture this is how to do it.
I am a noob in java but i have allot of experience in coding.
Stackoverflow helped me allot so now it is my time to do something back.
Under class activity you have to declare these two items.
asuming you have a working upload class and php script.
NOTE i am not taking any consideration about all the different API's
out there. I am using java compiler 1.7 and a API range of 10 to 18.
public class Yourproject extends Activity {
File imageFile;
File imageFileName;
//This part is needed for decoding the path adres.
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
//This is needed for the path name, now you might just want to use one decoding script depending on //your class in total.
//In my case this was the way to go.
//To use one single addres use this line ImageColumns.DATA in the int idx declaration.
private String getRealPathFromNAME(Uri contentNAME) {
String result;
Cursor cursor = getContentResolver().query(contentNAME, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentNAME.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
//Then under protected void onCreate(Bundle savedInstanceState) you place this code to get
//the image and process it.
#Override
protected void onCreate(Bundle savedInstanceState) {
//declare the ImageView
final ImageView inputPicture = (ImageView) findViewById(R.id.imageView2);
inputPicture.setImageURI((Uri) getIntent().getExtras().get("picture"));
//here where recieve the image from last page "Putextra" method
try {
//here we will get the data and proces it trough to get the real
//address for uploading.
//This is send from a other activity with a Intent.EXTRA_STREAM
//The code looks like this:
/*********"Putextra"*********/
//final ImageView iv = (ImageView) findViewById(R.id.imageView1);
//final Uri thumb = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);
//iv.setImageURI(thumb);
//Sending it to the next activity
//it.putExtra("picture", thumb);
/*********"Putextra"*********/
Uri fileUri = (Uri) getIntent().getExtras().get("picture");
//get
//Uri fileName = (Uri) getIntent().getExtras().get("picture");
//get
imageFile = new File(getRealPathFromURI(fileUri));
//send
imageFileName = new File(getRealPathFromNAME(fileUri));
//send
//i got a exeption Uri fileName, use fileUri twice..
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
//here we will declare the name for furter processing.
final File uploadFilePath = imageFile;
final File uploadFileName = imageFileName;
}
And the rest i will leave up to u, if you got this far, I am pretty sure you will finish.
Try this,
file = new File(getPath(outputFileUri));
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
#SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Hope this helps you
if (Build.VERSION.SDK_INT <19){
Intent intent = new Intent();
intent.setType("image/jpeg");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
getResources().getString(R.string.select_picture)),GALLERY_INTENT_CALLED);
}else{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/jpeg");
startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) return;
if (null == data) return;
Uri originalUri = null;
if (requestCode == GALLERY_INTENT_CALLED) {
originalUri = data.getData();
}
else if (requestCode == GALLERY_KITKAT_INTENT_CALLED) {
originalUri = data.getData();
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(originalUri, takeFlags);
}
loadSomeStreamAsynkTask(originalUri);
}
Try this to get data as well as file path and insert into folder.
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
try {
if (resultCode == RESULT_OK)
{
nav = data.getData();
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(nav, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path= cursor.getString(column_index);
Toast.makeText(getApplicationContext(), path, 500).show();
mBitmap = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), nav);
insert(mBitmap);
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void insert(Bitmap finalBitmap) {
File myDir=new File("/sdcard/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
File dstFile = new File(file.getParent(), "." + file.getName());
file.renameTo(dstFile);
} catch (Exception e) {
e.printStackTrace();
}
}

Categories