As known, ALBUM_ART was deprecated in Android 11. Google says that ContentResolver.loadThumbnail should be used instead. But i totally don't understand how to use it, especially what i should provide as first parameter, uri. Documentation says:
Uri: The item that should be visualized as a thumbnail. This value cannot be null.
What is that item and how can I get it? Is this Uri of the music file?
You need to pass in the Uri of the track.
//This will get you the uri of the track, if you already have the track id
Uri trackUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, trackId);
Bitmap bm = contentResolver.loadThumbnail(trackUri, new Size(512,512), null);
Set the bitmap to an ImageView
imageView.setImageBitmap(bm);
Related
EDIT:
I asked a similar question a day before and I wrote this post based on information I gathered since that question -
First Cache Question. I know they are similar but this question is more concise to avoid extra information. I also didn't want to delete that post since it was answered, even though the answer didn't suffice.
I use a recyclerview to show photos I get from google places api. I know that I am not allowed to legally cache photos outside of runtime. I didn't know that was happening until I randomly opened my phone's gallery to see a lot of copies of the photos I get from google.
My first guess was that my use of Picasso was the issue so I added code to fix it,
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE)
finding these in StackOverflow was pretty simple, but this didn't fix anything except that now it seems to only download them once especially when I delete them. I believe I eliminated the possible issues and am outlining the last one in this question.
private Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
#Override
public void onBindViewHolder(#NonNull VenueViewHolder venueViewHolder, int i) {
Collections.sort(vIAL, (o1, o2) -> o1.getVenueName().compareToIgnoreCase(o2.getVenueName()));
VenueItem currentItem = vIAL.get(i);
Picasso.with(context)
.load(getImageUri(context, currentItem.getVenueImage()))
.fit()
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(venueViewHolder.vIV);
venueViewHolder.vTV.setText(currentItem.getVenueName());
Log.i(TAG, "The photo should have been on screen");
}
The URI method getImageUri is something I found as an answer to another problem I had, that I needed a URI to implement the Picasso library so that I can manipulate the photos before displaying them.
My question is - How do I remove the photos when the app closes?
UPDATE:
I changed my tactic to see what would happened and used Glide
#Override
public void onBindViewHolder(#NonNull VenueViewHolder venueViewHolder, int i) {
Collections.sort(vIAL, (o1, o2) -> o1.getVenueName().compareToIgnoreCase(o2.getVenueName()));
VenueItem currentItem = vIAL.get(i);
Glide.with(context)
.load(currentItem.getVenueImage())
.into(venueViewHolder.vIV);
venueViewHolder.vTV.setText(currentItem.getVenueName());
}
and it gave a fatal Error
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 4344032)
This was one of the errors and it didn't occur the first time I ran this new code but it got worse the second and third time I ran it.
I shifted my code based on an answer I got early from #Padmini S but they used a url in the load part and I pass a bitmap because for the life of me I can't figure out how to get a URL from Google Places API instead of the code they provide in
Google Place Photos.
I'm relatively new to coding so this is me trying to piece together what I need to learn more. I'm just out of ideas of what to search for so I ask here,
based on the new information I gathered from the answer, can I replace
MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
in my code so that my photos don't get saved to my phone's photos?
Final Update
I ended up rewriting a lot of the code surrounding this and deleting this code. I ended up making an arraylist class to hold the array list for the duration of runtime and it let me remove most of the extra code I wrote out of ignorance.
I really don't know whether it'll solve your problem or not , but you are storing the images in device local storage here,
private Uri getImageUri(Context inContext, Bitmap inImage) {
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
}
I have never used google places api but usually apis will return you with an image url you can store that url in POJO class and display it directly in recyclerview row image view like I am doing in below code,
public void onBindViewHolder(#NonNull ViewHolder viewHolder, final int i) {
viewHolder.description.setText(links.get(i).getTitle());
Glide.with(context).load(links.get(i).getImage_url()).into(viewHolder.image);
}
I am developing a small online shopping application in Android which needs to have lot of items images, I have a web service which gives the path of image present in android drawable-mdpi, My problem here that I tried this code to get the imageresource id, but it always gives me 0.
String uri = "#drawable/bangle1.png";
int imageResource = getResources().getIdentifier(uri, null, getPackageName());
Is there any method, to get resource id, so that I can use it for drawable like :
Drawable res = getResources().getDrawable(imageResource);
I tried googling but most of them suggested the above method and this gives me always 0 value. Any one please help here.
It will be better to get your images into /assets/ folder, and don't use drawable resources for that. Because Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.
If you still want to use your method try
getResources().getIdentifier("bangle1.png", "drawable", getPackageName());
Thanks to all , even i tried it all suggested answers by others , it didnt resolve but i found finally the solution here: How do I get the resource id of an image if I know its name?.
it worked magically:
String mDrawableName = "bangle1";
int resID = getResources().getIdentifier(mDrawableName , "drawable", getPackageName());
Here , myDrawableName should not have extension like : ".png". Thanks to all.
Your problem is that you're writing the image name with its suffix. Try using this code:
int imageResource = getResources().getIdentifier(
"your image name without suffix(bangle1)", "drawable", YourActivtyName.this);
Loading images with Picasso is seemingly so easy, until I hit this roadblock. Not sure why! I can load photos from contacts via PHOTO_URI if the contacts only have a thumbnail, or, if I instead ask for PHOTO_THUMBNAIL_URI specifically.
#Override
public void bindView(View view, Context context, Cursor cursor) {
ImageView icon = (ImageView)view.findViewById(R.id.ContactImage);
String photoUri = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_URI));
if (photoUri == null) {
icon.setImageDrawable(null);
} else {
Picasso.with(context).load(photoUri).into(icon);
}
}
For what it's worth: if I use Picasso.with(context).load(photoUri).placeholder(R.drawable.placeholder).error(R.drawable.error).into(icon); then I see the placeholder image in the place of every contact who has a high res image. I never see an "error" picture. If I revert back to just using icon.setImageURI(Uri.parse(photoUri)); then I see the high res contact images again just fine. (But then I don't have a snazzy async caching picture loader!)
UPDATE: Thanks to #copolii and his answers below, the following now works flawlessly with Picasso 2.1.1:
#Override
public void bindView(View view, Context context, Cursor cursor) {
Long id = cursor.getLong(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
String photoUri = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_URI));
ImageView icon = (ImageView)view.findViewById(R.id.ContactImage);
if (photoUri == null) {
icon.setImageDrawable(null);
} else {
Picasso
.with(context)
.load(contactUri)
.into(icon);
}
}
This loads the higher-res photo, if there is one, and if not, shows the low-res photo, and if there is no photo set for a contact, it's set to a blank / null.
Have you tried using a contact uri?
That last boolean parameter in openContactPhotoInputStream promises to get you the high res photo if one is available.
Instead of using a photo uri use a contact uri or a contact lookup uri.
UPDATE
Since the question has been answered, I though I'd post the relevant details here:
A small test app is posted here (You need Android Studio): https://github.com/copolii/PicassoContactsTest
If you set both a placeholder and an error icon, the error icon is displayed for contacts who do not have a picture. I'd recommend setting the social face guy as your place-holder and no error icon. That way, your place-holder stays on if the contact has no picture.
If you do want to differentiate between the two, choose your error icon with the above in mind (i.e. don't use a big red OMFG error indicator).
--- Previous Content ---
Let me know if that helps.
I did the work for the contacts photo loading and unless I'm missing something, you should get the high resolution picture (API 14+) automatically:
if (SDK_INT < ICE_CREAM_SANDWICH) {
return openContactPhotoInputStream(contentResolver, uri);
} else {
return openContactPhotoInputStream(contentResolver, uri, true);
}
It seems that the openContactPhotoInputStream doesn't like the PHOTO_URI.
Android Docs: openContactPhotoInputStream
If the URIs are distinguishable I can easily add support for PHOTO_URI as well (I have to find out how to load it first though). I'm already determining if the given uri is a contact photo uri or a contact lookup uri (older android versions do not like lookup uris being fed into openContactPhotoInputStream so I have to dereference the lookup uri into a contact uri before passing it to openContactPhotoInputStream).
I hope this helps.
Here is an excerpt of the code. I can compile it, but the program crashes on the phone/emulator.
Bitmap bitmap;
View v1 = MyView.getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
String path = Images.Media.insertImage(getContentResolver(), bitmap,
"title", null);
Uri screenshotUri = Uri.parse(path);
final Intent socialIntent = new Intent(Intent.ACTION_SEND);
socialIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
socialIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
socialIntent.setType("image/png");
Anyone know how to do it? I want to capture a screenshot and let the user share it if he/she likes to. Everything else work, it's just the screenshot I cannot get.
The only way a screenshot can be obtained is by having direct access to the frame-buffer which is at the kernel level, this in turn requires rooted access to accomplish this and to pull in the data from there to make up the graphics that is the screen itself.
This requires either a modded ROM for this purpose or having root privilege to do so. Sony, I know, do it, they have that facility in place to do so without root as the ROM is modified, in the power menu, there is an option 'Take Screenshot'. CM is another that requires root.
There is a facility available in ICS that has the programmatic API available to do this, see this answer, but with earlier versions, you're out of luck.
So I'm trying to launch the Camera activity using the following code:
//In public void captureImage()
...
Intent cameraIntent = new Intent(MediaStore.ACTION_CAPTURE_IMAGE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(new File("/sdcard/image.jpg")));
startActivityForResult(cameraIntent, REQUEST_CAMERA);
And then to handle the result:
//In onActivityResult()
...
case REQUEST_CAMERA:
Intent intent = new Intent (CurrentScreen.this, NextScreen.this);
intent.putExtra(data);
startActivity(intent);
CurrentScreen.this.finish();
...
Where I use intent.putExtra(data) to attach the small bitmap to the intent, and use it as a thumbnail in the next activity, and the full sized file is supposedly saved as /sdcard/image.jpg.
This is the expected behavior (according to the documentation), to have a small bitmap for a thumbnail, and a large file saved. However when testing this on a G1 and an Eris, I have been seeing some strange behavior.
On the G1:
Although the resultCode shows RESULT_OK, the intent data that is returned to the result handler is null.
Also EXTRA_OUTPUT seems to be completely ignored, I have no idea where it is saving the image.
On the Eris:
The intent data comes back OK
EXTRA_OUTPUT is also ignored, but it is saving the images to the regular media store at /sdcard/dcim/100media
So my question is this: is there any way to get consistent behavior for what I am trying to do using the standard camera activity? I could write up a custom activity to try and get it to work the way I want, but I'd prefer to avoid that route.
I do not have answers to your question as I am new to the Java/Android development world. But I am attempting something similar to what you are doing, except I want to simply take the picture then attach it to an Email message.
I implemented part of your example and was able to verify that the camera created the file I specified and that if I use the same file name for the next picture that it overwrites the previous file which is what I would expect.
But what I was really going to say is perhaps you will have to test if the pat "/sdcard/..." actually exists or not. Also you could possibly simplify your process by passing the path to the next activity.
Good Luck,
Jamie Irwin