Android Universal Image Loader fails to display image by uri - android

So my application works something like that:
In some point I switch to an activity that takes a photo, gets the created bitmap's url and passes it on to my main activity:
public class CameraActivity extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Uri imageUri = data.getData();
Intent mainmenu = new Intent(this, MainActivity.class);
mainmenu.putExtra("imageUri", imageUri.toString());
setResult(Activity.RESULT_OK, mainmenu);
finish();
}
}
Then in my main activity I update my sqlite db with the new path
switch(requestCode)
{
case CAMERA_RESULT:
String imageUri = data.getStringExtra("imageUri");
Task imageTask= tasks.get(taskImageSet);
db.deleteTask(imageTask);
adapter.remove(imageTask);
imageTask.setImagePath(imageUri);
db.addTask(imageTask);
adapter.add(imageTask);
adapter.notifyDataSetChanged();
break;
(I know it's kinda silly doing it like this but I just try to make the image loader thing work...)
Then when the user clicks on something it switches to another activity which supposed to show the result:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_showimage);
// UNIVERSAL IMAGE LOADER SETUP
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheOnDisc(true).cacheInMemory(true)
.imageScaleType(ImageScaleType.EXACTLY)
.displayer(new FadeInBitmapDisplayer(300)).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.memoryCache(new WeakMemoryCache())
.discCacheSize(100 * 1024 * 1024).build();
ImageLoader.getInstance().init(config);
String url = getIntent().getStringExtra("url");
Toast.makeText(this, url, Toast.LENGTH_LONG).show();
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(R.drawable.at_save)
.showImageOnFail(R.drawable.cv_fail)
.showImageOnLoading(R.drawable.cv_loading).build();
ImageView imageView = (ImageView) findViewById(R.id.ivTaskImage);
imageLoader.displayImage(url, imageView, options);
}
But it doesn't and instead it show the cv_fail image.
Important to mention that I printed the path when the bitmap generated and before showing the image and it was the same, looking something like:
content://media/external/images/media/84443
I have the following permission in my manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Any help would be very much appreciated!

Instead of using URI, you also can use file path of the image that you can retrieve from URI. The reason why I prefer to use file because you can check if the image is really exist in your storage or not. You can check all the acceptables URIs here : Universal Image Loader
Uri selectedImageUri = Uri.parse(imageUri);
String photoPath = getRealPathFromURI(selectedImageUri);
This is the method to get photo path
private String getRealPathFromURI(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
#SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Now you're getting result like this file:///mnt/sdcard/image.png. Then you can display the image as usual.
imageLoader.displayImage(photoPath, imageView, options);
//make sure your photoPath contain this prefix: 'file:/'

Related

Image uploaded from gallery doesn't show in ImageView

I'm aware that there are several other questions on this topic but none of the solutions worked for me. I have added permissions in my manifest. I am able to open the gallery pick a photo and return to the application but the imageView does not change. The app is doing some processing and I am not getting any errors. I have tried also tried to scale the image before inserting it into my imageview with no luck.
Here is my code:
public class UserDetailsFragment extends Fragment {
private Context context;
private ImageView imageView;
private Bitmap uploadedImage;
public static final int RESULT_IMAGE = 0;
public UserDetailsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getActivity();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_user_details, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
imageView = (ImageView) getView().findViewById(R.id.profile_picture);
imageView.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, RESULT_IMAGE);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
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 filePath = cursor.getString(columnIndex);
cursor.close();
try {
InputStream in = new URL(filePath).openStream();
uploadedImage = BitmapFactory.decodeStream(in);
imageView.setImageBitmap(uploadedImage);
}catch (Exception ex){
}
}
}
}
Here is my imageView:
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="-160dp"
android:layout_gravity="center"
android:layout_below="#+id/imageView"
android:src="#drawable/user_details_icon"
android:id="#+id/profile_picture" />
EDIT
I tried to use Picasso instead but still no luck:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
Picasso.with(context)
.load(MediaStore.Images.Media.DATA)
.resize(10, 10)
.centerCrop()
.into(imageView);
}
In Your previous code, the problem is in the following lines:
InputStream in = new URL(filePath).openStream();
uploadedImage = BitmapFactory.decodeStream(in);
these lines are creating exception because that is responsible for downloading image from server and covert it into Bitmap. As you are picking image from local storage, the path of image is something like following
/storage/emulated/0/DCIM/Camera/IMG_20170209_183830841.jpg
when you pass it in new URL() as a parameter, it creates following exception
java.net.MalformedURLException: Protocol not found
In your case first of all you need to add READ_EXTERNAL_STORAGE permission in your manifest file and in onActivityResult(), you have to replace
InputStream in = new URL(filePath).openStream();
uploadedImage = BitmapFactory.decodeStream(in);
with
File image = new File(filePath);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(), bmOptions);
bitmap = Bitmap.createScaledBitmap(bitmap, imageView.getWidth(), imageView.getHeight(), true);
Note: In case of marshmallow, don't forget to add security permission in your code.
I tried to use Picasso instead but still no luck:
That is because you are not using the correct Uri. You are using a Uri that points to the entire collection of scanned media.
If you read the documentation for ACTION_PICK, it has:
Output: The URI of the item that was picked.
Here, the Uri in question is obtained by calling getData() on the Intent delivered to onActivityResult().
So, replace .load(MediaStore.Images.Media.DATA) with .load(data.getData()).
Also, most likely, you need to increase the size of the image, as a 10px x 10px image is going to be rather small.

android passing image file path to A then to B and finally C acitivity

