Reputation: 4460
I'm trying save an image using API Picasso. To do it I'm trying use Target
to save but I can't do this work.
How could I do this ?
Trying
//save image
public static void imageDownload(Context ctx){
Picasso.with(ctx)
.load("http://blog.concretesolutions.com.br/wp-content/uploads/2015/04/Android1.png")
.into(getTarget("http://blog.concretesolutions.com.br/wp-content/uploads/2015/04/Android1.png"));
}
//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() {
//Log.i("PRODUTOS_FOLDER", CreateAppFolder.getProdutosFolder());
File file = new File(Environment.getExternalStorageDirectory() + url);
try {
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
ostream.flush();
ostream.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
return target;
}
Exception
java.io.IOException: open failed: ENOENT (No such file or directory)
Upvotes: 29
Views: 39356
Reputation: 1035
My kotlin solution, storing files into the internal storage and with no user permission needed:
since I had to download multiple images at once, had to create a MutableList<Target?> called shareTargetsArray and to fill it with the multiple targets otherwise the garbage collector would have removed them except the last one. Just remember to clean up that array once you're done.
private var shareTargetsArray: MutableList<Target?> = ArrayList()
fun downloadImage(context: Context, url: String?, slug: String) {
val shareTarget = object : Target {
override fun onBitmapLoaded(bitmap: Bitmap, from: LoadedFrom?) {
val contextWrapper = ContextWrapper(context)
val directory: File =
contextWrapper.getDir("customDirectory", Context.MODE_PRIVATE)
val file = File(directory, slug + ".png")
var outputStream: FileOutputStream? = null
try {
outputStream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.flush()
} catch (e: IOException) {
e.printStackTrace()
} finally {
try {
outputStream!!.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
override fun onBitmapFailed(e: java.lang.Exception?, errorDrawable: Drawable?) {}
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
}
shareTargetsArray.add(shareTarget)
Picasso.get().load(url).into(shareTarget)
}
}
Files are downloaded in /data/data/com.***.***/customDirectory/
You can check them using View > Tool Windows > Device File Explorer
Upvotes: 1
Reputation: 3291
I Modified the solution to this, adding permissions and a button to load and save the Image,and PhotoLoader class remains the same !
private static final String[] STORAGE_PERMISSIONS = { Manifest.permission.WRITE_EXTERNAL_STORAGE};
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
verifyPermissions();
}
public void save(View view)
{
Picasso.with(this)
.load("https://www.w3schools.com/howto/img_fjords.jpg")
.into(new PhotoLoader("myImg.jpg" , imageView));
}
public void verifyPermissions()
{
// This will return the current Status
int permissionExternalMemory = ActivityCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permissionExternalMemory != PackageManager.PERMISSION_GRANTED)
{
// If permission not granted then ask for permission real time.
ActivityCompat.requestPermissions(MainActivity.this,STORAGE_PERMISSIONS,1);
}
}
Upvotes: 1
Reputation: 1
I think you need to check whether you are actually requesting the permission. In Android the permissions are dynamic starting from the version 6.0. Either you must request it at run time or just downgrade your targetSdk version to 22.
Upvotes: 0
Reputation: 4460
Solved. now works fine!
I did
//save image
public static void imageDownload(Context ctx, String url){
Picasso.with(ctx)
.load("http://blog.concretesolutions.com.br/wp-content/uploads/2015/04/Android1.png")
.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 file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + url);
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;
}
Upvotes: 31
Reputation: 195
I can see 2 possible issues:
Upvotes: 3