ImageView not loading via setImageURI on startup on Samsung Galaxy S4 Only
I got a specific issue when running the base code on a Samsung Galaxy S4 (Model: GT-I9500).
I have implemented an image picker via a camera or gallery and could not for a lifetime figure out why the ImageView was empty when called -
imageView.setImageURI(uri);
It wasn't until I ran the same code in the emulator (and then on the Nexus 5) that I found it was a Samsung S4 problem.
A complete sample project can be found on Github and is ready to go
The code I used was taken from this SO post :
In OnCreate :
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose Image Source");
builder.setItems(new CharSequence[]{"Gallery", "Camera"},
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
//Launching the gallery
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, GALLERY);
break;
case 1:
//Specify a camera intent
Intent getCameraImage = new Intent("android.media.action.IMAGE_CAPTURE");
File cameraFolder;
//Check to see if there is an SD card mounted
if (android.os.Environment.getExternalStorageState().equals
(android.os.Environment.MEDIA_MOUNTED))
cameraFolder = new File(android.os.Environment.getExternalStorageDirectory(),
IMAGEFOLDER);
else
cameraFolder = MainActivity.this.getCacheDir();
if (!cameraFolder.exists())
cameraFolder.mkdirs();
//Appending timestamp to "picture_"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
String timeStamp = dateFormat.format(new Date());
String imageFileName = "picture_" + timeStamp + ".jpg";
File photo = new File(Environment.getExternalStorageDirectory(),
IMAGEFOLDER + imageFileName);
getCameraImage.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
//Setting a global variable to be used in the OnActivityResult
imageURI = Uri.fromFile(photo);
startActivityForResult(getCameraImage, CAMERA);
break;
default:
break;
}
}
});
builder.show();
}
});
OnActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case GALLERY:
Uri selectedImage = data.getData();
imageView.setImageURI(selectedImage);
break;
case CAMERA:
imageView.setImageURI(imageURI);
break;
}
}
}
Also occurs when using Picasso
if (resultCode == RESULT_OK) {
switch (requestCode) {
case GALLERY:
Uri selectedImage = data.getData();
Picasso.with(context)
.load(selectedImage)
.into(imageView);
break;
case CAMERA:
Picasso.with(context)
.load(imageURI)
.into(imageView);
break;
}
}
Also occurs when using Bitmap Factory
try {
Bitmap bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(imageURI));
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Results when working on Samsung S4 with 4.2.2
Results when running GenyMotion 2.4.0 running Android 4.4.4
Does anyone know why this is happening?
source to share
So the problem is that the bitmaps of the image are too large for Samsung S4 control.
Unsurprisingly, errors aren't thrown. The correct solution looks like this:
switch (requestCode) {
case GALLERY:
Bitmap bitmap = createScaledBitmap(getImagePath(data, getApplicationContext()), imageView.getWidth(), imageView.getHeight());
imageView.setImageBitmap(bitmap);
break;
case CAMERA:
String path = imageURI.getPath();
Bitmap bitmapCamera = createScaledBitmap(path, imageView.getWidth(), imageView.getHeight());
imageView.setImageBitmap(bitmapCamera);
break;
}
Helper methods:
// Function to get image path from ImagePicker
public static String getImagePath(Intent data, Context context) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
return picturePath;
}
public Bitmap createScaledBitmap(String pathName, int width, int height) {
final BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, opt);
opt.inSampleSize = calculateBmpSampleSize(opt, width, height);
opt.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(pathName, opt);
}
public int calculateBmpSampleSize(BitmapFactory.Options opt, int width, int height) {
final int outHeight = opt.outHeight;
final int outWidth = opt.outWidth;
int sampleSize = 1;
if (outHeight > height || outWidth > width) {
final int heightRatio = Math.round((float) outHeight / (float) height);
final int widthRatio = Math.round((float) outWidth / (float) width);
sampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return sampleSize;
}
source to share
Are they using different apps? 4.4 introduced some new URIs for image selection as they can be local, google, etc.
Try the following: BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
It returns a bitmap that can be used in the image view as
imgView.setImageBitmap(bitmap)
source to share