Get correct Uri from file chooser with google drive - android

so here is my problem, i need to get a file in phone and then upload it to my parse-server. I've made a file chooser for document, download, external, media folder but android file chooser also propose GoogleDrive option. So i got te Uri but i can't find a way to access that "local copy?".
Do i need to use GoogleDrive SDK to access it? Or can't android just be smart enough and give me methods to handle that Uri ?
I did success getting file name.
content://com.google.android.apps.docs.storage/document/
Here is my file chooser and handler:
public static void pick(final Controller controller) {
final Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
chooseFileIntent.setType("application/pdf");
chooseFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
if (chooseFileIntent.resolveActivity(controller.getContext().getPackageManager()) != null) {
controller.startActivityForResult(chooseFileIntent, Configuration.Request.Code.Pdf.Pdf);
}
}
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 boolean isGoogleDriveUri(Uri uri) {
return "com.google.android.apps.docs.storage".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()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private static String getPath(Context context, Uri uri) {
if (DocumentsContract.isDocumentUri(context, uri)) {
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];
}
} else if (isGoogleDriveUri(uri)) {
// Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
// if (cursor != null) {
// int fileNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
// cursor.moveToFirst();
// Log.d("=== TAG ===", cursor.getString(fileNameIndex));
// Log.d("=== TAG ===", uri.getPath());
// cursor.close();
// }
} 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);
} 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);
}
}
else if ("content".equalsIgnoreCase(uri.getScheme())) {
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
public static void upload(final Context context, final String name, final ParseObject dataSource, final String field, final Uri uri, final Handler handler) {
if (context != null && name != null && dataSource != null && field != null && uri != null) {
String path = getPath(context, uri);
if (path != null) {
final File file = new File(path);
dataSource.put(field, new ParseFile(file));
dataSource.getParseFile(field).saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
if (handler != null) {
handler.success();
}
}
}
}, new ProgressCallback() {
#Override
public void done(Integer percentDone) {
if (handler != null) {
handler.progress(percentDone);
}
}
});
}
}
}
EDIT :
I've made some try but i got a problem when deleting the temporary file
Here is my code:
public static void copyFile(final Context context, final Uri uri, final ParseObject dataSource, final String field, final String name, final Data.Source target, final Handler handler) {
new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
if (inputStream != null) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int length;
while ((length = inputStream.read(bytes)) != -1) {
byteArrayOutputStream.write(bytes, 0, length);
}
dataSource.put(field, new ParseFile(name, byteArrayOutputStream.toByteArray()));
byteArrayOutputStream.close();
inputStream.close();
return true;
} else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
dataSource.getParseFile(field).saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
if (handler != null) {
handler.success();
}
}
}
}, new ProgressCallback() {
#Override
public void done(Integer percentDone) {
if (handler != null) {
handler.progress(percentDone);
}
}
});
}
}.execute();
}
Final Edit:
Here my code is correct, temporary file are created and put in cache by Parse himself, so its out of my range. Hope he can help.

So i got te Uri but i can't find a way to access that "local copy?".
There is no "local copy", at least one that you can access.
Or can't android just be smart enough and give me methods to handle that Uri ?
Use ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Either use that directly with your "parse-server", or use it to create a temporary "local copy" to a file that you control. Upload that local copy, deleting it when you are done.
Here is my file chooser and handler:
pick() is fine. upload() might be fine; I have not used Parse. The rest of that code is junk, copied from prior junk. It makes many unfounded, unreliable assumptions, and it will not work for Uri values from arbitrary apps (e.g., served via FileProvider).

Related

How to get absolute PATH from Uri picked from Downloads folder? [duplicate]