I'm new to android and to java trying to learn my way in.
Right now I am trying to achieve (A)Select image form gallery (B) show a preview and ( C ) activity is Uploading to server:
Select image form gallery and show a preview: done (achieved) by using below Code
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// call android default gallery
startActivityForResult(intent, PICK_FROM_GALLERY);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == PICK_FROM_GALLERY) {
if (resultCode == RESULT_OK) {
fileUri = data.getData();
filePath = getRealPathFromURI(getApplicationContext(), fileUri);
Intent imagePreview = new Intent(MainActivity.this, ImagePreview.class);
imagePreview.putExtra("filePath", filePath);
startActivity(imagePreview);
}
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}}
}
And In ImagePreview.java
Intent imagePreview = getIntent();
// image or video path that is captured in previous activity
filePath = imagePreview.getStringExtra("filePath");
displayImage(filePath);
private void displayImage(String filePath) {
ImageView imageView = (ImageView) findViewById(R.id.imageView1);
imageView.setImageBitmap(BitmapHelper.decodeSampledBitmap(filePath, 300, 250));
Now According to my understanding, since the filePath is already a string, I should be able it pass it to uploadactivity.java as such
private void upload(){
Intent upload = new Intent(ImagePreview.this, UploadActivity.class);
upload.putExtra("finalImage", filePath);
startActivity(upload);
}
and in uploadactivity.java
Intent upload = getIntent();
// image or video path that is captured in previous activity
finalImage = upload.getStringExtra("finalImage");
By this I can get to UpoloadActivity and upload button is displayed but filePath is not passed.
What am I doing wrong?
You're not using the same key for the extras:
upload.putExtra("finalImage", filePath);
upload.getStringExtra("filePath");
Replace
finalImage = upload.getStringExtra("filePath");
with
finalImage = upload.getStringExtra("finalImage");

Imageview from phone galley

im trying to access and select an image from my phone galley onto my application imageView, using android. So far ive managed to set get to the galley and select the image i want to use, the only problem is that once ive selected the image i want i cant get it onto the imageview. the problem seems to be that ive got the imageview class seperate from my main class. ive checked and cant find a solution.
heres the code for the mediagalley class
public class MediaGallery extends Activity {
public static final int SELECT_IMAGE = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == SELECT_IMAGE) {
Uri selectedImage = data.getData();
String path = getPath(selectedImage);
Bitmap bitmapImage = BitmapFactory.decodeFile(path);
ImageView image = (ImageView) findViewById(R.id.imageView1);
image.setImageBitmap(bitmapImage);
}
}
public String getPath(Uri uri) {
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, filePathColumn, null,null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
return cursor.getString(columnIndex);
}
}
and the main class code
case R.id.gallery_button:
MediaGallery activ1 = new MediaGallery();
Intent gallery = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, 1);
activ1.onActivityResult(1, 1, gallery);
break;
any help u gave give il be very greatful
You have declared MediaGallery is another Activity. Are you trying to show an ImageView on the same activity from which you select the button to launch the picker, or in a new activity? If the former, put that onActivityResult code into your main class. If the latter, then your main class should pass the Intent data to the MediaGallery class.

Android - Image does not display from built-in gallery

I am trying to use Android's built-in gallery. I am able to get the gallery and the albums, but whenever I want to display the image, the gallery straightaway directs me back to my app. I am unable to view the image despite it has been called.
This is my code:
public class CameraTab extends Activity implements OnClickListener{
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_tab);
ImageButton cameraBtn = (ImageButton)findViewById(R.id.camera_btn);
cameraBtn.setOnClickListener(this);
ImageButton galleryBtn = (ImageButton)findViewById(R.id.gallery_btn);
galleryBtn.setOnClickListener(this);
}
public void onClick(View v) {
// TODO Auto-generated method stub
if (v == this.findViewById(R.id.camera_btn)){
/// some codes here
}
if (v == this.findViewById(R.id.gallery_btn)){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
Can anyone please help me? Any help would be appreciated!! Thanks!!
The problem is a misunderstanding of Intent.ACTION_GET_CONTENT intent. It's intented to be used to choose a content (in this case image/*) from the archive.
If you want to show an image, just create a new activity with an ImageView in its layout. Pass the image URI using setData.
I think the Action you want to use is Intent.ACTION_VIEW.
try this
final Intent intent = new Intent(Intent.ACTION_VIEW);
final Uri uri = <The URI to your file>;
// Uri either from file eg.
final Uri uri = Uri.fromFile(yourImageFileOnSDCard);
// or from media store like your method getPath() does but with the URI
// from http://developer.android.com/reference/android/provider/MediaStore.Images.Media.html#EXTERNAL_CONTENT_URI
intent.setDataAndType(uri, "image/*");
startActivity(intent);
The string "image/* is the mime type to be used.
Now the gallery is opened with the given picture selected. To return to your app the user has to press the back button, as usual ;)
private Context context;
public void onCreate(Bundle savedInstanceState) {
...
context = this;
}
I used a scaled Bitmap below because on some devices the images in the Gallery might be too large for being displayed on an ImageView (I had this problem before).
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
Bitmap b = new BitmapDrawable(context.getResources(),
selectedImagePath).getBitmap();
int i = (int) (b.getHeight() * (512.0 / b.getWidth()));
bitmap = Bitmap.createScaledBitmap(b, 512, i, true);
// To display the image, you need to set it to an ImageView here
ImageView img = (ImageView) findViewById(R.id.myImageView);
img.setImageBitmap(bitmap);
}
}
}

Learning the path of the captured image in onActivityResult method

#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()

Categories

Resources