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

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

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

        

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

    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() {            @Override            public void subscribe(FlowableEmitter 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() {                    @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}: 复制成功
{@code false}: 复制失败 */ public static boolean copyFile(File srcFile, File destFile) { return copyOrMoveFile(srcFile, destFile, false); } /** * 复制或移动文件 * * @param srcFile 源文件 * @param destFile 目标文件 * @param isMove 是否移动 * @return {@code true}: 复制或移动成功
{@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}: 删除成功
{@code false}: 删除失败 */ public static boolean deleteFile(File file) { return file != null && (!file.exists() || file.isFile() && file.delete()); } /** * 判断目录是否存在,不存在则判断是否创建成功 * * @param file 文件 * @return {@code true}: 存在或创建成功
{@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}: 写入成功
{@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}: 存在或创建成功
{@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(); } }}

 

更多相关文章

  1. Google继Project Treble后的大动作:Android(安卓)Q系统组件更新机
  2. Android(安卓)Studio的使用小贴士
  3. ndk初体验
  4. android JNI学习之一
  5. xml文件内引用资源
  6. Android(安卓)Studio打包时如何将版本号修改成apk名字
  7. Android(安卓)Studio 移动项目到新文件夹,Installation failed wi
  8. Android中SimpleAdapter,ArrayAdapter和BaseAdapter详解
  9. Android(安卓)- 预装(push) lib64中so文件查找错误

随机推荐

  1. Android(安卓)属性系统 Property service
  2. Android(安卓)广播接收器注册与注销源码
  3. [原]Android应用程序消息处理机制(Looper
  4. Android(安卓)图像绘制之 Drawable(二)
  5. android wifi 连接笔记
  6. Android插件开发初探——分析篇
  7. ANDROID: 设置显示窗口的SIZE和DENSITY
  8. Android在MediaMuxer和MediaCodec录制视
  9. Android(安卓)Studio 单元测试
  10. Activity的launchMode相关