I am trying to get the Path from an image to send it later to a server. The problem is when I try to get it, my code doesn't work (you will see there is an extra }. That is because the code from the OnCreate ends and then I worte the other functions):
enviar.setOnClickListener(new View.OnClickListener() {
String datos="";
//Bundle extras=getIntent().getExtras();
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 0);
//Uri imagen=intent.getData();
//datos=imagen.getPath();
//mostrar.setText(datos);
}
});
}
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) {
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case 0:
if(resultCode == this.RESULT_OK){
try {
final Uri imageUri = imageReturnedIntent.getData();
String path = getRealPathFromURI(imageUri);
mostrar.setText(path);
}
catch (Exception e) {
Log.e("Erroreeeee: ", e.getMessage());
}
}
break;
}
}
You have two problems.
The first one is that startActivityForResult() is not immediate. You do not have any results in the next statement.
So, you are welcome to call startActivityForResult(), as I do in this sample app:
private void get() {
Intent i=
new Intent()
.setType("image/png")
.setAction(Intent.ACTION_GET_CONTENT)
.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(i, REQUEST_GET);
}
Your results are delivered to onActivityResult():
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
if (resultCode==Activity.RESULT_OK) {
Uri image=resultData.getData();
// do something
}
}
Your second problem is that you are thinking that you are picking a file. You are not. You are picking a piece of content, using any activity that the user decides to have handle ACTION_GET_CONTENT. getPath() only has meaning if the scheme of the Uri is file, and that is rather unlikely. There is no reliable means of getting a filesystem path for an arbitrary Uri, for the simple reason that the Uri does not have to point to a file.
Ideally, your "upload to a server" logic can work with an InputStream. In that case, call openInputStream() on a ContentResolver to get an InputStream on the content identified by the Uri. If your "upload to a server" logic only works with files, use that InputStream to copy the content to some temporary file that you control (e.g., in getCacheDir()), then use that temporary file for your upload. Delete the temporary file when you are done with it.
Related
i would like to know the community opinion on the problem of getting image on Android from common sources to use in our App.
I know that there are questions back to 2010's about it on stack overflow, but i found the answers a bit to much boilerplate code for this simple task.
Maybe anyone knows some lightweight library to get image from gallery (or other common sources) so code can stay simple and readable
maybe something like:
Bitmap image;
SomeCoolLib.
.performImageSelect()
.asBitmap()
.listener(new RequestListener<String, Bitmap>() {
#Override
public boolean onException(Exception e) {
e.printStackTrace();
return false;
}
#Override
public boolean onCancel() {
return false;
}
}).into(image);
to let user:
The best way is to use the Android Storage Access Framework (https://developer.android.com/guide/topics/providers/document-provider.html).
For instance, in your activity you can request to the device and type of document (notice the intent.setType method, if you want to filter by document type).
This code will open the android document picker and let user to pick an image:
public class MainActivity extends AppCompatActivity {
private static final int OPEN_DOCUMENT_CODE = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.floatingActionButton).setOnClickListener(view -> {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, OPEN_DOCUMENT_CODE);
});
}
}
Then, just implement the onActivityResult in the very same activity, in order to receive the image selected:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (requestCode == OPEN_DOCUMENT_CODE && resultCode == RESULT_OK) {
if (resultData != null) {
// this is the image selected by the user
Uri imageUri = resultData.getData();
}
}
}
1, Pick a image
If u use this(Old style):
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
Or this(Official recommendation):
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
Those code will open FileManager in Android 8, that's difficult to use.
If u want to open the albums app in user's device and pick a photo, u should use this(I recommendation):
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
All those way before will get an Uri in onActivityResult(int, int, Intent).
2, Handle the Uri
Sometimes we need the image's real path, u should use those code:
#Nullable
public static String getImagePathFromUri(#Nullable Uri aUri) {
String imagePath = null;
if (aUri == null) {
return imagePath;
}
if (DocumentsContract.isDocumentUri(ApplicationContext.get(), aUri)) {
String documentId = DocumentsContract.getDocumentId(aUri);
if ("com.android.providers.media.documents".equals(aUri.getAuthority())) {
String id = documentId.split(":")[1];
String selection = MediaStore.Images.Media._ID + "=" + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
} else if ("com.android.providers.downloads.documents".equals(aUri.getAuthority())) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
Long.valueOf(documentId));
imagePath = getImagePath(contentUri, null);
}
} else if ("content".equalsIgnoreCase(aUri.getScheme())) {
imagePath = MediaUtils.getImagePath(aUri, null);
} else if ("file".equalsIgnoreCase(aUri.getScheme())) {
imagePath = aUri.getPath();
}
return imagePath;
}
private static String getImagePath(Uri aUri, String aSelection) {
String path = null;
Cursor cursor = ApplicationContext.get()
.getContentResolver()
.query(aUri, null, aSelection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}
I'm not able to pick pdf file from internal storage, external storage, recent or google sheet.
Intent intent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
intent.putExtra("CONTENT_TYPE", "application/pdf");
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivityForResult(intent, FILE_SELECT_CODE);
Try this,
private static final int PICK_FILE = 101;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(Intent.createChooser(intent, "Select a File"), PICK_FILE);
} catch (android.content.ActivityNotFoundException ex) {
// Potentially direct the user to the Market with a Dialog
Toast.makeText(this, "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
onActivityResult:
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case PICK_FILE:
if (resultCode == RESULT_OK) {
// Get the Uri of the selected file
Uri uri = data.getData();
// Get the path
String path = getPath(mContext, uri);
Log.d(TAG, "Path: " + path);
if (path != null && path.contains(".pdf")) {
}
}
break;
}
}
getPath:
public String getPath(Context context, Uri uri) {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {"_data"};
Cursor cursor;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
assert cursor != null;
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
cursor.close();
} catch (Exception e) {
// Eat it
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
You can use Intent.ACTION_OPEN_DOCUMENT,
Each document is represented as a content:// URI backed by a DocumentsProvider, which can be opened as a stream with openFileDescriptor(Uri, String), or queried for DocumentsContract.Document metadata.
All selected documents are returned to the calling application with persistable read and write permission grants. If you want to maintain access to the documents across device reboots, you need to explicitly take the persistable permissions using takePersistableUriPermission(Uri, int).
Callers must indicate the acceptable document MIME types through setType(String). For example, to select photos, use image/*. If multiple disjoint MIME types are acceptable, define them in EXTRA_MIME_TYPES and setType(String) to /.
For the more details, please refer this link
Note that above mentioned is only available on API Level 19+.
Have a look at this also, how to pick few type of file via intent in android?
I'm trying to display the path of a saved picture taken by the camera, by calling
`data.getdata`
inside a Toast, but the App crashs. I also tried data.getDataString but it did not solve
any thing.
Code:
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent imageIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "My Images");
imagesFolder.mkdirs();
File image = new File(imagesFolder, "img01");
Uri uriSavedImage = Uri.fromFile(image);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(imageIntent,CAMERA_REQUEST_CODE);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ((requestCode == CAMERA_REQUEST_CODE) && (resultCode == RESULT_OK)) {
Toast.makeText(getApplicationContext(), "Image Saved To: "+data.getData(), Toast.LENGTH_SHORT).show();
}
Camera Intent result woes
looked through this..
have you tried data.getExtras().get(TAG); ?
Get the extras bundle from your intent, there is the resulting data accessible.
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
Don't forget a null check, since I'm in the impression that the tag "data" is not valid on all phones.
edit: Made code more precise, i.e. giving the exact solution here.
Also use, data.getData().toString()
data.getData().toString() should work. But, it won't actually give you the actual path of the image stored. It'll rather give you an URI of that image. You'll need to parse that uri using.
public String getRealPathFromURI(String uriString) {
try {
String[] proj = { MediaStore.Image.Media.DATA};
Log.d("First", proj[0]);
Cursor cursor = managedQuery(Uri.parse(uriString), proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Image.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "Alas!";
}
I am using Native Camera intent to capture video. In Nexus S If i capture a video then whether i cancel or pressed ok always the video file is getting store in default Medi URI path. But I have a requirement to delete the captured video when user clicks ok. I am using
following code to call camera
Intent videoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(videoIntent, CAPTURE_VIDEO);
and following ciode handles cancel button click event
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
if (requestCode == CAPTURE_VIDEO) {if(resultCode == Activity.RESULT_CANCELED)
//pointer comes here successfully. It tells that cancel button is clicked. But I am unabelt to know how to delete the currently cancelled video
}
}
}
Ok, Its some ugly way..
First get the real path of the video from returned URI, like
private String videoPath = "";
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAPTURE_VIDEO)
{
Uri vid = data.getData();
videoPath = getRealPathFromURI(vid);
}
}
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Videos.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Videos.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Now you have a real path of video file then using file operation you can delete it.
File videoFile = new File(videoPath);
videoFile.deleteOnExit();
I doubt if there is available any method to delete it form android database..
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.picture_choice_activity);
Button takePictureButton = (Button)findViewById(R.id.takePictureButton);
takePictureButton.setOnClickListener(new OnClickListener() {
public void onClick(View v){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, IMAGE_CAPTURE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == IMAGE_CAPTURE){
if(resultCode == Activity.RESULT_OK){
// I should get the path here
}else if(resultCode == Activity.RESULT_CANCELED){
}
}
}
In the above code I am trying to get the path of the captured image. I should not use EXTRA_OUTPUT to specify a custom path to save the image. How can I do that?
Use this in ur onActivity result
final Uri contentUri = data.getData();
final String[] proj = { MediaStore.Images.Media.DATA};
final Cursor cursor = managedQuery(contentUri, proj, null, null, null);
final int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();
final String path = cursor.getString(column_index);
Kindly check, http://developer.android.com/guide/topics/media/camera.html#intents
MediaStore.EXTRA_OUTPUT : This setting requires a Uri object specifying a path and file name where you'd like to save the picture. This setting is optional but strongly recommended. If you do not specify this value, the camera application saves the requested picture in the default location with a default name, specified in the returned intent's Intent.getData() field.
so, check the Intent data in onActivityResult()