1. import android.content.Context;
  2. import android.content.Intent;
  3. import android.database.Cursor;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Canvas;
  7. import android.graphics.Matrix;
  8. import android.graphics.Paint;
  9. import android.graphics.Rect;
  10. import android.media.MediaScannerConnection;
  11. import android.net.Uri;
  12. import android.os.Environment;
  13. import android.provider.MediaStore;
  14. import android.view.View;
  15.  
  16. public class PictureUtils {
  17.  
  18. private static String TAG = PictureUtils.class.getSimpleName();
  19.  
  20. private static int CODE_WIDTH = 60;
  21. private static int CODE_HEIGHT = 60;
  22.  
  23. private PictureUtils() {
  24.  
  25. }
  26.  
  27. /**
  28. * 保存一张或者多张图片到图库
  29. */
  30. public static void saveImageListToGallery(final BaseActivity context,
  31. final List<String> imgList, final OnSaveImgCallBack callBack) {
  32.  
  33. if (context == null) {
  34. LogUtils.dTag(TAG, "context 不能为null");
  35. return;
  36. }
  37.  
  38. RxPermissionsUtils.getInstance()
  39. .requestPermission(context, RxPermissionsUtils.READ_AND_WRITE_PERMISSION,
  40. new RxPermissionsUtils.OnPermissionRequestCallBack() {
  41. @Override
  42. public void onSuccess() {
  43. if (imgList == null) {
  44. LogUtils.dTag(TAG, "图片数组为 null");
  45. return;
  46. }
  47.  
  48. // 保存图片到图库
  49. saveImageListToGalleryPrivate(context, imgList, callBack);
  50.  
  51. }
  52.  
  53. @Override
  54. public void onFail() {
  55. ToastUtils.showShort("请在设置授予应用存储权限^_^");
  56. PermissionUtils.launchAppDetailsSettings();
  57. }
  58. });
  59.  
  60. }
  61.  
  62. /**
  63. * 保存多张图片
  64. */
  65. private static void saveImageListToGalleryPrivate(BaseActivity context, List<String> imgList,
  66. final OnSaveImgCallBack callBack) {
  67.  
  68. Observable.just(imgList)
  69. .observeOn(Schedulers.io())
  70. .flatMap(new Function<List<String>, ObservableSource<Boolean>>() {
  71. @Override
  72. public ObservableSource<Boolean> apply(List<String> strings) throws Exception {
  73.  
  74. for (String filePath : strings) {
  75.  
  76. if (filePath.startsWith("http://") || filePath.startsWith("https://")) {
  77.  
  78. Bitmap bmp = Glide.with(BaseApplication.getInstance())
  79. .asBitmap()
  80. .load(filePath)
  81. .submit()
  82. .get();
  83.  
  84. saveImageToGallery(BaseApplication.getInstance(), bmp, filePath);
  85.  
  86. } else {
  87.  
  88. Bitmap bmp = BitmapFactory.decodeFile(filePath);
  89.  
  90. saveImageToGallery(BaseApplication.getInstance(), bmp, filePath);
  91. }
  92.  
  93. }
  94.  
  95. return Observable.just(true);
  96. }
  97. })
  98. .observeOn(AndroidSchedulers.mainThread())
  99. .subscribe(new Observer<Boolean>() {
  100. Disposable mD;
  101.  
  102. @Override
  103. public void onSubscribe(Disposable d) {
  104. mD = d;
  105. if (callBack != null) {
  106. callBack.onSaveStart();
  107. }
  108. }
  109.  
  110. @Override
  111. public void onNext(Boolean aBoolean) {
  112. ToastUtils.showShort("图片已成功保存到系统相册^_^");
  113. if (callBack != null) {
  114. callBack.onSaveSuccess();
  115. }
  116. }
  117.  
  118. @Override
  119. public void onError(Throwable e) {
  120. if (mD != null) {
  121. mD.dispose();
  122. }
  123. if (callBack != null) {
  124. callBack.onSaveFail();
  125. }
  126. }
  127.  
  128. @Override
  129. public void onComplete() {
  130. if (mD != null) {
  131. mD.dispose();
  132. }
  133. }
  134. });
  135.  
  136. }
  137.  
  138. /**
  139. * 保存 Bitmap 到相册 获得路径
  140. */
  141. public static String saveImageToGallery(Context context, Bitmap bmp, String imageUrl) {
  142.  
  143. if (!SDCardUtils.isSDCardEnableByEnvironment()) {
  144. LogUtils.dTag(TAG, "内存卡不可用");
  145. return null;
  146. }
  147.  
  148. // 首先保存图片
  149. File appDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),
  150. NetWorkConstants.FileKey.COMMONLIB_SHARE_CODE_DIR_NAME);// 获取文件存储路径
  151.  
  152. if (!appDir.exists()) {
  153. boolean isCreate = appDir.mkdir();
  154. if (!isCreate) {
  155. return null;
  156. }
  157. }
  158.  
  159. // 创建文件 截取,取出名字
  160. String url_truncated = String.valueOf(System.currentTimeMillis());
  161. String fileName = "mryt_share_code" + "_" + url_truncated;
  162. File file = new File(appDir, fileName);
  163. FileUtils.deleteFile(file);
  164. if (FileUtils.isFileExists(file)) {
  165. LogUtils.dTag(TAG, file.getAbsolutePath());
  166. return file.getAbsolutePath();
  167. }
  168. try {
  169. FileOutputStream fos = new FileOutputStream(file);
  170. bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
  171. fos.flush();
  172. fos.close();
  173. // 插入图库
  174. /**MediaStore.Images.Media
  175. .insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName,
  176. String.valueOf(System.currentTimeMillis()));*/
  177. } catch (FileNotFoundException e) {
  178. e.printStackTrace();
  179. } catch (IOException e) {
  180. e.printStackTrace();
  181. }
  182. // 最后通知图库更新
  183.  
  184. /**MediaScannerConnection.scanFile(context, new String[]{file.getAbsolutePath()}, null,
  185. new MediaScannerConnection.OnScanCompletedListener() {
  186. @Override
  187. public void onScanCompleted(String path, Uri uri) {
  188.  
  189. }
  190. });*/
  191. try {
  192. savePhotoToMedia(context, file, fileName);
  193. } catch (FileNotFoundException e) {
  194. e.printStackTrace();
  195. }
  196. return file.getAbsolutePath();
  197. }
  198.  
  199. /**
  200. * 保存 Bitmap 到相册 获得路径 不传递文件名称 用时间后缀
  201. */
  202. public static String saveImageToGallery(Context context, Bitmap bmp) {
  203. // 首先保存图片
  204. File appDir = context.getExternalFilesDir(
  205. NetWorkConstants.FileKey.COMMONLIB_SHARE_CODE_DIR_NAME);// 获取文件存储路径
  206. if (appDir != null && !appDir.exists()) {
  207. boolean isCreate = appDir.mkdir();
  208. if (!isCreate) {
  209. return null;
  210. }
  211. }
  212. if (!SDCardUtils.isSDCardEnableByEnvironment()) {
  213. LogUtils.dTag(TAG, "内存卡不可用");
  214. return null;
  215. }
  216.  
  217. // 创建文件 截取,取出名字
  218. String url_truncated = String.valueOf(System.currentTimeMillis());
  219. String fileName = "mryt_share_code" + "_" + url_truncated;
  220. File file = new File(appDir, fileName);
  221. if (FileUtils.isFileExists(file)) {
  222. LogUtils.dTag(TAG, file.getAbsolutePath());
  223. return file.getAbsolutePath();
  224. }
  225. try {
  226. FileOutputStream fos = new FileOutputStream(file);
  227. bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
  228. fos.flush();
  229. fos.close();
  230. // 插入图库
  231. /**MediaStore.Images.Media
  232. .insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName,
  233. String.valueOf(System.currentTimeMillis()));*/
  234. } catch (FileNotFoundException e) {
  235. e.printStackTrace();
  236. } catch (IOException e) {
  237. e.printStackTrace();
  238. }
  239. // 最后通知图库更新
  240. // context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
  241. /**MediaScannerConnection.scanFile(context, new String[]{file.getAbsolutePath()}, null,
  242. new MediaScannerConnection.OnScanCompletedListener() {
  243. @Override public void onScanCompleted(String path, Uri uri) {
  244. }
  245. });*/
  246.  
  247. try {
  248. savePhotoToMedia(context, file, fileName);
  249. ToastUtils.showShort("图片已成功保存到相册");
  250. } catch (FileNotFoundException e) {
  251. e.printStackTrace();
  252. ToastUtils.showShort("图片保存失败");
  253. }
  254. return file.getAbsolutePath();
  255. }
  256.  
  257. public static Bitmap getBitmapFromView(Context context, View view) {
  258. view.setDrawingCacheEnabled(true);
  259. //启用DrawingCache并创建位图
  260. view.buildDrawingCache();
  261. //创建一个DrawingCache的拷贝,因为DrawingCache得到的位图在禁用后会被回收
  262. Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
  263. //禁用DrawingCahce否则会影响性能
  264. view.setDrawingCacheEnabled(false);
  265. return bitmap;
  266. }
  267.  
  268. //图片上绘制文字
  269. public static Bitmap drawTextToBitmap(Bitmap bitmap, String text,
  270. Paint paint, Rect bounds, int paddingLeft, int paddingTop) {
  271. android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
  272.  
  273. paint.setDither(true); // 获取跟清晰的图像采样
  274. paint.setFilterBitmap(true);// 过滤一些
  275. if (bitmapConfig == null) {
  276. bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
  277. }
  278. bitmap = bitmap.copy(bitmapConfig, true);
  279. Canvas canvas = new Canvas(bitmap);
  280. canvas.drawText(text, paddingLeft, paddingTop, paint);
  281. return bitmap;
  282. }
  283.  
  284. public static Bitmap setImgSize(Bitmap bm, int newWidth, int newHeight) {
  285. // 获得图片的宽高.
  286. int width = bm.getWidth();
  287. int height = bm.getHeight();
  288. // 计算缩放比例.
  289. float scaleWidth = ((float) newWidth) / width;
  290. float scaleHeight = ((float) newHeight) / height;
  291. // 取得想要缩放的matrix参数.
  292. Matrix matrix = new Matrix();
  293. matrix.postScale(scaleWidth, scaleHeight);
  294. // 得到新的图片.
  295. return Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
  296. }
  297.  
  298. // 保存图片的回调
  299. public interface OnSaveImgCallBack {
  300.  
  301. void onSaveStart();
  302.  
  303. void onSaveSuccess();
  304.  
  305. void onSaveFail();
  306. }
  307.  
  308. public static void savePhotoToMedia(Context context, File file, String fileName)
  309. throws FileNotFoundException {
  310. String uriString = MediaStore.Images.Media
  311. .insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
  312. // String uriString = MediaStore.Images.Media.insertImage(context.getContentResolver(), bitmap, null, null);
  313. File file1 = new File(getRealPathFromURI(Uri.parse(uriString), context));
  314. updatePhotoMedia(file1, context);
  315. }
  316.  
  317. //更新图库
  318. private static void updatePhotoMedia(File file, Context context) {
  319. Intent intent = new Intent();
  320. intent.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
  321. intent.setData(Uri.fromFile(file));
  322. context.sendBroadcast(intent);
  323. }
  324.  
  325. //得到绝对地址
  326. private static String getRealPathFromURI(Uri contentUri, Context context) {
  327. String[] proj = {MediaStore.Images.Media.DATA};
  328. Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
  329. if (cursor == null) {
  330. return "";
  331. }
  332. int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
  333. cursor.moveToFirst();
  334. String fileStr = cursor.getString(column_index);
  335. cursor.close();
  336. return fileStr;
  337. }
  338. }

