I want to take photo from fragment but if I use follow codes onActivityResult Intent data return null. I didn't figure out why Intent data return null?
CameraFragement.java
private void takePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getContext(),
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
String imagePath;
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
imagePath = image.getAbsolutePath();
return image;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { // this Intent data return null
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
Intent intent = new Intent(getActivity(), PostActivity.class);
intent.setData(data.getData());
startActivity(intent);
}
}
If I use this follow code instead of above takePictureIntent Intent data return with extras but data.getData() return null. I don't want to return data with extras. I don't want to Bitmap data. I need datas Uri form. I need data.getData(). This follow code used to before but now it's not work. I update my application always with Android SDK. I think this is the reason but what is the solution?
private void takePictureIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
Edit: I tried almost everything but Intent data still return null. I am using follow code with first code example for now. You can use this, it's works fine. If you have a solution for Intent data please don't forget to notice me.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
File file = new File(imagePath);
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(getActivity(), PostActivity.class);
intent.setData(uri);
startActivity(intent);
}
//capture image
public void requestTakePhoto() {
//SettingsManager.sharedInstance().TAKE_PHOTO = true;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
final File photoFile;
try {
photoFile = createImageFile();
}
catch (IOException e) {
// Error occurred while creating the File
Log.e("ChatActivity", "Unable to create photo file", e);
return;
}
// Continue only if the File was successfully created
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(intent, REQ_TAKE_PHOTO);
}
}
//save captured image
private Uri mPhotoLocation;
private File createImageFile() throws IOException {
final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(newDate());
final String imageFileName = timeStamp + "filename";
final File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
final File image = File.createTempFile(imageFileName, ".jpg", storageDir);
mPhotoLocation = Uri.fromFile(image);
return image;
}
//handle result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode) {
case REQ_PICK_IMAGE:
if (resultCode == Activity.RESULT_OK && data.getData() != null) {
Uri uri =data.getData();
//do your work with data
// String filePath = getRealPathFromUri(uri);
//if (filePath != null && !filePath.isEmpty()) {
// Uri fileUri = Uri.parse(filePath);
//sendImageMessage(fileUri);
}
}
break;
case REQ_TAKE_PHOTO:
if (resultCode == Activity.RESULT_OK ) {
//do your work with data
String filePath = getRealPathFromUri(mPhotoLocation);
if (filePath != null && !filePath.isEmpty()) {
Uri fileUri = Uri.parse(filePath);
sendImageMessage(fileUri);
}
mPhotoLocation = null;
}
break;
case REQ_FILE_ATTACHMENT:
if (resultCode == Activity.RESULT_OK && data.getData() != null) {
Uri uri = data.getData();
//String filePath = getRealPathFromUri(uri);
//if (filePath != null && !filePath.isEmpty()) {
//Uri fileUri = Uri.parse(filePath);
//sendFileMessage(fileUri);
}
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
//get realpath
public String getRealPathFromUri(final Uri uri) {
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(getActivity(), 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(getActivity(), 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(getActivity(), contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(getActivity(), uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
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 index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
private boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
the requestcode is lost in the fragment, you need to use activity context:
getActivity().startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
This library will help you to fetch image from Camera or Storage to view in Activity or Fragment.
Its provide very simple methods t do that,
https://github.com/coomar2841/image-chooser-library
Related
private void openCamera(int imageArray){
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/SurveyDA/assets/images","absen_" +
System.currentTimeMillis() + ".jpg"));
Log.d("ddddd : ", String.valueOf(fileUri));
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(cameraIntent, imageArray);
}
when I want open camera, I set the fileuri, and Log success return uri
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
try {
//getting bitmap object from uri
Log.d("ddddd : ", String.valueOf(fileUri));
bitmapImage[requestCode] = MediaStore.Images.Media.getBitmap(this.getContentResolver(), fileUri);
// Initialize a new ByteArrayStream
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Compress the bitmap with JPEG format and quality 50%
bitmapImage[requestCode].compress(Bitmap.CompressFormat.JPEG,60,stream);
byte[] byteArray = stream.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
bitmapImage[requestCode] = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), false);
//displaying selected image to imageview
imageViews[requestCode].setImageBitmap(bitmapImage[requestCode]);
//calling the method uploadBitmap to upload image
} catch (IOException e) {
e.printStackTrace();
}
}else if(resultCode == Activity.RESULT_CANCELED) {
// User Cancelled the actiongetUriForFile
}
}
but in onActivityResult variable fileuri sometimes get null, and sometimes success return uri. And when I try in other phone Android 8.0.0, there no error.
how to fix that?
java.lang.RuntimeException: Unable to resume activity {com.example.surveyonlineda/com.example.surveyonlineda.Activity.AbsenActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=null} to activity {com.example.surveyonlineda/com.example.surveyonlineda.Activity.AbsenActivity}: java.lang.NullPointerException
Refer this Document for your issue you will get best solution
as I see, the fileUri is not returned by onActivityResult. You create it before start your cameraIntent. So in case your activity has been destroyed, the fileUri will null. To prevent it, I think you should use onSaveInstanceState to save the fileUri.
Here is an example to save the string fileUri
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of fileUri from saved state
fileUri = savedInstanceState.getString(FILE_URI);
} else {
// Probably initialize values for a new instance
}
}
#Override protected void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(FILE_URI, fileUri);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
You can try it. it worked for me
Step 1. Create class GetPathFromUri.class
import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.*;
public class GetPathFromUri {
#SuppressLint("NewApi")
public static String getPath(final Context context, final Uri uri) {
#SuppressLint("ObsoleteSdkInt") 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];
}
if ("raw".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
if ("5D68-9217".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
if (id != null && id.startsWith("raw:")) {
return id.substring(4);
}
String[] contentUriPrefixesToTry = new String[]{
"content://downloads/public_downloads",
"content://downloads/my_downloads"
};
for (String contentUriPrefix : contentUriPrefixesToTry) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
try {
String path = getDataColumn(context, contentUri, null, null);
if (path != null) {
return path;
}
} catch (Exception e) {}
}
// path could not be retrieved using ContentResolver, therefore copy file to accessible cache using streams
String fileName = getFileName(context, uri);
File cacheDir = getDocumentCacheDir(context);
File file = generateFileName(fileName, cacheDir);
String destinationPath = null;
if (file != null) {
destinationPath = file.getAbsolutePath();
saveFileFromUri(context, uri, destinationPath);
}
return destinationPath;
}
// 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 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.
*/
private static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
final String column = "_data";
final String[] projection = {column};
try (Cursor 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);
}
}
return null;
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
private 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.
*/
private 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.
*/
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static String getFileName(#NonNull Context context, Uri uri) {
String mimeType = context.getContentResolver().getType(uri);
String filename = null;
if (mimeType == null && context != null) {
String path = getPath(context, uri);
if (path == null) {
filename = getName(uri.toString());
} else {
File file = new File(path);
filename = file.getName();
}
} else {
Cursor returnCursor = context.getContentResolver().query(uri, null,
null, null, null);
if (returnCursor != null) {
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
returnCursor.moveToFirst();
filename = returnCursor.getString(nameIndex);
returnCursor.close();
}
}
return filename;
}
public static String getName(String filename) {
if (filename == null) {
return null;
}
int index = filename.lastIndexOf('/');
return filename.substring(index + 1);
}
public static File getDocumentCacheDir(#NonNull Context context) {
File dir = new File(context.getCacheDir(), DOCUMENTS_DIR);
if (!dir.exists()) {
dir.mkdirs();
}
logDir(context.getCacheDir());
logDir(dir);
return dir;
}
public static final String DOCUMENTS_DIR = "documents";
static final String TAG = "FileUtils";
private static final boolean DEBUG = false; // Set to true to enable logging
private static void logDir(File dir) {
if (!DEBUG) return;
Log.d(TAG, "Dir=" + dir);
File[] files = dir.listFiles();
for (File file : files) {
Log.d(TAG, "File=" + file.getPath());
}
}
#Nullable
public static File generateFileName(#Nullable String name, File directory) {
if (name == null) {
return null;
}
File file = new File(directory, name);
if (file.exists()) {
String fileName = name;
String extension = "";
int dotIndex = name.lastIndexOf('.');
if (dotIndex > 0) {
fileName = name.substring(0, dotIndex);
extension = name.substring(dotIndex);
}
int index = 0;
while (file.exists()) {
index++;
name = fileName + '(' + index + ')' + extension;
file = new File(directory, name);
}
}
try {
if (!file.createNewFile()) {
return null;
}
} catch (IOException e) {
Log.w(TAG, e);
return null;
}
logDir(directory);
return file;
}
private static void saveFileFromUri(Context context, Uri uri, String destinationPath) {
InputStream is = null;
BufferedOutputStream bos = null;
try {
is = context.getContentResolver().openInputStream(uri);
bos = new BufferedOutputStream(new FileOutputStream(destinationPath, false));
byte[] buf = new byte[1024];
is.read(buf);
do {
bos.write(buf);
} while (is.read(buf) != -1);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) is.close();
if (bos != null) bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Step 2:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
try {
String path = GetPathFromUri.getPath(this, data.getData())
Glide.with(this).load(path).into(imageView);
// Glide is library https://github.com/bumptech/glide
} catch (IOException e) {
e.printStackTrace();
}
}else if(resultCode == Activity.RESULT_CANCELED) {
// User Cancelled the actiongetUriForFile
}
}
My app has functionality for allowing the user to either select a photo or video from their current library, or to take a new one, and then attach to an email. It seems to be working on the majority of devices and Android versions. However, I'm seeing some crashes intermittently for some device setups when getting the uri to the image or video to attach to the email. An example crash is: Fatal Exception: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=67425, result=-1, data=Intent { dat=content://com.google.android.apps.docs.storage/document/acc=1;doc=3 flg=0x1 }} to activity: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference. This happens on the "File file = new File(imagePath);" line in the email() method below. Are there changes I can make to my code to allow for a more universal solution to this? My minSdkVersion is 16, and my targetSdkVersion is 23.
Below is my code for the implementation:
private enum Type {
PHOTO,
VIDEO
}
private enum Source {
LIBRARY,
CAMERA
}
private void select(Type type) {
if(selectedSource == Source.LIBRARY) {
// choose from library
Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
if (type == Type.PHOTO) {
getIntent.setType("image/*");
} else {
getIntent.setType("video/*");
}
Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
if (type == Type.PHOTO) {
pickIntent.setType("image/*");
} else {
pickIntent.setType("video/*");
}
Intent chooserIntent = Intent.createChooser(getIntent, "Select Photo/Video");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent});
startActivityForResult(chooserIntent, CHOOSE_IMAGE_VIDEO_ACTIVITY_REQUEST_CODE);
} else if(selectedSource == Source.CAMERA) {
// take photo/video from camera
// check for camera permission
if ( ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
}
if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//Toast.makeText(getActivity(), "You need to allow camera access", Toast.LENGTH_LONG).show();
return;
} else {
if (getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
if ( ContextCompat.checkSelfPermission(getActivity(), READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, REQUEST_EXTERNAL_STORAGE);
}
if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(getActivity(), READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//Toast.makeText(getActivity(), "You need to allow external storage access", Toast.LENGTH_LONG).show();
return;
} else {
if (selectedType == Type.PHOTO) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
File photo = null;
try {
// place where to store camera taken picture
photo = this.createTemporaryFile("photo", ".jpg");
photo.delete();
} catch (Exception e) {
//Log.v(TAG, "Can't create file to take picture!");
Toast.makeText(getActivity(), "Please check SD card! Image shot is impossible!", Toast.LENGTH_LONG).show();
}
mImageUri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
startActivityForResult(intent, TAKE_IMAGE_ACTIVITY_REQUEST_CODE);
} else {
Toast.makeText(getActivity(), "Unable to access the camera", Toast.LENGTH_LONG).show();
}
} else if (selectedType == Type.VIDEO) {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
File video = null;
try {
// place where to store camera taken video
video = this.createTemporaryFile("video", ".mp4");
video.delete();
} catch (Exception e) {
//Log.v(TAG, "Can't create file to take picture!");
Toast.makeText(getActivity(), "Please check SD card! Video is impossible!", Toast.LENGTH_LONG).show();
}
mImageUri = Uri.fromFile(video);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
startActivityForResult(intent, TAKE_VIDEO_ACTIVITY_REQUEST_CODE);
} else {
Toast.makeText(getActivity(), "Unable to access the camera", Toast.LENGTH_LONG).show();
}
}
}
} else {
Toast.makeText(getActivity(), "No camera available", Toast.LENGTH_LONG).show();
}
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CAMERA: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("REQUEST CAMERA RESULT");
select(selectedType);
} else {
//Permission denied
Toast.makeText(getActivity(), "You need to allow camera access", Toast.LENGTH_LONG).show();
}
return;
}
case REQUEST_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("REQUEST EXTERNAL STORAGE RESULT");
select(selectedType);
} else {
//Permission denied
Toast.makeText(getActivity(), "You need to allow external storage access", Toast.LENGTH_LONG).show();
}
return;
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CHOOSE_IMAGE_VIDEO_ACTIVITY_REQUEST_CODE) {
// from image picker
if (resultCode == Activity.RESULT_OK) {
if(data != null) {
//InputStream inputStream = getActivity().getContentResolver().openInputStream(data.getData());
mImageUri = data.getData();
imagePath = getPath(getActivity(), mImageUri);
email();
}
}
} else if(requestCode == TAKE_IMAGE_ACTIVITY_REQUEST_CODE || requestCode == TAKE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
grabImageOrVideoTaken();
}
}
}
private void grabImageOrVideoTaken() {
getActivity().getContentResolver().notifyChange(mImageUri, null);
imagePath = getPath(getActivity(), mImageUri);
email();
}
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 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 column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private void email() {
String mediaType = "photo";
if(selectedType == Type.VIDEO) {
mediaType = "video";
}
String email = "test#test.com";
Intent intent = new Intent(Intent.ACTION_SEND, Uri.fromParts("mailto", email, null));
intent.putExtra(Intent.EXTRA_SUBJECT, getResources().getString(R.string.app_name) + ": Photo/Video Submission");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{email});
File file = new File(imagePath);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (selectedType == Type.PHOTO) {
intent.setType("image/jpeg");
} else {
intent.setType("video/3gp");
}
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + file.getAbsolutePath()));
startActivity(Intent.createChooser(intent, "Submit Photo/Video"));
}
Are there changes I can make to my code to allow for a more universal solution to this?
Sure. Get rid of getPath().
It seems to be working on the majority of devices and Android versions.
Not really.
Use the Uri properly. It is not a file. Even in the few cases where it does point to a file, you may not have access to that file via the filesystem.
You say that you are using this for an email attachment. If that is ACTION_SEND with a EXTRA_STREAM extra, use the Uri that you were given. Add FLAG_GRANT_READ_URI_PERMISSION on the ACTION_SEND Intent, so that the read permissions that you were granted get sent along to the ACTION_SEND handler.
If you are using something else for the email, use a ContentResolver and openInputStream() to get an InputStream on the file or content Uri. Then, either pass that stream to the other code, or use that stream to make your own local file copy (e.g., in getCacheDir()), and then use that local copy, deleting it when you do not need it.
I am trying to set an image to an imageview that a user selects from their gallery. However all the images seem to load to my imageview except when I select an image from the camera folder. It doesn't put the image into my imageview. Refer to the following image http://i.stack.imgur.com/h6QGG.jpg
Call of intent
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.INTERNAL_CONTENT_URI);
// Start the Intent
Log.d(TAG,"STARTING ACTIVITY FOR RESULT");
startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE);
OnActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
Log.d(TAG,"IN ON ACTIVIY RESULT");
super.onActivityResult(requestCode, resultCode, data);
try {
Log.d(TAG, "IN INTERESTS ON ACTIVITY RESULT");
if (requestCode == RESULT_LOAD_IMAGE && resultCode == Activity.RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContext().getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
File file = new File(picturePath);
bmOptions.inJustDecodeBounds = true;
Bitmap original = BitmapFactory.decodeFile(picturePath);
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
Bitmap newBm = Bitmap.createScaledBitmap(original, 900, 1280, true);
newBm.compress(Bitmap.CompressFormat.JPEG, 90, ostream);
ostream.close();
BitmapFactory.decodeFile(picturePath, bmOptions);
iconpic.setImageBitmap(newBm);
Toast.makeText(getContext(), picturePath, Toast.LENGTH_SHORT)
.show();
cursor.close();
SharedPreferences appPrefs = getContext().getSharedPreferences("com.example.gcmclient_preferences", Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = appPrefs.edit();
prefsEditor.putString("iconPath", picturePath);
prefsEditor.commit();
// String picturePath contains the path of selected Image
}
}
catch (Exception e){
e.printStackTrace();
}
}
Hope this will work.
Uri imageUri;
File file;
public int CAMERA_INTENT_CALLED = 100;
public int GALLERY_INTENT_CALLED = 101;
public int GALLERY_KITKAT_INTENT_CALLED = 102;
if (Build.VERSION.SDK_INT < 19) {
Intent intent = new Intent();
intent.setType("image/jpeg");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select image to promote"),
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);
}
onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
Uri originalUri = null;
if (requestCode == GALLERY_INTENT_CALLED) {
if (data.getData() != null) {
originalUri = data.getData();
String path = getRealPathFromURI(originalUri);
setImageBitmap(path);
originalUri = null;
}
} else if (requestCode == GALLERY_KITKAT_INTENT_CALLED) {
if (data.getData() != null) {
originalUri = data.getData();
String path = getPath(this, originalUri);
setImageBitmap(path);
originalUri = null;
}
} else if (requestCode == CAMERA_INTENT_CALLED) {
Uri selectedImage = imageUri;
try {
if (selectedImage != null) {
getContentResolver().notifyChange(selectedImage, null);
String path = getRealPathFromURI(selectedImage);
Log.e("Imagepath Camera", path);
setImageBitmap(path);
imageUri = null;
}
} catch (Exception e) {
Log.e("Camera", e.toString());
}
}
}
API <19 and above GalleryImage selected
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);
}
}
KITKAT and above GalleryImage selected
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;
}
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 isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri
.getAuthority());
}
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());
}
Goal: to be able to attach a file of any type to a <input type="file" /> in a webview in Android 4.1+. (Android 5+ is fine)
I set openFileChooser as I saw fit based on few examples I have found. It works on 4.1 but not on 4.4.4 where the files attached do not have their filename correctly set.
Instead is set as filename the last path of the intent.mData return to onActivityResult, .e.g, for a mData value of content://com.android.providers.downloads.documents/document/2, the filename will be 2―without extension of course―while the name should be image.png.
What can I do to fix it? Would there be any problem in my code?
I do my testing on an emulator: Galaxy Nexus, API 19, target: Default
See code below.
webView.setWebChromeClient(new WebChromeClient() {
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
if (UseWebViewActivity.this.valueCallback != null) {
UseWebViewActivity.this.valueCallback.onReceiveValue(null);
}
UseWebViewActivity.this.valueCallback = valueCallback;
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("*/*");
startActivityForResult(Intent.createChooser(contentSelectionIntent,
getString(R.string.file_chooser_title)), INPUT_FILE_REQUEST_CODE);
}
});
// ...
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == INPUT_FILE_REQUEST_CODE && valueCallback != null) {
Uri result = null;
if (resultCode == Activity.RESULT_OK) {
result = intent.getData();
}
valueCallback.onReceiveValue(result);
valueCallback = null;
}
}
The problem is in the onActivityResult() method for KitKat which returns the URI. You need to get the realpath of the imagefile.
Notice how i get the Real Path of the IMG by calling :
KitkatPath = Uri.parse("file://"+getPath(MobilestyxAppActivity.this, result)); in the onActivityResult().
You must add the string "file://" for it to work.
PS : I have gathered the code from various sources and modified it.
Look at my code below which works for Kitkat & Lolipop and other low versions of Android.
/** CODE FOR FILE UPLOAD*/
private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
Uri KitkatPath ;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
}
else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
System.out.println("In KitKat Condition");
if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
System.out.println("In != Null");
super.onActivityResult(requestCode, resultCode, data);
return;
}
if (requestCode == FILECHOOSER_RESULTCODE) {
System.out.println("requestCode == FileChooser ResultCode");
if (null == this.mUploadMessage) {
System.out.println("In null == this.mUploadMessage");
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
//newcode
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
KitkatPath = Uri.parse("file://"+getPath(MobilestyxAppActivity.this, result));
System.out.println("KitkatPath== "+KitkatPath);
System.out.println("result = "+result);
}
} catch (Exception e) {
// Toast.makeText(getApplicationContext(), "activity :" + e, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
// mUploadMessage.onReceiveValue(result);
mUploadMessage.onReceiveValue(KitkatPath);
System.out.println("mUploadMessage = "+mUploadMessage);
mUploadMessage = null;
}
}
return;
}
/** CODE FOR FILE UPLOAD*/
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());
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date(heightDiff));
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
& now in the WebViewChromeClient ---
browser.setWebChromeClient(new WebChromeClient()
{
// For Android 5.0
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
System.out.println("in 5.0");
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
// Log.e(TAG, "Unable to create Image File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
// openFileChooser for Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
System.out.println("in 3.0+");
mUploadMessage = uploadMsg;
// Create AndroidExampleFolder at sdcard
// Create AndroidExampleFolder at sdcard
File imageStorageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "AndroidExampleFolder");
if (!imageStorageDir.exists()) {
// Create AndroidExampleFolder at sdcard
imageStorageDir.mkdirs();
}
// Create camera captured image file path and name
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);
//
// Camera capture image intent
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
// Create file chooser intent
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
// Set camera intent to file chooser
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS
, new Parcelable[] { captureIntent });
// On select image call onActivityResult method of activity
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
// openFileChooser for Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
System.out.println("in <3.0");
openFileChooser(uploadMsg, "");
}
// openFileChooser for other Android versions
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType, String capture) {
System.out.println("in OTHER");
openFileChooser(uploadMsg, acceptType);
}
Try using aFileChooser to avoid complications with API Level compatibilities (the library has it handled):
aFileChooser is an Android Library Project that simplifies the process
of presenting a file chooser on Android 2.1+.
Intents provide the ability to hook into third-party app components
for content selection. This works well for media files, but if you
want users to be able to select any file, they must have an existing
"file explorer" app installed. Because many Android devices don't have
stock File Explorers, the developer must often instruct the user to
install one, or build one, themselves. aFileChooser solves this issue.
Features:
Full file explorer
Simplify GET_CONTENT Intent creation
Hooks into Storage Access Framework
Determine MIME data types
Follows Android conventions (Fragments, Loaders, Intents, etc.)
Supports API 7+
Check the readme.md on The repo's GitHub page for setup and usage instructions.
Android 4.1 and 4.4 have different workings here since Storage Access Framework was introduced in Android 4.4 (API level 19). To retrieve the file name, you can try something like this:
Uri uri = intent.getData();
File imageFile = new File(uri);
if(imageFile.exists()){
String name = imageFile.getName();
}
I want to select gallery intent in fragment.when user choose option to select image from gallery then gallery opens and immediately onActivityResult of fragment is being called.and when user pick image then onActivityResult() is not called.So i am not able to select image from gallery.
Belo is my code to open gallery -
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("video/, images/");
startActivityForResult(intent, 2);
and here is my onActivityResult-
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult"); // not printed
Toast.makeText(mContext, "aaaa"+requestCode, Toast.LENGTH_SHORT).show();
}
What the problem in my code.
Thanks in advance.
Use this to open the android image chooser:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
} else {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
}
and for onActivityResult use this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Cursor cursor = null;
if (resultCode != Activity.RESULT_OK)
return;
if (data == null)
return;
Uri originalUri = null;
if (requestCode == GALLERY_INTENT_CALLED && data != null) {
originalUri = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
cursor = getActivity().getContentResolver().query(originalUri,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();
Log.d("path of uri", filePath);
} else if (requestCode == GALLERY_KITKAT_INTENT_CALLED && data != null) {
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.
getActivity().getContentResolver().takePersistableUriPermission(
originalUri, takeFlags);
Log.d("Uri: ", originalUri.toString());
filePath = getPath(getActivity(), originalUri);
Log.d("filepath", filePath);
}
}
#SuppressLint("NewApi")
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 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 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.
*/
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());
}
# I am showing you an example in which i used an ImageView to show image result .There are two methods used 1.From camera and 2.From SD card #
public void camera(View view) {
Log.i("SonaSys", "startCameraActivity()");
File file = new File(path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
public void gallery(View view) {
String path = Environment.getExternalStorageDirectory()
+ "/images/imagename.jpg";
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK
&& null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
bitmap = BitmapFactory.decodeFile(picturePath);
image.setImageBitmap(bitmap);
if (bitmap != null) {
ImageView rotate = (ImageView) findViewById(R.id.rotate);
rotate.setVisibility(View.VISIBLE);
}
} else {
Log.i("SonaSys", "resultCode: " + resultCode);
switch (resultCode) {
case 0:
Log.i("SonaSys", "User cancelled");
break;
case -1:
onPhotoTaken();
break;
}
}
}
protected void onPhotoTaken() {
// Log message
Log.i("SonaSys", "onPhotoTaken");
taken = true;
imgCapFlag = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(path, options);
image.setImageBitmap(bitmap);
}
use this code for choose image,
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select image"),
PICK_IMAGE);
Since Activity gets the result of onActivityResult(), you will need to override the activity's onActivityResult() and call super.onActivityResult() to propagate to the respective fragment for unhandled results codes or for all.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
To help others who are struggling with this bug, i would suggest the following:
1. The launch mode of your fragment activity
if launch mode of your activity is the "singleInstance"
in that case the onActivityResult will be called automatically once you leave the activity and goes to activity where you are supposed to pick the image. This is true for the camera intent also. Try to change your launch mode to "singleTop" or anything as an alternative to the launch mode that you have right now. This way what will happen that your activityOnResult will be called only when you finish up picking the image. Also the result will be return to the fragment only from where you have called the startActivityForResult. I will suggest you to consider to implement the dialogueFragment for giving option to user to pick the image or click image
2. The how have you called the startActivityForResult
Its another interesting thing, if you call your startActivityResult from fragment using the local context of the fragment the result will be returned back to the fragment but if you call it using the fragment activity context like getActivity().startActivityResult the result will be passed back to the parent fragment activity. So it depends upon you where you want to handle it.
Other important thing, do call the
super.onActivityResult(requestCode, resultCode, data);
in your method where you are getting the result.
Other than these try following the suggestion that other has provided for picking the image using the proper intent.