This question already has answers here:
Android Kotlin: Getting a FileNotFoundException with filename chosen from file picker?
(5 answers)
Android - Get real path of a .txt file selected from the file explorer
(1 answer)
Closed 1 year ago.
I want to get absolute path by Uri, when picking some files from Downloads folder. API level 21+.
Currently I have such errors:
Input Uri: content://com.android.providers.downloads.documents/document/1603
Path: content://downloads/public_downloads/1603
Giving error: java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/1603
or this one:
java.io.FileNotFoundException: /document/msf:64020: open failed: ENOENT (No such file or directory)
java.lang.NumberFormatException: For input string: "msf:64020"
depending on how I access such files. How can I do that properly? Maby you can provide some usuful link to documentation. Thanks.
This is my current solution:
private FileUtils() {
}
static final String TAG = "FileUtils";
public static final String MIME_TYPE_AUDIO = "audio/*";
public static final String MIME_TYPE_TEXT = "text/*";
public static final String MIME_TYPE_IMAGE = "image/*";
public static final String MIME_TYPE_VIDEO = "video/*";
public static final String MIME_TYPE_APP = "application/*";
public static final String HIDDEN_PREFIX = ".";
public static String getExtension(String uri) {
if (uri == null) {
return null;
}
int dot = uri.lastIndexOf(".");
if (dot >= 0) {
return uri.substring(dot);
} else {
// No extension.
return "";
}
}
public static boolean isLocal(String url) {
return url != null && !url.startsWith("http://") && !url.startsWith("https://");
}
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;
}
public static String getPath(final Context context, final Uri uri) {
// DocumentProvider
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 ----- This if-else is working wrong.
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.parseLong(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;
}
public static File getFile(Context context, Uri uri) {
if (uri != null) {
String path = getPath(context, uri);
if (!Strings.isNullOrEmpty(path) && isLocal(path)) {
return new File(path);
}
}
return null;
}
public static Intent createGetContentIntent(String mimeType) {
final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType(mimeType);
// Only return URIs that can be opened with ContentResolver
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
return intent;
}
}
And this is in myActivity:
public void checkPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE},
IMAGE_PICKER_PERMISSION_KEY);
} else {
startImagePickerActivity();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == IMAGE_PICKER_PERMISSION_KEY && grantResults.length == 2
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
startImagePickerActivity();
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && data != null) {
if (requestCode == REQUEST_CODE_CHOOSE) {
ClipData clipData = data.getClipData();
if (clipData != null) {
//user choose 2+ images
int i = 0;
while (i < clipData.getItemCount()) {
onPhotoAdded(clipData.getItemAt(i).getUri());
i++;
}
} else if (data.getData() != null) {
//user choose only 1 image
onPhotoAdded(data.getData());
}
}
}
}
public void onPhotoAdded(Uri uri) {
try {
File f = FileUtils.getFile(this, uri);
if (f == null) {
Log.d("LOG", "File is null");
} else {
listOfUri.add(uri);
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
Log.d("LOG", e.getMessage());
}
}

IllegalArgumentException while getting the value of data column from uri

I was using below code to get a file path from Uri.
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];
} else {
// Below logic is how External Storage provider build URI for documents
// Based on http://stackoverflow.com/questions/28605278/android-5-sd-card-label and https://gist.github.com/prasad321/9852037
StorageManager mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
try {
Class<?> storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getUuid = storageVolumeClazz.getMethod("getUuid");
Method getState = storageVolumeClazz.getMethod("getState");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isPrimary = storageVolumeClazz.getMethod("isPrimary");
Method isEmulated = storageVolumeClazz.getMethod("isEmulated");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
//String uuid = (String) getUuid.invoke(storageVolumeElement);
final boolean mounted = Environment.MEDIA_MOUNTED.equals(getState.invoke(storageVolumeElement))
|| Environment.MEDIA_MOUNTED_READ_ONLY.equals(getState.invoke(storageVolumeElement));
//if the media is not mounted, we need not get the volume details
if (!mounted) continue;
//Primary storage is already handled.
if ((Boolean) isPrimary.invoke(storageVolumeElement) && (Boolean) isEmulated.invoke(storageVolumeElement))
continue;
String uuid = (String) getUuid.invoke(storageVolumeElement);
if (uuid != null && uuid.equals(type)) {
String res = getPath.invoke(storageVolumeElement) + "/" + split[1];
return res;
}
}
} catch (Exception ex) {
}
}
}
// 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);
}
// 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;
}
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
/**
* Get the value of the data column for this Uri.
*/
private 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;
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
private 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.
*/
private 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.
*/
private boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
But sometimes getting below exception in Crashlytics-
Fatal Exception: java.lang.IllegalArgumentException: column '_data' does not exist. Available columns: [] at
android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:340)
at
android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:87)
at
To resolve this I changed(seeing this) -
private 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;
}
to
private 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);
}
} catch(IllegalArgumentException e) {
getFilePathFromURI(context,uri);
}finally
{
if (cursor != null)
cursor.close();
}
return null;
}
public static String getFilePathFromURI(Context context, Uri contentUri) {
//copy file and send new file path
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
boolean success = true;
if (!moviesDir.exists()) {
success = moviesDir.mkdir();
}
if(success) {
String fileName = getFileName(contentUri);
if (!TextUtils.isEmpty(fileName)) {
File copyFile = new File(moviesDir, fileName+".mp4");
copy(context, contentUri, copyFile);
return copyFile.getAbsolutePath();
}
}
return null;
}
public static String getFileName(Uri uri) {
if (uri == null) return null;
String fileName = null;
String path = uri.getPath();
int cut = path.lastIndexOf('/');
if (cut != -1) {
fileName = path.substring(cut + 1);
}
return fileName;
}
public static void copy(Context context, Uri srcUri, File dstFile) {
try {
InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
if (inputStream == null) return;
OutputStream outputStream = new FileOutputStream(dstFile);
IOUtils.copy(inputStream, outputStream);
inputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
How optimal is this solution?And is there any better way of handling this?

How to get PDF file path using Android Studio?

I am working on project were i have to upload PDF file or DOC file i have write too much codes but no success
whenever i clicked submit Toast say Upload PDF File and Activity exit.
how to solve the problem?
here is the Code i use
public class contactus extends AppCompatActivity {
EditText name,email,mobile;
Button submit,uploadCv;
public static final String pdfurl = "https://umsctest.000webhostapp.com/testdb/upload.php";
Uri uri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contactus);
name = findViewById(R.id.et_name);
email = findViewById(R.id.et_email);
mobile = findViewById(R.id.et_no);
submit = findViewById(R.id.bt_submit);
uploadCv = findViewById(R.id.bt_uploadCv);
InputFilter[] inputFilter = new InputFilter[1];
inputFilter[0] = new InputFilter.LengthFilter(10);
mobile.setFilters(inputFilter);
uploadCv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
uploadfile();
}
});
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String fname = name.getText().toString();
String mail = email.getText().toString();
String mob = mobile.getText().toString();
String filepath = FilePath.getPath(contactus.this,uri);
if (filepath == null)
{
Toast.makeText(getApplicationContext(),"Please Upload PDF file",Toast.LENGTH_SHORT).show();
}else
{
String pdfId = UUID.randomUUID().toString();
try {
new MultipartUploadRequest(contactus.this,pdfId,pdfurl).addFileToUpload(filepath, "pdf")
.addParameter("name",fname)
.addParameter("email",mail)
.addParameter("mobile",mob)
.setNotificationConfig(new UploadNotificationConfig())
.setMaxRetries(5)
.startUpload();
} catch (FileNotFoundException e) {
Toast.makeText(getApplicationContext(),"Error in Uploading Fis",Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (MalformedURLException e) {
Toast.makeText(getApplicationContext(),"Error in Uploading File",Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
if (fname.length() <=0)
{
name.setError("Name Please");
}else if (mail.length() <=0)
{
email.setError("Email Please");
}else if (mob.length() <=0)
{
mobile.setError("WhatsApp No. Please");
}else if (mob.length() >10)
{
mobile.setError("Only 10 Digits No.");
}else
{
name.setText("");
email.setText("");
mobile.setText("");
}
}
});
}
private void uploadfile() {
Intent intent = new Intent();
intent.setType("application/pdf");
intent.setAction(intent.ACTION_GET_CONTENT);
startActivityForResult(intent.createChooser(intent,"Select Pdf"),1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK && data !=null)
{
Uri path = data.getData();
uploadCv.setText("PDF Selected");
}
}
this is my contactus(mainactivity).java
and i also used FilePath.java
public class FilePath {
public static String getPath(final Context context, final Uri uri)
{
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat && 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);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}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]};
}else if ("content".equalsIgnoreCase(uri.getScheme())) {
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
}
return null;
}
private static String getDataColumn(Context context, Uri contentUri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(contentUri, 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;
}
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());
}
}
Help me out its returns Null path

