I'm trying to share image on Instagram in my app. I've url of the image and using Picasso library to download image.
Target target = new Target() {
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
Log.d(TAG, "Bitmap Loaded");
File outputDir = getApplicationContext().getCacheDir(); // context being the Activity pointer
try {
File outputFile = File.createTempFile("instagram", "png", outputDir);
outputFile.createNewFile();
FileOutputStream ostream = new FileOutputStream(outputFile);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,ostream);
ostream.close();
Log.d(TAG, "Image downloaded");
shareOnInstagram(Uri.fromFile(outputFile));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(this).load(imageUrl).into(target);
But onBitmapLoaded is never being called. Is there any other way to share image on Instagram from a url? The intent which share on Instagram takes Intent.EXTRA_STREAM parameter which should be a media path on device.
How do I convert an image from a url into that type?
Picasso only keeps weak reference to target, so in your case it will be garbage collected. As a result, onBitmapLoaded is not being called.
You should store strong reference to target (make target member of your class).
I using this approach
public class ShareToOtherApp extends AsyncTask<Bitmap, Void, Uri> {
#Override
protected Uri doInBackground(Bitmap... bitmaps) {
return bitmaps.length > 0 ? BitmaptoUri(bitmaps[0]) : null;
}
#Override
protected void onPostExecute(Uri uri) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
if (uri != null) {
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
}
shareIntent.setType("image/*");
Intent chooserIntent = Intent.createChooser(shareIntent, "Share Image");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyApp.GetContext().startActivity(chooserIntent);
}
public File GetSDCardDir(){
boolean ISSDCard;
File[] Dirs = ContextCompat.getExternalFilesDirs(MyApp.GetContext(), null);
ISSDCard = false;
for (File Dir : Dirs) {
if (Dir != null) {
if (Dir.getPath().contains("sdcard")) {
ISSDCard = true;
break;
}
}
}
File SDCardDir;
if(ISSDCard && Dirs[Dirs.length -1] != null){
SDCardDir = Dirs[Dirs.length -1];
}else{
SDCardDir = Dirs[0];
}
return SDCardDir;
}
public Uri BitmaptoUri(Bitmap bitmap){
Uri uri = null;
try {
File file = new File(GetSDCardDir() , HConstants.IMG_FILE_NAME + ".jpg");
if(file.getParentFile() != null){
file.getParentFile().mkdirs();
}else{
GetSDCardDir().mkdirs();
}
file.createNewFile();
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.close();
uri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return uri;
}
}
and finally for using from it.
new ShareToOtherApp().execute(bitmap);
Related
I've created a camera with Android Studio and want to save the taken image to the gallery.
I use the Camera2 Api and don't really know how to save the picture.
Moreover, I don't know, where my photo gets stored. The App says: Saved: /storage/emulated/1.jpg.
Here is some code:
mFile = new File(Environment.getExternalStorageDirectory() + "1.jpg");
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
= new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
}
};
private static class ImageSaver implements Runnable {
/**
* The JPEG image
*/
private final Image mImage;
/**
* The file we save the image into.
*/
private final File mFile;
public ImageSaver(Image image, File file) {
mImage = image;
mFile = file;
}
#Override
public void run() {
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
FileOutputStream output = null;
try {
output = new FileOutputStream(mFile);
output.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
mImage.close();
if (null != output) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
The next problem is, that I don't know how to store more photos. In this case, 1.jpg is always overwritten.
To add your picture in the gallery :
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
See here
To save multiple pictures generate a new name for every new picture (use the date and time or an UUID)
I have a chat app and I need to save the images that the user sends receives. For the images the user sends I am saving it to an image folder like so
private void imageDownload(final String url){
Picasso.with(getContext())
.load(url)
.into(getTarget(url));
}
//target to save
private static Target getTarget(final String url){
Target target = new Target(){
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
new Thread(new Runnable() {
#Override
public void run() {
File heyJudeFile = new File(Environment.getExternalStorageDirectory().getPath() + "/Hey Jude");
if (!heyJudeFile.exists()){
heyJudeFile.mkdirs();
}
localProfilePictureAdress = Environment.getExternalStorageDirectory().getPath() + "/Hey Jude" + "/" + url.substring(url.lastIndexOf("/")+1);
File file = new File(localProfilePictureAdress);
try {
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, ostream);
ostream.flush();
ostream.close();
} catch (IOException e) {
Log.e("IOException", e.getLocalizedMessage());
}
}
}).start();
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
return target;
}
But for images the user receives I want to save the images but I do not want the images to be viewable in the gallery how does that work?
Thanks
Use below method to hide media from gallery
/* To Hide media file in gallery */
public void createNoMedia(String myDir){
File noMediaFile = new File(myDir, ".nomedia");
if (!noMediaFile.exists()) {
try {
noMediaFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* To use this */
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/MyImages/";
File newDir = new File(dir);
newDir.mkdirs();
createNoMedia(dir);
and in manifest.xml
You also need the WRITE_EXTERNAL_STORAGE permission.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
you can do it by editing name of your file and adding an unknown format like ".example" then it doesn't appear in gallery
Sorry for my english is not good.
I have a problem, i download image from url by using picasso library, then store it in sdcard, but i can't see it in sdcard, and i only see it when i restart my phone, here is my code, what i do wrong??? help me, please !!!
public class Image extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_show_image);
Intent it = getIntent();
Bundle bundle = it.getExtras();
final String link = bundle.getString("link");
final ImageView ivView = (ImageView) findViewById(R.id.ivView);
Picasso.with(getApplicationContext()).load(link).into(ivView);
Button btSetWallpaper = (Button) findViewById(R.id.btSetWallpaper);
btSetWallpaper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downloadImage(link);
}
});
}
public void downloadImage(final String link){
Picasso.with(getApplicationContext()).load(link).into(new Target() {
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/abc.jpg");
try {
file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.close();
}
catch (Exception e){
e.getStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Success" + Environment.getExternalStorageDirectory().getPath(), Toast.LENGTH_LONG).show();
}
#Override
public void onBitmapFailed(Drawable drawable) {
Toast.makeText(getApplicationContext(), "Load Fail", Toast.LENGTH_LONG).show();
}
#Override
public void onPrepareLoad(Drawable drawable) {
}
});
}
}
You need to tell Android Media Library that a media file has been added.
Intent intent =
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);
Replace the file with your saved file and it should appear in your Android Media Library without rebooting the phone.
You need to tell the system to run a media scanner and only then the file will appear in the gallery. Which can be done as follows:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
OR
MediaScannerConnection.scanFile(this,
new String[] { filepath }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// your code here
}
});
I have a button that downloads an image to the phone gallery using Picasso library.. the image is downloaded but I can't save it to the gallery..
I'm trying to save the image to the DCIM folder using the following code :
if (bitmap != null) {
FileOutputStream out = null;
try {
String name = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
+ "/"
+ pageTitle
+ "-img"
+ System.currentTimeMillis() + "." + imgExt;
Log.d("Bitmap", "Name: " + name);
File f = new File(name);
out = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
Intent mediaScanIntent = new
Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
SinglePageActivity.this.sendBroadcast(mediaScanIntent);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
Log.d("Bitmap", "Null image");
}
But I get the following exception :
java.io.FileNotFoundException:
/storage/sdcard/DCIM/offer11-img1438046842226.jpg: open failed: EACCES
(Permission denied)
Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
on this line :
out = new FileOutputStream(f);
Also is there a more efficient way to save the image to the gallery directly ?
Thanks
check if you have declared the permission in
AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>,
if not,then try to add;
You can use like this
public class ImageDownload implements Target {
public static final String TAG = "tag";
private String name;
public ImageDownload(String fileName) {
name = fileName.substring(fileName.lastIndexOf("/"));
}
#Override
public void onBitmapFailed(Drawable arg0) {
// TODO Auto-generated method stub
}
#Override
public void onBitmapLoaded(final Bitmap bitmap, LoadedFrom arg1) {
Log.e("ImageDownlaod", "inside Download ");
new Thread(new Runnable() {
#Override
public void run() {
File file = new File(Environment.getExternalStorageDirectory()
.getPath() + "/" + FACTOR_APP + "/" + name);
try {
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
#Override
public void onPrepareLoad(Drawable arg0) {
// TODO Auto-generated method stub
}
}
and you can use this class as
public void downLoadImagesWithPicasso() {
Picasso.with(this).load(thumbnailPath)
.into(new ImageDownload(thumbnailPath));
}
I want to capture an image from custom camera and then display it on an other activity where i can add other png emoticons, i have this code but it doesnt show any photo after activity launches
Please see some changes which i have done in your code.
1. please call new Intent after taking photo and the pass the filepath as i do.
MainActivity :
ImageView mCaptureButton = (ImageView) findViewById(R.id.button_capture);
mCaptureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the came
mCamPreview.captureImage(MainActivity.this);
//starting(); // don't call Intent here
}
});
}
CameraPreview class:
private Activity _activity ;
public void captureImage(Activity activity){
this._activity = activity;
mCamera.takePicture(null, null, mJpegCallback);
}
PictureCallback mJpegCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
// Store bitmap to local storage
FileOutputStream out = null;
try {
// Prepare file path to store bitmap
// This will create Pictures/MY_APP_NAME_DIR/
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "AVORI");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "failed to create directory");
return;
}
}
// Bitmap will be stored at /Pictures/MY_APP_NAME_DIR/YOUR_FILE_NAME.jpg
String filePath = mediaStorageDir.getPath() + File.separator + "Av.jpg";
out = new FileOutputStream(filePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
//call EditPicture.class here
Intent i = new Intent(_activity, EditPicture.class);
i.putExtra("FILE_PATH", filePath );
startActivity(i);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
};