这也不是特别大的功能,只要多注意一点细节即可
注意需要在 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();
}
}
}