Unable to get the image path from whatsapp share URI

Uri = content://com.whatsapp.provider.media/item/118727
I'm not able to get the actual path from this URI
Following the Documentation , i receive the image intent through :
void onCreate (Bundle savedInstanceState) {
...
// Get intent, action and MIME type
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if (type.startsWith("image/")) {
handleSendImage(intent); // Handle single image being sent
}
}
}
ContentResolver wasn't working in this case as "_data" field was returning null. So i found another way to get a file from content URI.
In handleSendImage() you need to open inputStream and then copy it into a file.
void handleSendImage(Intent intent) throws IOException {
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) {
File file = new File(getCacheDir(), "image");
InputStream inputStream=getContentResolver().openInputStream(imageUri);
try {
OutputStream output = new FileOutputStream(file);
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
} finally {
output.close();
}
} finally {
inputStream.close();
byte[] bytes =getFileFromPath(file);
//Upload Bytes.
}
}
}
getFileFromPath() gets you the bytes which you can upload on your server.
public static byte[] getFileFromPath(File file) {
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bytes;
}
You can get imageFilePath from getRealPathFromUri() below:
String filePath = getRealPathFromUri(this, fileUri);
// You can upload it as File
if (filePath != null && !filePath.isEmpty()) {
File file = new File(filePath);
if (file.exists()) {
// Using Retrofit you can do it like
// create Retrofit Client code......
// creates RequestBody instance from file
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual filename
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
// pass body as parameter while execute call
}
}
getRealPathFromUri()
public static String getRealPathFromUri(Context context, final Uri uri) {
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && 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;
}
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()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
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());
}

