(Tutorial Android) Download Image to External Storage using Picasso

Saturday, July 29, 2017

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 ^^

Share this :

Previous
Next Post »
3 Komentar
avatar

gan.. ada contoh listview yang diambil dari database mysql ga ? contohnya nampilin gambar ikan nama ikan, jenis ikan dll (dalam bentuk listview)

Balas
avatar

blm ada gan, kalo mau ntr sy buat tutorialnya..
request aja di sini http://wimsonevel.blogspot.co.id/2017/07/request-tutorial.html

Balas

Penulisan markup di komentar
  • Silakan tinggalkan komentar sesuai topik. Komentar yang menyertakan link aktif, iklan, atau sejenisnya akan dihapus.
  • Untuk menyisipkan kode gunakan <i rel="code"> kode yang akan disisipkan </i>
  • Untuk menyisipkan kode panjang gunakan <i rel="pre"> kode yang akan disisipkan </i>
  • Untuk menyisipkan quote gunakan <i rel="quote"> catatan anda </i>
  • Untuk menyisipkan gambar gunakan <i rel="image"> URL gambar </i>
  • Untuk menyisipkan video gunakan [iframe] URL embed video [/iframe]
  • Kemudian parse kode tersebut pada kotak di bawah ini
  • © 2015 Simple SEO ✔