Android 使用RxJava保存图片到本地、并刷新本地图库

这也不是特别大的功能,只要多注意一点细节即可

注意需要在  AndroidManifest.xml 申请权限,

Android 6.0 开始也开始动态权限 ,我这是使用 EasyPermissions 来申请权限的 这个只给做一个参考。

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

 长按图片弹框、以下代码的实现:

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setItems(new String[]{"保存到手机"}, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            if (EasyPermissions.hasPermissions(PreviewImageActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE)) {
                // Have permission, do the thing!
                ImageUtils.saveImageToLocal(PreviewImageActivity.this,
                        imagePath,
                        PreviewImageActivity.this);
            } else {
                // Request one permission
                EasyPermissions.requestPermissions(PreviewImageActivity.this,
                        "请允许APP申请的应用权限,否则可能会影响部分功能的使用!",
                        Constants.RC_WRITE_READ_STORAGE_PERM,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE);
            }
        }
    });
    builder.show();

ImageUtils 下的方法

    /**
     * 保存图片到本地
     *
     * @param context
     * @param imagePath
     */
    public static void saveImageToLocal(final Context context, final String imagePath){
        Flowable.create(new FlowableOnSubscribe<File>() {
            @Override
            public void subscribe(FlowableEmitter<File> e) throws Exception {
                e.onNext(GlideApp.with(context).asFile()
                        .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
                        .load(imagePath)
                        .downloadOnly(Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL)
                        .get());
                e.onComplete();
            }
        },BackpressureStrategy.BUFFER)
                .subscribeOn(io.reactivex.schedulers.Schedulers.io())
                .observeOn(io.reactivex.schedulers.Schedulers.newThread())
                .subscribe(new Consumer<File>() {
                    @Override
                    public void accept(File file) {
                        try{
                            //系统相册目录
                            File appDir = new File(Environment.getExternalStorageDirectory()
                                    + File.separator + Environment.DIRECTORY_DCIM
                                    +File.separator+"Camera"+File.separator);
                            if (!appDir.exists()) {
                                appDir.mkdirs();
                            }
                            String fileName = System.currentTimeMillis() + ".jpg";
                            File destFile = new File(appDir, fileName);
                            //把gilde下载得到图片复制到定义好的目录中去
                            if (FileUtils.copyFile(file, destFile)){
                                //插入刷新本地图库
                                ContentValues values = new ContentValues(2);
                                values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
                                values.put(MediaStore.Images.Media.DATA, destFile.getAbsolutePath());
                                context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                                Looper.prepare();
                                ToastUtil.showShortToast(context,"保存成功");
                                Looper.loop();
                            }else {
                                Looper.prepare();
                                ToastUtil.showShortToast(context,"保存失败");
                                Looper.loop();
                            }
                        }catch (Exception e){
                            Looper.prepare();
                            ToastUtil.showShortToast(context,"保存失败");
                            Looper.loop();
                        }
                    }
                });
    }

public class FileUtils {

    /**
     * 复制文件
     *
     * @param srcFile  源文件
     * @param destFile 目标文件
     * @return {@code true}: 复制成功<br>{@code false}: 复制失败
     */
    public static boolean copyFile(File srcFile, File destFile) {
        return copyOrMoveFile(srcFile, destFile, false);
    }

    /**
     * 复制或移动文件
     *
     * @param srcFile  源文件
     * @param destFile 目标文件
     * @param isMove   是否移动
     * @return {@code true}: 复制或移动成功<br>{@code false}: 复制或移动失败
     */
    private static boolean copyOrMoveFile(File srcFile, File destFile, boolean isMove) {
        if (srcFile == null || destFile == null) return false;
        // 源文件不存在或者不是文件则返回false
        if (!srcFile.exists() || !srcFile.isFile()) return false;
        // 目标文件存在且是文件则返回false
        if (destFile.exists() && destFile.isFile()) return false;
        // 目标目录不存在返回false
        if (!createOrExistsDir(destFile.getParentFile())) return false;
        try {
            return writeFileFromIS(destFile, new FileInputStream(srcFile), false)
                    && !(isMove && !deleteFile(srcFile));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除文件
     *
     * @param file 文件
     * @return {@code true}: 删除成功<br>{@code false}: 删除失败
     */
    public static boolean deleteFile(File file) {
        return file != null && (!file.exists() || file.isFile() && file.delete());
    }


    /**
     * 判断目录是否存在,不存在则判断是否创建成功
     *
     * @param file 文件
     * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
     */
    public static boolean createOrExistsDir(File file) {
        // 如果存在,是目录则返回true,是文件则返回false,不存在则返回是否创建成功
        return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
    }

    /**
     * 将输入流写入文件
     *
     * @param file   文件
     * @param is     输入流
     * @param append 是否追加在文件末
     * @return {@code true}: 写入成功<br>{@code false}: 写入失败
     */
    public static boolean writeFileFromIS(File file, InputStream is, boolean append) {
        if (file == null || is == null) return false;
        if (!createOrExistsFile(file)) return false;
        OutputStream os = null;
        try {
            os = new BufferedOutputStream(new FileOutputStream(file, append));
            byte data[] = new byte[1024];
            int len;
            while ((len = is.read(data, 0, 1024)) != -1) {
                os.write(data, 0, len);
            }
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            closeIO(is, os);
        }
    }

    /**
     * 判断文件是否存在,不存在则判断是否创建成功
     *
     * @param file 文件
     * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
     */
    public static boolean createOrExistsFile(File file) {
        if (file == null) return false;
        // 如果存在,是文件则返回true,是目录则返回false
        if (file.exists()) return file.isFile();
        if (!createOrExistsDir(file.getParentFile())) return false;
        try {
            return file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 关闭IO
     *
     * @param closeables closeable
     */
    public static void closeIO(Closeable... closeables) {
        if (closeables == null) return;
        try {
            for (Closeable closeable : closeables) {
                if (closeable != null) {
                    closeable.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WL-鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值