Ví dụ này minh họa cách ghi file ảnh vào bộ nhớ ngoài (external storage) với quyền runtime (cấp quyền lúc chạy) trên Android.
Bước 1: Tạo dự án mới
Tạo dự án mới trong Android Studio: File → New Project, điền thông tin cần thiết.
Bước 2: Thiết kế giao diện (res/layout/activity_main.xml)
<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "https://schemas.android.com/apk/res/android"
xmlns:tools = "https://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity"
android:orientation = "vertical">
<Button
android:id = "@+id/save"
android:text = "Lưu"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content" />
</LinearLayout>
Giao diện chỉ có một nút. Khi nhấn nút, ảnh sẽ được lưu vào bộ nhớ ngoài.
Bước 3: Code MainActivity.java
package com.example.andy.myapplication;
import android.annotation.TargetApi;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 100;
Button save;
Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Drawable drawable = getResources().getDrawable(R.drawable.mario);
bitmap = ((BitmapDrawable) drawable).getBitmap();
save = findViewById(R.id.save);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
if (Build.VERSION.SDK_INT >= 23) { // Android 6.0+
if (checkPermission()) {
saveImageToExternalStorage();
} else {
requestPermission(); // Yêu cầu cấp quyền
}
} else {
// Android dưới 6.0 không cần runtime permission
saveImageToExternalStorage();
}
}
}
});
}
private void saveImageToExternalStorage() {
String path = Environment.getExternalStorageDirectory().toString();
File file = new File(path, "UniqueFileName" + ".jpg");
if (!file.exists()) {
Log.d("path", file.toString());
try {
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
Toast.makeText(this, "Đã lưu ảnh vào bộ nhớ ngoài", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(MainActivity.this, "Quyền ghi bộ nhớ ngoài cho phép lưu file. Vui lòng cấp quyền trong Cài đặt.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("value", "Đã cấp quyền, giờ có thể sử dụng bộ nhớ ngoài.");
saveImageToExternalStorage();
} else {
Log.e("value", "Quyền bị từ chối, không thể sử dụng bộ nhớ ngoài.");
}
break;
}
}
}
Bước 4: Cấu hình AndroidManifest.xml
<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "https://schemas.android.com/apk/res/android"
package = "com.example.andy.myapplication">
<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:roundIcon = "@mipmap/ic_launcher_round"
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>
Chạy ứng dụng
Kết nối thiết bị, chạy từ Android Studio. Màn hình hiển thị giao diện mặc định.

Nhấn nút Lưu để lưu ảnh vào bộ nhớ ngoài như hình dưới:
