I've searched on stackoverflow but never found a solution
Here is my situation:
I have a button which start an intent to pick an image
How can I resize proportionally (to keep the aspect ration) and display it on another activity (in imageview)?
I also want to save this resized image to user storage. How can I do that?
Thanks!
Here is my code
MainActivity.java
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, getString(R.string.completeaction)),
PICK_FROM_FILE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap selectedphoto = null;
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RequestExternal && 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 filePath = cursor.getString(columnIndex);
selectedphoto = BitmapFactory.decodeFile(filePath);
cursor.close();
Intent intent = new Intent(MainActivity.this,PhotoResized.class);
intent.putExtra("data", selectedphoto);
startActivity(intent);
}
}
PhotoResized.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photoresized);
img = (ImageView) findViewById(R.id.imageView1);
}
For resizing the image use sampling technique provided by dev.android here
Use Lrucache for storing images. Use technique shown here
I found a program on this page to fetch image from sd card and show it on an imageView. I am getting issue at this line -
bitmap = BitmapFactory.decodeFile(picturePath);
I am getting correct value of picturePath variable but in the above line it is setting bitmap value as null. I had visited various threads and almost everyone is using this same line. I am not getting what is wrong with my code
Here is my complete code -
private Button upload;
ImageView imgView;
EditText caption;
Bitmap bitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgView = (ImageView) findViewById(R.id.imageView);
upload = (Button) findViewById(R.id.Upload);
caption = (EditText) findViewById(R.id.caption);
imgView.setImageResource(R.drawable.ic_menu_gallery);
upload.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 2);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2 && 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);
imgView.setImageBitmap(bitmap);
caption.setText("Hello");
}
}
Try putting this in your AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
After that, make sure you have the permission enabled in the App Info screen on your device.
I have created an activity that upon button click user are able to upload a picture from their device gallery, which would get cast to an imageview. The problem is that it is only able to retrieve image from device gallery, not from phone camera gallery, or from phone google drive folder. I would want that its able to upload any picture from their phone, regardless of the source.
Below is the code:
Button buttonLoadImage = (Button) findViewById(R.id.btnPictureSelect);
buttonLoadImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
});
}
#Override
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();
ImageView imageView = (ImageView) findViewById(R.id.profilePicturePreview);
imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
}
}
private byte[] readInFile(String path) throws IOException {
// TODO Auto-generated method stub
byte[] data = null;
File file = new File(path);
InputStream input_stream = new BufferedInputStream(new FileInputStream(
file));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
data = new byte[16384]; // 16K
int bytes_read;
while ((bytes_read = input_stream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, bytes_read);
}
input_stream.close();
return buffer.toByteArray();
}
Any help would be greatly appreciated.
Update:
private static final int READ_REQUEST_CODE = 42;
in the code
Button buttonLoadImage = (Button) findViewById(R.id.btnPictureSelect);
buttonLoadImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent imageIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
imageIntent.addCategory(Intent.CATEGORY_OPENABLE);
imageIntent.setType("image/*");
imageIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(imageIntent , READ_REQUEST_CODE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (data != null) {
uri = data.getData();
Log.i(TAG, "Uri: " + uri.toString());
showImage(uri);
}
}
}
private void showImage(Uri uri) {
// TODO Auto-generated method stub
ImageView imageView = (ImageView) findViewById(R.id.profilePicturePreview);
imageView.setImageUri(Uri.parse(new File("path_to_your_image".toString()));
}
error:
The method parse(String) in the type Uri is not applicable for the arguments (File)
in line
imageView.setImageUri(Uri.parse(new File("path_to_your_image".toString()));
Update 2:
private void showImage(Uri uri) {
// TODO Auto-generated method stub
ImageView imageView = (ImageView) findViewById(R.id.profilePicturePreview);
imageView.setImageUri(Uri.fromFile(new File("/sdcard/myimage.jpg")));
error:
The method setImageUri(Uri) is undefined for the type ImageView
It would be better to use Intent to search the image type files available in your device.
Intent imageIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
imageIntent.addCategory(Intent.CATEGORY_OPENABLE);
imageIntent.setType("image/*");
imageIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(imageIntent , READ_REQUEST_CODE); // set READ_REQUEST_CODE to 42 in your class
Now, process your results in the onActivityResult() method.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (data != null) {
uri = data.getData();
Log.i(TAG, "Uri: " + uri.toString());
showImage(uri);
}
}
I'm trying to launch an intent to pick a image from the camera or the android's gallery. I checked THIS post and currently my code is near to work:
private Intent getPickIntent() {
final List<Intent> intents = new ArrayList<Intent>();
if (allowCamera) {
setCameraIntents(intents, cameraOutputUri);
}
if (allowGallery) {
intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
}
if (intents.isEmpty()) return null;
Intent result = Intent.createChooser(intents.remove(0), null);
if (!intents.isEmpty()) {
result.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[] {}));
}
return result;
}
private void setCameraIntents(List<Intent> cameraIntents, Uri output) {
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = context.getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
cameraIntents.add(intent);
}
}
When I set allowCamera=true it works correctly.
When I set allowGallery=true it shows the following chooser:
But if I set allowCamera=true and allowGallery =true the chooser shown is:
And if you select Android System then the first chooser is shown.
I'd like the chooser to be something like:
How can I "expand" the Android System option?
Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT, null);
galleryintent.setType("image/*");
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, galleryintent);
chooser.putExtra(Intent.EXTRA_TITLE, "Select from:");
Intent[] intentArray = { cameraIntent };
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooser, REQUEST_PIC);
In your linked post you can find the solution. The difference to your code is how the gallery intent is created:
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
Not with ACTION_PICK how you did but with ACTION_GET_CONTENT. It seems that if a single ACTION_PICK is in the list (a "container intent"), the system traverses it to display the content of the pick, but as soon you include the camera intent it can't traverse anymore (since there is one direct intent and one container intent).
In the comment of this answer you find the difference between ACTION_PICK and ACTION_GET_CONTENT.
There are some solutions available which recommend to use a custom dialog. But this dialog will not have the standards icons (see develper docs here). So I recommend to stay at your solution and just fix the hierarchie issue.
## Intent to choose between Camera and Gallery Heading and can crop image after capturing from camera ##
public void captureImageCameraOrGallery() {
final CharSequence[] options = { "Take photo", "Choose from library",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(
Post_activity.this);
builder.setTitle("Select");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
if (options[which].equals("Take photo")) {
try {
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, TAKE_PICTURE);
} catch (ActivityNotFoundException ex) {
String errorMessage = "Whoops - your device doesn't support capturing images!";
}
} else if (options[which].equals("Choose from library")) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, ACTIVITY_SELECT_IMAGE);
} else if (options[which].equals("Cancel")) {
dialog.dismiss();
}
}
});
dialog = builder.create();
dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
dialog.show();
}
public void onActivityResult(int requestcode, int resultcode, Intent intent) {
super.onActivityResult(requestcode, resultcode, intent);
if (resultcode == RESULT_OK) {
if (requestcode == TAKE_PICTURE) {
picUri = intent.getData();
startCropImage();
} else if (requestcode == PIC_CROP) {
Bitmap photo = (Bitmap) intent.getExtras().get("data");
Drawable drawable = new BitmapDrawable(photo);
backGroundImageLinearLayout.setBackgroundDrawable(drawable);
} else if (requestcode == ACTIVITY_SELECT_IMAGE) {
Uri selectedImage = intent.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = getContentResolver().query(selectedImage, filePath,
null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
Drawable drawable = new BitmapDrawable(thumbnail);
backGroundImageLinearLayout.setBackgroundDrawable(drawable);
}
}
}
private void startCropImage() {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
// indicate output X and Y
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, PIC_CROP);
} catch (ActivityNotFoundException anfe) {
// display an error message
String errorMessage = "Whoops - your device doesn't support the crop action!";
Toast toast = Toast
.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
You may need to create a custom dialog for this:
Here is the code for the method which is to be called when the user clicks on a particular button:
private void ChooseGallerOrCamera() {
final CharSequence[] items = { "Take Photo", "Choose from Gallery",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Take Photo")) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment
.getExternalStorageDirectory(), "MyImage.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, REQUEST_CAMERA);
} else if (items[item].equals("Choose from Gallery")) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(
Intent.createChooser(intent, "Select File"),
SELECT_FILE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
And the code for handling onActivityResult():
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Bitmap mBitmap;
if (requestCode == REQUEST_CAMERA) {
File camFile = new File(Environment.getExternalStorageDirectory()
.toString());
for (File temp : camFile.listFiles()) {
if (temp.getName().equals("MyImage.jpg")) {
camFile = temp;
break;
}
}
try {
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
mBitmap = BitmapFactory.decodeFile(camFile.getAbsolutePath(),
btmapOptions);
//Here you have the bitmap of the image from camera
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == SELECT_FILE) {
Uri selectedImageUri = data.getData();
String tempPath = getPath(selectedImageUri, MyActivity.this);
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
mBitmap = BitmapFactory.decodeFile(tempPath, btmapOptions);
//Here you have the bitmap of the image from gallery
}
}
}
public String getPath(Uri uri, Activity activity) {
String[] projection = { MediaColumns.DATA };
Cursor cursor = activity
.managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
EDIT:
Try Using this:
private void letUserTakeUserTakePicture() {
Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(getTempFile(getActivity())));
String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra
(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{takePhotoIntent});
startActivityForResult(chooserIntent, Values.REQ_CODE_TAKEPICTURE);
}
Your code already very achieve the goal. Just exchange the gallery and camera add order.
if (allowGallery) {
intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
}
if (allowCamera) {
setCameraIntents(intents, cameraOutputUri);
}
Here's my test result. Appearance difference since my OS is Android Nougat(7.0)
The first screenshot is in your order, the second is after exchange. Just like you said, in first situation, click the system logo will show gallery items.
Intent for showing camera and video files in activity chooser:
Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT, null);
galleryintent.setType("video/*");
Intent cameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, galleryintent);
chooser.putExtra(Intent.EXTRA_TITLE, "Select from:");
Intent[] intentArray = { cameraIntent };
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooser, REQUEST_VIDEO_CAPTURE);
I'm trying to save the path of an image imported from the gallery using this method:
case R.id.media:
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
return true;
Here is the on activity result method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
final 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();
mImage = picturePath;
ImageView imageView = (ImageView) findViewById(R.id.note_image);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
imageView.setClickable(true);
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent viewImageIntent = new Intent(android.content.Intent.ACTION_VIEW, selectedImage);
startActivity(viewImageIntent);
}
});
}
}
And here is the populate field method:
mImage =(note.getString(
note.getColumnIndexOrThrow(NotesDbAdapter.KEY_IMAGE)));
But this is not working, the path doesnt get saved and when i close the activity and start the activity again, the image is gone. How can i fix this?