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));
Related
I am trying to reload the image that I get from either my gallery or camera in the imagebutton once the app closes
I have tried saving it to a file and loading from that file but I cannot get it to work.
public class HomeFragment extends Fragment {
ImageButton profilePic;
Drawable myDrawable;
Bitmap bitmap ;
String photoPath = Environment.getExternalStorageDirectory().toString();
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
profilePic = (ImageButton) root.findViewById(R.id.imageButton);
myDrawable = profilePic.getBackground();
bitmap = drawableToBitmap(myDrawable);
// set up listener on ImageButton to load method changeProfilePicture() when user clicks profilePic
profilePic.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
changeProfilePicture();
}
});
int Permission_All = 1;
String[] Permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
if(!hasPermissions(getActivity(), Permissions)){
ActivityCompat.requestPermissions(getActivity(), Permissions, Permission_All);
}
loadImageFromStorage(photoPath);
return root;
}
public void onResume() {
super.onResume();
loadImageFromStorage(photoPath);
}
public void onStart() {
super.onStart();
}
public void onPause() {
super.onPause();
}
public void onStop() {
super.onStop();
saveBitmap(bitmap);
}
public void onDestroy() {
super.onDestroy();
}
static final int REQUEST_IMAGE_CAPTURE = 1;
static final int REQUEST_GALLERY = 0;
//create changeProfilePicture method and call it when the ImageButton is pressed
public void changeProfilePicture() {
// add alert dialog to ask user how they would like to change their profile icon
}
// override onActivityResult to allow the imageButton to be changed to picture taken from camera or gallery
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK) {
//create a switch based on requestCode
switch (requestCode) {
// if user clicks change profilePic through gallery use picture user picked from gallery
case REQUEST_GALLERY:
Uri galleryImage = data.getData();
try {
Bitmap galleryBitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), galleryImage);
galleryBitmap = Bitmap.createScaledBitmap(galleryBitmap, 200, 200, false);
profilePic.setImageBitmap(galleryBitmap);
saveBitmap(galleryBitmap);
} catch (IOException e) {
Log.i("TAG", "Exception " + e);
}
break;
// if user clicks change profilePic through camera use picture user took from camera app
case REQUEST_IMAGE_CAPTURE:
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
imageBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 200, false);
profilePic.setImageBitmap(imageBitmap);
saveBitmap(imageBitmap);
break;
}
}
}
private void saveBitmap(Bitmap bm){
File file = Environment.getExternalStorageDirectory();
File newFile = new File(file, "myImage.jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(newFile);
bm.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i( "getExternalStorageDirectory", file.getPath()) ;
}
private void loadImageFromStorage(String path)
{
try {
File f=new File(path, "myImage.jpg");
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
profilePic.setImageBitmap(b);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
} else {
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;
}
public static boolean hasPermissions(Context context, String... permissions)
{
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M && context!=null && permissions!=null){
for(String permission: permissions){
if(ActivityCompat.checkSelfPermission(context, permission)!= PackageManager.PERMISSION_GRANTED){
return false;
}
}
}
return true;
}
}
// what I have for my ImageButton in xml
<ImageButton
android:id="#+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:contentDescription="#string/profilePic"
android:onClick="changeProfilePicture"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="5dp"
android:background="#0000"
app:srcCompat="#mipmap/ic_launcher_round" />
I have the following permissions inside the manifest.xml
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I am trying to save the new ImageButton from my result and load it when the app is relaunched. Can this be done with an ImageButton? Can it be saved to and loaded from a file?
As a first step, you need to get the bitmap from the imageButton like this
Bitmap bitmap = ((BitmapDrawable)imageButton.getDrawable()).getBitmap();
Next you need to save this Bitmap to external storage like this
private void saveBitmap(Bitmap bm){
File file = Environment.getExternalStorageDirectory();
File newFile = new File(file, "myImage.jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(newFile);
bm.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
And you load this saved bitmap like this
private void loadImageFromStorage(String path)
{
try {
File f=new File(path, "myImage.jpg");
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
imageButton.setImageBitmap(b);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
You should define the image path like this
String photoPath = Environment.getExternalStorageDirectory() + "/myImage.jpg";
This is the main idea, you can add a bit of flavor into this code by setting a default image when there is no available image saved.
Hope this is what are looking for.
UPDATE:
You need to change this line
Bitmap bitmap = ((BitmapDrawable)imageButton.getDrawable()).getBitmap();
To this
Drawable myDrawable = imageButton.getBackground();
After that you convert this Drawable to a Bitmap
Bitmap bitmap = drawableToBitmap(myDrawable);
Here is the function for this conversion
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
} else {
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;
}
UPDATE 2 :
You need to request runtime permissions to save and retreive images
First you need to add this to your manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Next add this method to your activity
public static boolean hasPermissions(Context context, String... permissions)
{
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M && context!=null && permissions!=null){
for(String permission: permissions){
if(ActivityCompat.checkSelfPermission(context, permission)!= PackageManager.PERMISSION_GRANTED){
return false;
}
}
}
return true;
}
Finally in your onCreate add those lines
int Permission_All = 1;
String[] Permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
if(!hasPermissions(this, Permissions)){
ActivityCompat.requestPermissions(this, Permissions, Permission_All);
}
I am working on online gallery app, in a fragment Dialog images from specific displaying as a viewPager.
But the main problem i am unable to share a particular image on whatsapp because I am finding difficulty to get imageViewPreview.
Here is the code for loading image in viewPager
public class MyViewPagerAdapter extends PagerAdapter {
private LayoutInflater layoutInflater;
public MyViewPagerAdapter() {
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.image_fullscreen_preview, container, false);
final ImageView imageViewPreview = (ImageView) view.findViewById(R.id.image_preview);
Image image = images.get(position);
Glide.with(getActivity()).load(image.getLarge())
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageViewPreview);
container.addView(view);
return view;
}
Now i am trying to get image from imageViewPreview from
whatsappShare.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.e(TAG, "Click working");
//shareImage();
// ImageView imageWhatsapp = (ImageView) view.findViewById(R.id.image_preview);
Uri bmpUri = getLocalBitmapUri(imageViewPreview);
if (bmpUri != null) {
// Construct a ShareIntent with link to image
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
shareIntent.setType("image/*");
shareIntent.setPackage("com.whatsapp");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Launch sharing dialog for image
startActivity(Intent.createChooser(shareIntent, "Share Image"));
} else {
// ...sharing failed, handle error
Log.e(TAG, "ERROR" + bmpUri);
}
}
});
My getLocalBitmapUri() methos is as follow:
public Uri getLocalBitmapUri(ImageView imageViewPreview) {
// Extract Bitmap from ImageView drawable
Drawable drawable = imageViewPreview.getDrawable();
Bitmap bmp = null;
if (drawable instanceof BitmapDrawable) {
bmp = ((BitmapDrawable) imageViewPreview.getDrawable()).getBitmap();
} else {
return null;
}
// Store image to default external storage directory
Uri bmpUri = null;
try {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "share_image_" + System.currentTimeMillis() + ".png");
file.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(file);
Log.e(TAG, "popopo: " + file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
But the problem is I am getting **NULL** from getLocalBitmapUri() method.
please guide me the get imageViewPreview.
i had faced sacreate this method, few time ago i used it and work, i forgot who given this snippet.
public Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
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;
}
at your getLocalBitmapUri()
public Uri getLocalBitmapUri(ImageView imageViewPreview) {
// Extract Bitmap from ImageView drawable
Drawable drawable = imageViewPreview.getDrawable();
Bitmap bmp = drawableToBitmap(imageViewPreview);
//...................
try {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "share_image_" + System.currentTimeMillis() + ".png");
file.getParentFile().mkdirs();
if(!file.exist()) file.createNewFile();
//..............
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 have created a custom listview that is handled by a custom adapter. Each item in this list displays an image and a share button. The images are loaded from external sources with ion. This works fine.
Now I want to share the image when the user clicks on the button. While I'm able to share text, etc. I'm not able to share these external images, even after implementing this code: Sharing Remote Images
Two things:
I'm new to android so I might be using the setTag/getTag completely wrong
if (drawable instanceof BitmapDrawable) is false, but I don't know why or how to fix this
Any help or suggestion is greatly appreciated!
This is the code from my adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
//brand new
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.contentImageView = (ImageView) convertView.findViewById(R.id.contentImageView);
holder.contentLabel = (TextView) convertView.findViewById(R.id.contentLabel);
holder.contentShareButton = (Button) convertView.findViewById(R.id.contentShareButton);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
Content content = mContents[position];
Ion.with(mContext)
.load(content.getSrc()) //the external image url
.intoImageView(holder.contentImageView);
holder.contentLabel.setText(content.getTitle());
holder.contentShareButton.setTag(holder.contentImageView);
holder.contentShareButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ImageView ivImage = (ImageView) v.getTag();
//ImageView ivImage = (ImageView) findViewById(R.id.ivResult);
// Get access to the URI for the bitmap
Uri bmpUri = getLocalBitmapUri(ivImage);
if (bmpUri != null) {
// Construct a ShareIntent with link to image
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
shareIntent.setType("image/*");
// Launch sharing dialog for image
mContext.startActivity(Intent.createChooser(shareIntent, "Share Image"));
} else {
Log.i("test", "Sharing failed, handler error.");
}
}
});
return convertView;
}
// Returns the URI path to the Bitmap displayed in specified ImageView
public Uri getLocalBitmapUri(ImageView imageView) {
// Extract Bitmap from ImageView drawable
Drawable drawable = imageView.getDrawable();
Bitmap bmp = null;
if (drawable instanceof BitmapDrawable){
bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
} else {
Log.i("test", "is null");
return null;
}
// Store image to default external storage directory
Uri bmpUri = null;
try {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "share_image_" + System.currentTimeMillis() + ".png");
file.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
Adding these four lines to the getLocalBitmapUri-function got it working for me:
bmp = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
And here is the complete function with the updated code:
// Returns the URI path to the Bitmap displayed in specified ImageView
public Uri getLocalBitmapUri(ImageView imageView) {
// Extract Bitmap from ImageView drawable
Drawable drawable = imageView.getDrawable();
Bitmap bmp = null;
if (drawable instanceof BitmapDrawable){
bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
} else {
bmp = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
}
// Store image to default external storage directory
Uri bmpUri = null;
try {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "share_image_" + System.currentTimeMillis() + ".png");
file.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
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);
}
}