Android--解决图片保存到相册显示1970年1月1日 8:00的问题的更多相关文章

  1. 1970年1月1日(00:00:00 GMT)Unix 时间戳(Unix Timestamp)

    转载自(http://jm.ncxyol.com/post-88.html) 今天在看Python   API时,看到time模块: The epoch is the point where the ...

  2. Android将图片保存到相册并及时看到

    Android中将图片保存到SD卡中,相册里不会及时出现这张图片,因为没有及时更新其索引,一般需要开机几次.当然我们可以手动更新其索引. 1,首先将文件保存到SD卡中. String filePath ...

  3. [RN] React Native 图片保存到相册(支持 Android 和 ios)

    React Native 图片保存到相册(支持 Android 和 ios) 原理: IOS用 RN自带的 CameraRoll, Android 使用 不成功,需要 react-native-fs  ...

  4. 小程序图片保存的相册授权失败问题,原接口wx.openSeting()已经废弃了的解决办法

    项目中使用的是wepy框架开发的小程序,,, 使用场景是,用户点击下载图片的时候,要调起授权button(小程序拉起授权的功能都集成在了button组件,所以这里需要用到button组件里的一个ope ...

  5. java为啥计算时间从1970年1月1日开始

    http://www.myexception.cn/program/1494616.html ————————————————————————————————————————————————————— ...

  6. Java 获取各时区时间,获取当前时间到格林威治时间1970年01月01日00时00分00秒的秒数

    格林威治时间即UTC/GMT时间,1970年01月01日00时00分00秒(即UTC+8的北京时间1970年01月01日08时00分00秒)计算代码如下: /** * 获取指定时间到格林威治时间的秒数 ...

  7. 从1970年1月1日00:00:00 GMT以来此时间对象表示的毫秒数转化为Datetime

    1970年1月1日(00:00:00 GMT)Unix 时间戳(Unix Timestamp)对时间转换 将Long类型转换为DateTime类型 /// <summary> /// 将L ...

  8. 格林治时间,也就是返回从 UTC 1970 年 1 月 1 日午夜开始经过的毫秒数。

    格林治时间,也就是返回从 UTC 1970 年 1 月 1 日午夜开始经过的毫秒数. (* Delphi获取13位格林治时间实现方法, 与java中的java.lang.System.currentT ...

  9. DedeCMS文章编辑不更新时间1970年1月1日

    在修改文章或者后期优化的时候,织梦dedecms5.7版本存在一个问题,修改文章的同时也修改了文章的发布时间,这个功能可能有些人比较需要,但同时也有些站长朋友又不需要,因为我们编辑某个文章的时候,发现 ...

随机推荐

  1. ansible基础-加密

    一 简介 注:本文demo使用ansible2.7稳定版 众所周知,ansible是很火的一个自动化部署工具,在ansible控制节点内,存放着当前环境服务的所有服务的配置信息,其中自然也包括一些敏感 ...

  2. [Swift]LeetCode61. 旋转链表 | Rotate List

    Given a linked list, rotate the list to the right by k places, where k is non-negative. Example 1: I ...

  3. [Swift]LeetCode381. O(1) 时间插入、删除和获取随机元素 - 允许重复 | Insert Delete GetRandom O(1) - Duplicates allowed

    Design a data structure that supports all following operations in averageO(1) time. Note: Duplicate ...

  4. [Swift]LeetCode404. 左叶子之和 | Sum of Left Leaves

    Find the sum of all left leaves in a given binary tree. Example: 3 / \ 9 20 / \ 15 7 There are two l ...

  5. 【Spark篇】---Spark中Master-HA和historyServer的搭建和应用

    一.前述 本节讲述Spark Master的HA的搭建,为的是防止单点故障. Spark-UI 的使用介绍,可以更好的监控Spark应用程序的执行. 二.具体细节 1.Master HA 1.Mast ...

  6. Python内置函数(3)——any

    英文文档: any(iterable) Return True if any element of the iterable is true. If the iterable is empty, re ...

  7. ElasticSearch(1)---Mysql同步数据到ElSearch

    ElasticSearch同步Mysql 先讲项目需求:对于资讯模块添加搜索功能 这个搜索功能我就是采用ElasticSearch实现的,功能刚实现完,所以写这篇博客做个记录,让自己在记录下整个步骤和 ...

  8. mybatis框架(6)---mybatis插入数据后获取自增主键

    mybatis插入数据后获取自增主键 首先理解这就话的意思:就是在往数据库表中插入一条数据的同时,返回该条数据在数据库表中的自增主键值. 有什么用呢,举个例子: 你编辑一条新闻,同时需要给该新闻打上标 ...

  9. I-think-3

    一段很有哲理的话,与大家分享一下: 时光匆匆, 有些东西很重要,有些东西不重要, 有些东西已经不再重要,有些东西还是很重要. 宏观地看待人生,大学文凭只是一种达到目标的途径,而并非是唯一. 主要坚定自 ...

  10. 《连连看》算法c语言演示(自动连连看)

    (图片是游戏的示意图,来自互联网,与本文程序无关) 看题目就知道是写给初学者的,没需要的就别看了,自己都觉得怪无聊的. 很多游戏的耐玩性都来自精巧的算法,特别是人工智能的水平.比如前几天看了著名的Al ...