(Tutorial Android) Download Image to External Storage using Picasso


Pada tutorial sebelumnya http://wimsonevel.blogspot.co.id/2016/05/tutorial-android-image-loader-using.html saya menjelaskan bagaimana penggunaan library Picasso sebagai library Image Loader yang berfungsi menampilkan gambar dari penyimpanan lokal maupun link url. Nah, pada kesempatan kali ini saya akan membagikan sedikit code agar gambar yang sudah di-load oleh Picasso bisa didownload atau disimpan di memori penyimpanan.

Langsung aja ke TKP.

Pertama buat project baru agan-agan.

Tambahkan library Picasso di build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.squareup.picasso:picasso:2.5.2'
testCompile 'junit:junit:4.12'
}
Kedua buat layout dengan activity_main.xml dengan komponen Image View dan Button.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="id.co.blogspot.wimsonevel.android_picassodownload.MainActivity">

<ImageView
android:id="@+id/iv_image"
android:layout_width="300dp"
android:layout_height="400dp"
android:layout_gravity="center"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_above="@+id/btn_save"
tools:ignore="ContentDescription" />

<Button
android:id="@+id/btn_save"
android:text="@string/save_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />

</RelativeLayout>

Kemudian beberapa resouce lainnya berikut :

colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#b94948</color>
<color name="colorPrimaryDark">#b94948</color>
<color name="colorAccent">#FF4081</color>
</resources>
strings.xml
<resources>
<string name="app_name">Android-PicassoDownload</string>

<string name="save_image">Save Image</string>

</resources>

Picasso Target
Picasso menyediakan sebuat interface Target yang menyediakan callback bitmap sehingga kita dapat memanfaatkan bitmap dari image untuk diproses lebih lanjut.

Contoh penggunaannya :
Picasso.with(this)
.load(url)
.into(new Target() {
@Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {

}

@Override
public void onBitmapFailed(Drawable errorDrawable) {

}

@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
Hasil bitmap lalu kita proses untuk dijadikan sebuah file image ber-ekstensi jpg. Kemudian disimpan di direktori folder memori eksternal yang kita inginkan. Contohnya saya menyimpan file image di folder Pictures.
File sd = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File folder = new File(sd, "/PicassoDownload/");
if (!folder.exists()) {
if (!folder.mkdir()) {
Log.e("ERROR", "Cannot create a directory!");
} else {
folder.mkdir();
}
}
File fileName = new File(folder, imgName);
try {
fileName.createNewFile();
FileOutputStream ostream = new FileOutputStream(fileName);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
Buat activity dengan nama MainActivity.java, implementasikan code di atas di dalamnya ketika tombol save diklik. Untuk memodifikasi baik itu membaca maupun menulis file di memori eksternal kita memerlukan permission, di Android versi M ke atas perlu adanya pengecekan permission secara runtime.

Berikut list kode lengkapnya.
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;

import java.io.File;
import java.io.FileOutputStream;

public class MainActivity extends AppCompatActivity {

private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 100;
private static final String PREF_CAMERA_REQUESTED = "cameraRequested";

private String url;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ImageView ivImage= (ImageView) findViewById(R.id.iv_image);
Button btnSave = (Button) findViewById(R.id.btn_save);

url = "https://scontent-sit4-1.xx.fbcdn.net/v/t1.0-9/20228885_1440264296060520_6773935769024601349_n.jpg?oh=da445041a4bc99ec499b78d39b8832eb&oe=5A371E89";

Picasso.with(this)
.load(url)
.into(ivImage);

btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
saveImage(url, "newfile.jpg");
}
});
}

private void saveImage(String url, final String imgName) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "In progress...", Toast.LENGTH_SHORT).show();

Picasso.with(this)
.load(url)
.into(new Target() {
@Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
File sd = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File folder = new File(sd, "/PicassoDownload/");
if (!folder.exists()) {
if (!folder.mkdir()) {
Log.e("ERROR", "Cannot create a directory!");
} else {
folder.mkdir();
}
}

File fileName = new File(folder, imgName);

try {
fileName.createNewFile();
FileOutputStream ostream = new FileOutputStream(fileName);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}

Toast.makeText(MainActivity.this, "Image Saved Successfully!", Toast.LENGTH_SHORT).show();
}

@Override
public void onBitmapFailed(Drawable errorDrawable) {
Toast.makeText(MainActivity.this, "Image Failed to Save", Toast.LENGTH_SHORT).show();
}

@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {

}
});
} else {
requestWriteExternalPermission();
}
}

private void requestWriteExternalPermission() {
final String[] permissions = new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE};

if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {
if (!isPermissionRequested(PREF_CAMERA_REQUESTED)) {
ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
setPermissionRequested(PREF_CAMERA_REQUESTED);
} else {
Toast.makeText(MainActivity.this, "Please grant storage permission to save images", Toast.LENGTH_SHORT).show();
}
}
}

private void setPermissionRequested(String permission) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean(permission, true);
editor.apply();
}

private boolean isPermissionRequested(String permission) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
return preferences.getBoolean(permission, false);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

switch (requestCode) {
case PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE: {
if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d("SUCCESS", "Write External permission granted");
saveImage(url, "newFile.jpg");
return;
}
Log.e("ERROR", "Permission not granted: results len = " + grantResults.length +
" Result code = " + (grantResults.length > 0 ? grantResults[0] : "(empty)"));
finish();
}
default: {
Log.d("ERROR", "Got unexpected permission result: " + requestCode);
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
}
}
Terakhir tambahkan permission di AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="id.co.blogspot.wimsonevel.android_picassodownload">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Build dan jalankan maka hasilnya sebagai berikut :


Klik “Save Image” maka image akan tersimpan di folder Pictures->PicassoDownload

Source code lengkap dapat dilihat di https://github.com/wimsonevel/Android-PicassoDownload

Sekian tutorial kali ini dan semoga bermanfaat.
Jangan lupa share ke sosial media kalian ^^

Berlangganan update artikel terbaru via email: