I'm attempting to save all of the icons of the packages on a device as a BMP or PNG file by iterating through each package and doing the following.
Drawable icon = getPackageManager().getApplicationIcon(packageInfo);
Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Config.ARGB_8888);
try {
out = new FileOutputStream("/storage/sdcard0/images/" + packageInfo.packageName +".png");
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
out.close();
} catch(Throwable ignore) {}
}
This is creating blank images though, how would I change my code to create the actual icon in an image format?
My issue was this if anyone has the same problem, I referenced this answer.
I forgot to check to see if the icon was already an instance of BitmapDrawable. Because it was I could just cast it to a bitmapdrawable and use .getBitmap
if (icon instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable)icon).getBitmap();
}else{
bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Config.ARGB_8888);
}
Below is the code that could cover all the cases.
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if (bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
return Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
}
Related
I've been trying to check if a ImageView has a bitmap on it and it's not working..
I tried
Bitmap bitmap = ((BitmapDrawable) IdFront.getDrawable()).getBitmap();
but it retunrs ""
and imageViewOne.getDrawable() == null
and finally :
private boolean hasImage(#NonNull ImageView view) {
Drawable drawable = view.getDrawable();
boolean hasImage = (drawable != null);
if (hasImage && (drawable instanceof BitmapDrawable)) {
hasImage = ((BitmapDrawable)drawable).getBitmap() != null;
}
return hasImage;
But the Bitmap returns "" and not null.
You could do like this:
ImageView view = findViewById(R.id.imageView);
view.setImageResource(R.drawable.sample);
BitmapDrawable drawable = (BitmapDrawable) view.getDrawable();
Bitmap bitmap = drawable.getBitmap();
If you want to know drawable or bitmap variable value when debugging, you could see
drawable.toString()
bitmap.toString()
like below fig:
Try like below:
boolean hasImage = (view.getDrawable() == null);
I'm using Cardslib library. I was trying to add thumbnail view for each pacakge from its icon. Icon is Drawable type. So I assume, we need to use CustomSource to create a Bitmap of it. Then add it to the card.
The problem with the below code is, all packages gets same thumbnail image. (The image from last package appearing on the list). Is this due to cardslib loads them using the built-in AsyncTask and LRUCache. How to resolve this issue?
public void listpkg(Context c) {
ArrayList<Card> cards = new ArrayList<Card>();
Card card = new Card(this);
mContext = c;
CardHeader header = new CardHeader(c);
PackageManager pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
header = new CardHeader(this);
header.setTitle(pm.getApplicationLabel(packageInfo).toString());
card = new Card(this);
card.addCardHeader(header);
card.setTitle("Package: " + packageInfo.packageName);
icon =getPackageManager().getApplicationIcon(packageInfo); //TODO use this icon
tagname = packageInfo.packageName;
// CustomSource --
thumb = new CardThumbnail(c);
thumb.setCustomSource(new CardThumbnail.CustomSource() {
#Override
public String getTag() {
return tagname;
}
#Override
public Bitmap getBitmap() {
PackageManager pm = mContext.getPackageManager();
Bitmap bitmap = null;
try {
bitmap = drawableToBitmap(pm.getApplicationIcon(getTag()));
} catch (PackageManager.NameNotFoundException e) {
}
return bitmap;
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
});
card.addCardThumbnail(thumb);
// CustomSource --
cards.add(card);
}
CardArrayRecyclerViewAdapter mCardArrayAdapter;
mCardArrayAdapter = new CardArrayRecyclerViewAdapter(this, cards);
//Staggered grid view
CardRecyclerView mRecyclerView = (CardRecyclerView) this.findViewById(R.id.mainListView);
mRecyclerView.setHasFixedSize(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//Set the empty view
if (mRecyclerView != null) {
mRecyclerView.setAdapter(mCardArrayAdapter);
}
}
xml
<it.gmariotti.cardslib.library.recyclerview.view.CardRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:list_card_layout_resourceID="#layout/list_card_thumbnail_layout"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="12dp"
android:id="#+id/mainListView" />
Ok instead of keeping tagname to one variable and passing it to an inner implementation of CustomSource, you implement the CustomSource in another class and keep a field variable to hold the tagname. As in the current implementation the global (in this context) tagname is being replaced with each iteration.
class MyThumbnailSource implements CardThumbnail.CustomSource {
private String tagname;
public MyThumbnailSource(String tagname){
this.tagname = tagname;
}
#Override
public String getTag() {
return tagname;
}
#Override
public Bitmap getBitmap() {
PackageManager pm = mContext.getPackageManager();
Bitmap bitmap = null;
try {
bitmap = drawableToBitmap(pm.getApplicationIcon(getTag()));
} catch (PackageManager.NameNotFoundException e) {
}
return bitmap;
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
and call it like : thumb.setCustomSource(new MyThumbnailSource(tagname));
I was searching everywhere, but can't found solution...
I have two xml layouts for share.
I have inflated and assigned to the views correctly.
shareLayout = LayoutInflater.from(getApplicationContext()).inflate(R.layout.share_every_for_self_game_layout, null);
contentView = (LinearLayout) shareLayout.findViewById(R.id.share_container_layout_id);
Problem is that the shared image is always empty.
Here is my code
private void shareResultToFacebook(){
try {
Bitmap bitmap = getBitmapFromView(contentView);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, getImageUri(this, bitmap));
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
}catch (Exception e){
e.getMessage();
}
}
//create bitmap from view and returns it
private Bitmap getBitmapFromView(View view) {
try {
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(800, 600, Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
//Get the view's background
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
} else {
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
}
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}catch (Exception e){
Global.logError("getBitmapFromView", e);
}
return null;
}
public Uri getImageUri(Context inContext, Bitmap inImage) {
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(),
inImage, "", "");
return Uri.parse(path);
}catch (Exception e){
e.getMessage();
}
return null;
}
I found solution
I have changed my getBitmapFromView method body
private Bitmap getBitmapFromView(LinearLayout view) {
try {
view.setDrawingCacheEnabled(true);
view.measure(View.MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(600, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache(true);
Bitmap returnedBitmap = Bitmap.createBitmap(view.getDrawingCache());
//Define a bitmap with the same size as the view
view.setDrawingCacheEnabled(false);
return returnedBitmap;
}catch (Exception e){
Global.logError("getBitmapFromView", e);
}
return null;
}
And everything works fine ;)
private Bitmap getBitmapFromView(LinearLayout view) {
try {
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(800, 600, Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
//Get the view's background
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
} else {
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.RED);
}
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}catch (Exception e){
// Global.logError("getBitmapFromView", e);
}
return null;
}
I would like to get all the icons of all installed Applications in my Tablet. I know how to get icon and how to view them, but I would like to save each icon in an external file. The part of code used to get icon is given by the code below.
try{
String pkg = "com.app.my";//your package name
Drawable icon = getContext().getPackageManager().getApplicationIcon(pkg);
imageView.setImageDrawable(icon);
}
catch (PackageManager.NameNotFoundException ne)
{
}
Try something like this:
try{
//get icon from package
String pkg = "com.app.my";//your package name
Drawable icon = getContext().getPackageManager().getApplicationIcon(pkg);
imageView.setImageDrawable(icon);
Bitmap bitmap = drawableToBitmap(icon);
//save bitmap to sdcard
FileOutputStream out;
try {
out = new FileOutputStream(Environment.getExternalStorageDirectory()
+ File.separator + "output.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
//close output stream (important!)
try{
out.close();
} catch(Throwable ignore) {}
}
} catch (PackageManager.NameNotFoundException ne) {}
//convert drawable to a bitmap
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
I want to set the image res/drawable-hdpi/nasa_image.jpg as the wallpaper.
I wrote the following code but it raises the FileNotFoundException.
Uri u1 = Uri.fromFile(new File("res/drawable-hdpi/nasa_image.jpg"));
Uri u2 = Uri.parse("android.resource://com.my.package/drawable/nasa_image.jpg");
Uri u3 = Uri.parse("android.resource://com.my.package/" + R.drawable.nasa_image);
WallpaperManager w = WallpaperManager.getInstance(this);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(u));
w.setBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
First I tried for u1. It didn't work. Then I searched and found this. I then tried u2 and u3.
I checked the log. Every time it gave the same FileNotFoundException.
How to refer to it? Where am I wrong? Am I taking the wrong root directory?
I think this is a wrong way to do that in android. why don't you use the resource identifier?
ImageView imgView=(ImageView)findViewById(R.id.imageView1);
int id = getResources().getIdentifier(nasa_image, "drawable", getPackageName());
Drawable drawable=res.getDrawable(id);
imgView.setImageDrawable(drawable);
or
ImageView imgView=(ImageView)findViewById(R.id.imageView1);
Drawable drawable= getResources().getDrawable(R.drawable.nasa_image);
imgView.setImageDrawable(drawable);
imgView.setImageDrawable();
Update to convert from drawable to bitmap just use this (assuming that your drawable is an instanceof Bitmapdrawable)
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
Use this method if you are not sure about drawable instance
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
Use this method if you are sure that you the right file path
private Drawable getDrawable(String path) {
File imgFile = new File(path);
if (imgFile.exists()) {
Bitmap bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
return new BitmapDrawable(resources, bitmap);
}
return null;
}
you can adjust it to return bitmap or drawable according to your issue
You should not include the extention (.jpg)
Use:
Uri.parse("android.resource://" + BuildConfig.APPLICATION_ID + "/drawable/nasa_image");
Try
Uri u1 = Uri.parse("R.drawable.nasa_image");