Android: All file ain't readable. File finder

i'am trying to make a finder to get '.pdf', i got my Uri the file exist but he always return false for File.canRead()
Just before trying to upload that document on my parse server i log this:
final File file = new File(path);
Log.d("=== TAG ====", file.getAbsolutePath());
Log.d("=== TAG ====", String.valueOf(file.exists()));
Log.d("=== TAG ====", String.valueOf(file.canRead()));
Give me this:
06-27 10:58:03.746 24136-24136/bruce.team D/=== TAG ====: /storage/emulated/0/Download/random.pdf
06-27 10:58:03.747 24136-24136/bruce.team D/=== TAG ====: true
06-27 10:58:03.747 24136-24136/bruce.team D/=== TAG ====: false
Then it's just fail uploading after 15 sec, my parse-server isn't access so it must be the read problem !
Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
My way to pick it:
public static void pick(final Controller controller) {
final Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
chooseFileIntent.setType("application/pdf");
chooseFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
if (chooseFileIntent.resolveActivity(controller.getContext().getPackageManager()) != null) {
controller.startActivityForResult(chooseFileIntent, Configuration.Request.Code.Pdf.Pdf);
}
}
So my question why canRead always return false ? How can I read it?
EDIT: The way I get my Path that seems good for me.
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 index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
public static String getPath(Context context, 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;
}
My on activity result :
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Configuration.Request.Code.Pdf.Pdf) {
if (resultCode == RESULT_OK) {
Uri fileUri = data.getData();
if (Session.User != null) {
final Document document = new Document(Session.User);
document.setCategory(Document.Category.CurriculumVitae);
document.setType("PDF");
document.save(getContext(), fileUri, new Uploader.Handler() {
#Override
public void progress(Integer percentage) {
Log.d("=====", String.valueOf(percentage));
if (isLoading()) {
int progressValue = 0;
progressValue += document.uploaded;
documentProgressBar.setProgress(60 * progressValue);
}
}
#Override
public void success() {
continueHeadline.setVisibility(android.view.View.VISIBLE);
continueButton.setVisibility(android.view.View.VISIBLE);
}
#Override
public void error(Error.Code code) {}
});
}
}
}
}
Just maybe you dont have permissions to read the file. The file can be stored with permission that doesnt allow you to read in other applications.
Okey so for everyone who can be in the same situation, just re-check if your application didn't loose permission :/ I'am sad

Categories

Resources