Related
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.
I have a screen where on a button click I open a file chooser and then I select a file named "Test.jpg" for further operation.
I use following code to get name of that file.
Uri uri = data.getData();
File file = new File(uri.getPath());
String fileName = file.getName();
Here are the results from debugger
file.getName() => 167522
file.toString() => /external/images/media/167522
I want to get Test.jpg as my filename.
Please let me know what is wrong with my code.
Need path from your uri. here is a method to get path from uri.
public String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { "_data" };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it
}
}
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
Get file name
try{
//call the getPath uri with context and uri
//To get path from uri
String path = getPath(this, uri);
File file = new File(path);
String filename = file.getName();
Log.e(TAG, "File Name: " + filename);
}catch(Exception e){
e("Err", e.toString()+"");
}
output
uri: content://com.android.providers.media.documents/document/image%3A12876
FileName : profile.png
This method worked for me in Kotlin:
private fun getFilename(uri: Uri): String? {
val cursor = activity?.contentResolver?.query(uri, null, null, null, null)
var filename: String? = null
cursor?.getColumnIndex(OpenableColumns.DISPLAY_NAME)?.let { nameIndex ->
cursor.moveToFirst()
filename = cursor.getString(nameIndex)
cursor.close()
}
return filename
}
Try to use this method:
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
I am trying to save an image, and alert the Gallery about the new image. The image is not immediately shown in the gallery, but it can take even a few hour to refresh. I use the following code:
String title = "title";
String r = MediaStore.Images.Media.insertImage(getContentResolver(), State.pictureWithDekor, title, title);
Uri uri = Uri.parse(r);
MediaScannerConnection.scanFile(this,
new String[] { uri.getPath() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("TAG", "Finished scanning " + path);
}
});
the value of r after the insertImage is content://media/external/images/media/2082, the uri in the onScanCompleted is null.
What am I doing wrong?
The problem is that the path returned from the MediaStore.Images.Media.insertImage is not a phisical path. to get the real path, use:
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
Source: Get filename and path from URI from mediastore
I'm trying to select image from gallery then convert this image to File and send it via HttpPost but I'm getting always FileNotFoundException. This my Code :
Selecting the photo
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 1) {
// currImageURI is the global variable I’m using to hold the content:
currImageURI = data.getData();
//Save the currImageUri (URI type) to global variable.
photosHolder.getInstance().setOneIm(currImageURI);
}
}
}
Converting the photo
// First Try
File myFile = new File((photosHolder.getInstance().getOneIm()).toString());
params.put("visit_report[photos_attributes][0][file]",myFile); **The exception Raised here
// second try
File myFile2 = new File((photosHolder.getInstance().getOneIm()).getPath());
params.put("visit_report[photos_attributes][1][file]",myFile2); ** Also here
And those are myFiles Value while debuging :
mFile : content:/com.android.providers.media.documents/document/image%3A19143
myFile2 : /document/image:19143
So any help ?
Update
I have tried this solution also :
//get The real path from uri then save it (and then use it to create the file)
photosHolder.getInstance().setUriString(getRealPathFromURI(currImageURI));
//Convert the image URI to the direct file system path of the image file
private String getRealPathFromURI(Uri contentURI) {
String result = "";
try {
Cursor cursor = getActivity().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.DATA);
result = cursor.getString(idx); // Exception raised HERE
cursor.close(); }
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
But I got java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it and the idx var == to -1
Also I have tried #Praneeth Kalluri Solution but it returns always null as result.
Uri currImageURI = data.getData();
printing currImageURI will give you some thing like this:
content://media/external/images/media/47
But what we need is the absolute path of that particular image . So we need to get real path from uri
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
Now modifiy your code like
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 1) {
// currImageURI is the global variable I’m using to hold the content:
currImageURI = data.getData();
//Save the currImageUri (URI type) to global variable.
photosHolder.getInstance().setOneIm(getRealPathFromURI(getActivity(),currImageURI));
}
}
}
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
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();
}
}