效果图
遇见平江路
代码实现
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <View android:layout_width="match_parent" android:layout_height="200dp"/> <ImageView android:id="@+id/bgPhoto" android:layout_width="340dp" android:layout_height="254dp" android:layout_gravity="center" android:background="@drawable/photo"/> <Button android:id="@+id/btn" android:layout_width="100dp" android:layout_height="60dp" android:text="下载" android:layout_marginTop="20dp" android:layout_gravity="center"/> </LinearLayout>
MainActivity
package top.gaojc; import android.content.Context; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import top.gaojc.util.DownloadPhotoUtil; import top.gaojc.util.ImageUtil; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private ImageView bgPhoto;//图片控件 private Button btn;//下载按钮 private Context mContext = MainActivity.this; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bgPhoto = findViewById(R.id.bgPhoto); btn = findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, "下载至手机", Toast.LENGTH_SHORT).show(); // 调用相关工具类 DownloadPhotoUtil.requestPermission(MainActivity.this, ImageUtil.createBitmapFromView(bgPhoto)); } }); } }
DownloadPhotoUtil
package top.gaojc.util; import android.Manifest; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.MediaStore; import android.text.format.DateUtils; import android.widget.Toast; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; public class DownloadPhotoUtil { private static Activity mContext; private static final int REQUEST_CODE_SAVE_IMG = 0; /** * 请求读取sd卡的权限 */ public static void requestPermission(Activity context, Bitmap bitmap) { mContext = context; /** * 添加读写权限 * READ_EXTERNAL_STORAGE:读外部存储的权限 * WRITE_EXTERNAL_STORAGE:写外部存储的权限 */ String[] mPermissionList = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; // 判断有无读写权限 if (hasPermissions(mContext, mPermissionList)) { // 已同意 去保存 saveImage(context, bitmap); } else { // 未同意 申请权限 ActivityCompat.requestPermissions(context, mPermissionList, REQUEST_CODE_SAVE_IMG); } } // 是否有对应权限 public static boolean hasPermissions(Context context, String... perms) { // 判断sdk版本 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } for (String perm : perms) { boolean hasPerm = (ContextCompat.checkSelfPermission(context, perm) == PackageManager.PERMISSION_GRANTED); if (!hasPerm) { return false; } } return true; } // 保存图片 public static void saveImage(Context context, Bitmap bitmap) { if (bitmap == null) { return; } boolean isSaveSuccess; if (Build.VERSION.SDK_INT < 29) { isSaveSuccess = saveImageToGallery(context, bitmap); } else { isSaveSuccess = saveImageToGallery1(context, bitmap); } if (isSaveSuccess) { Toast.makeText(mContext, "保存图片成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(mContext, "保存图片失败,请稍后重试", Toast.LENGTH_SHORT).show(); } } /** * android 10 以下版本 */ public static boolean saveImageToGallery(Context context, Bitmap image) { // 首先保存图片 String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dearxy"; File appDir = new File(storePath); if (!appDir.exists()) { appDir.mkdir(); } String fileName = System.currentTimeMillis() + ".jpg"; File file = new File(appDir, fileName); try { FileOutputStream fos = new FileOutputStream(file); // 通过io流的方式来压缩保存图片 boolean isSuccess = image.compress(Bitmap.CompressFormat.JPEG, 60, fos); fos.flush(); fos.close(); // 保存图片后发送广播通知更新数据库 Uri uri = Uri.fromFile(file); mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)); if (isSuccess) { return true; } else { return false; } } catch (IOException e) { e.printStackTrace(); } return false; } /** * android 10 以上版本 */ public static boolean saveImageToGallery1(Context context, Bitmap image) { Long mImageTime = System.currentTimeMillis(); String imageDate = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(mImageTime)); String SCREENSHOT_FILE_NAME_TEMPLATE = "winetalk_%s.png";//图片名称,以"winetalk"+时间戳命名 String mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate); final ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + File.separator + "winetalk"); //Environment.DIRECTORY_SCREENSHOTS:截图,图库中显示的文件夹名。"dh" values.put(MediaStore.MediaColumns.DISPLAY_NAME, mImageFileName); values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png"); values.put(MediaStore.MediaColumns.DATE_ADDED, mImageTime / 1000); values.put(MediaStore.MediaColumns.DATE_MODIFIED, mImageTime / 1000); values.put(MediaStore.MediaColumns.DATE_EXPIRES, (mImageTime + DateUtils.DAY_IN_MILLIS) / 1000); values.put(MediaStore.MediaColumns.IS_PENDING, 1); ContentResolver resolver = context.getContentResolver(); final Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); try { // First, write the actual data for our screenshot try (OutputStream out = resolver.openOutputStream(uri)) { if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) { return false; } } // Everything went well above, publish it! values.clear(); values.put(MediaStore.MediaColumns.IS_PENDING, 0); values.putNull(MediaStore.MediaColumns.DATE_EXPIRES); resolver.update(uri, values, null, null); } catch (IOException e) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){ resolver.delete(uri, null); } return false; } return true; } }
ImageUtil
package top.gaojc.util; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.view.View; import android.widget.ImageView; public class ImageUtil { // view转bitmap public static Bitmap createBitmapFromView(View view) { //是ImageView直接获取 if (view instanceof ImageView) { Drawable drawable = ((ImageView) view).getDrawable(); if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } } view.clearFocus(); Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); if (bitmap != null) { Canvas canvas = new Canvas(bitmap); view.draw(canvas); canvas.setBitmap(null); } return bitmap; } }