Android--解決圖片保存到相冊顯示1970年1月1日 8:00的問題

来源:https://www.cnblogs.com/819158327fan/archive/2018/11/07/9925624.html
-Advertisement-
Play Games

import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics... ...


import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;


public class PictureUtils {

    private static String TAG = PictureUtils.class.getSimpleName();

    private static int CODE_WIDTH = 60;
    private static int CODE_HEIGHT = 60;

    private PictureUtils() {

    }

    /**
     * 保存一張或者多張圖片到圖庫
     */
    public static void saveImageListToGallery(final BaseActivity context,
            final List<String> imgList, final OnSaveImgCallBack callBack) {

        if (context == null) {
            LogUtils.dTag(TAG, "context 不能為null");
            return;
        }

        RxPermissionsUtils.getInstance()
                .requestPermission(context, RxPermissionsUtils.READ_AND_WRITE_PERMISSION,
                        new RxPermissionsUtils.OnPermissionRequestCallBack() {
                            @Override
                            public void onSuccess() {
                                if (imgList == null) {
                                    LogUtils.dTag(TAG, "圖片數組為 null");
                                    return;
                                }

                                // 保存圖片到圖庫
                                saveImageListToGalleryPrivate(context, imgList, callBack);

                            }

                            @Override
                            public void onFail() {
                                ToastUtils.showShort("請在設置授予應用存儲許可權^_^");
                                PermissionUtils.launchAppDetailsSettings();
                            }
                        });

    }

    /**
     * 保存多張圖片
     */
    private static void saveImageListToGalleryPrivate(BaseActivity context, List<String> imgList,
            final OnSaveImgCallBack callBack) {

        Observable.just(imgList)
                .observeOn(Schedulers.io())
                .flatMap(new Function<List<String>, ObservableSource<Boolean>>() {
                    @Override
                    public ObservableSource<Boolean> apply(List<String> strings) throws Exception {

                        for (String filePath : strings) {

                            if (filePath.startsWith("http://") || filePath.startsWith("https://")) {

                                Bitmap bmp = Glide.with(BaseApplication.getInstance())
                                        .asBitmap()
                                        .load(filePath)
                                        .submit()
                                        .get();

                                saveImageToGallery(BaseApplication.getInstance(), bmp, filePath);

                            } else {

                                Bitmap bmp = BitmapFactory.decodeFile(filePath);

                                saveImageToGallery(BaseApplication.getInstance(), bmp, filePath);
                            }

                        }

                        return Observable.just(true);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Boolean>() {
                    Disposable mD;

                    @Override
                    public void onSubscribe(Disposable d) {
                        mD = d;
                        if (callBack != null) {
                            callBack.onSaveStart();
                        }
                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        ToastUtils.showShort("圖片已成功保存到系統相冊^_^");
                        if (callBack != null) {
                            callBack.onSaveSuccess();
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        if (mD != null) {
                            mD.dispose();
                        }
                        if (callBack != null) {
                            callBack.onSaveFail();
                        }
                    }

                    @Override
                    public void onComplete() {
                        if (mD != null) {
                            mD.dispose();
                        }
                    }
                });


    }

    /**
     * 保存 Bitmap 到相冊 獲得路徑
     */
    public static String saveImageToGallery(Context context, Bitmap bmp, String imageUrl) {

        if (!SDCardUtils.isSDCardEnableByEnvironment()) {
            LogUtils.dTag(TAG, "記憶體卡不可用");
            return null;
        }

        // 首先保存圖片
        File appDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),
                NetWorkConstants.FileKey.COMMONLIB_SHARE_CODE_DIR_NAME);// 獲取文件存儲路徑

        if (!appDir.exists()) {
            boolean isCreate = appDir.mkdir();
            if (!isCreate) {
                return null;
            }
        }

        // 創建文件 截取,取出名字
        String url_truncated = String.valueOf(System.currentTimeMillis());
        String fileName = "mryt_share_code" + "_" + url_truncated;
        File file = new File(appDir, fileName);
        FileUtils.deleteFile(file);
        if (FileUtils.isFileExists(file)) {
            LogUtils.dTag(TAG, file.getAbsolutePath());
            return file.getAbsolutePath();
        }
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
            // 插入圖庫
            /**MediaStore.Images.Media
                    .insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName,
                            String.valueOf(System.currentTimeMillis()));*/
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 最後通知圖庫更新

        /**MediaScannerConnection.scanFile(context, new String[]{file.getAbsolutePath()}, null,
                new MediaScannerConnection.OnScanCompletedListener() {
                    @Override
                    public void onScanCompleted(String path, Uri uri) {

                    }
                });*/
        try {
            savePhotoToMedia(context, file, fileName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return file.getAbsolutePath();
    }

    /**
     * 保存 Bitmap 到相冊 獲得路徑 不傳遞文件名稱 用時間尾碼
     */
    public static String saveImageToGallery(Context context, Bitmap bmp) {
        // 首先保存圖片
        File appDir = context.getExternalFilesDir(
                NetWorkConstants.FileKey.COMMONLIB_SHARE_CODE_DIR_NAME);// 獲取文件存儲路徑
        if (appDir != null && !appDir.exists()) {
            boolean isCreate = appDir.mkdir();
            if (!isCreate) {
                return null;
            }
        }
        if (!SDCardUtils.isSDCardEnableByEnvironment()) {
            LogUtils.dTag(TAG, "記憶體卡不可用");
            return null;
        }

        // 創建文件 截取,取出名字
        String url_truncated = String.valueOf(System.currentTimeMillis());
        String fileName = "mryt_share_code" + "_" + url_truncated;
        File file = new File(appDir, fileName);
        if (FileUtils.isFileExists(file)) {
            LogUtils.dTag(TAG, file.getAbsolutePath());
            return file.getAbsolutePath();
        }
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
            // 插入圖庫
            /**MediaStore.Images.Media
             .insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName,
             String.valueOf(System.currentTimeMillis()));*/
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 最後通知圖庫更新
//        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
        /**MediaScannerConnection.scanFile(context, new String[]{file.getAbsolutePath()}, null,
         new MediaScannerConnection.OnScanCompletedListener() {
        @Override public void onScanCompleted(String path, Uri uri) {
        }
        });*/

        try {
            savePhotoToMedia(context, file, fileName);
            ToastUtils.showShort("圖片已成功保存到相冊");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            ToastUtils.showShort("圖片保存失敗");
        }
        return file.getAbsolutePath();
    }

    public static Bitmap getBitmapFromView(Context context, View view) {
        view.setDrawingCacheEnabled(true);
        //啟用DrawingCache並創建點陣圖
        view.buildDrawingCache();
        //創建一個DrawingCache的拷貝,因為DrawingCache得到的點陣圖在禁用後會被回收
        Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
        //禁用DrawingCahce否則會影響性能
        view.setDrawingCacheEnabled(false);
        return bitmap;
    }

    //圖片上繪製文字
    public static Bitmap drawTextToBitmap(Bitmap bitmap, String text,
            Paint paint, Rect bounds, int paddingLeft, int paddingTop) {
        android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();

        paint.setDither(true); // 獲取跟清晰的圖像採樣
        paint.setFilterBitmap(true);// 過濾一些
        if (bitmapConfig == null) {
            bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
        }
        bitmap = bitmap.copy(bitmapConfig, true);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawText(text, paddingLeft, paddingTop, paint);
        return bitmap;
    }


    public static Bitmap setImgSize(Bitmap bm, int newWidth, int newHeight) {
        // 獲得圖片的寬高.
        int width = bm.getWidth();
        int height = bm.getHeight();
        // 計算縮放比例.
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要縮放的matrix參數.
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的圖片.
        return Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
    }

    // 保存圖片的回調
    public interface OnSaveImgCallBack {

        void onSaveStart();

        void onSaveSuccess();

        void onSaveFail();
    }

    public static void savePhotoToMedia(Context context, File file, String fileName)
            throws FileNotFoundException {
        String uriString = MediaStore.Images.Media
                .insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
//        String uriString = MediaStore.Images.Media.insertImage(context.getContentResolver(), bitmap, null, null);
        File file1 = new File(getRealPathFromURI(Uri.parse(uriString), context));
        updatePhotoMedia(file1, context);
    }

    //更新圖庫
    private static void updatePhotoMedia(File file, Context context) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(Uri.fromFile(file));
        context.sendBroadcast(intent);
    }

    //得到絕對地址
    private static String getRealPathFromURI(Uri contentUri, Context context) {
        String[] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
        if (cursor == null) {
            return "";
        }
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String fileStr = cursor.getString(column_index);
        cursor.close();
        return fileStr;
    }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.rpm -qa | grep mysql,查看原系統中是否有已經安裝得mysql。 註:centos7系統在安裝完成後,未安裝mysql任何版本。 2. rpm -e --nodeps mysql-libs-*********,如果有則將相關得卸載。 3.wget http://repo.mys ...
  • 小白如何學習大數據技術?大數據怎麼入門?怎麼做大數據分析?數據科學需要學習那些技術?大數據的應用前景等等問題,已成為熱門大數據領域熱門問題,以下是對新手如何學習大數據技術問題的解答~ 大數據開發學習可以按照以下內容進行學習 第一階段:JavaSE+MySql+Linux 學習內容:Java 語言入門 ...
  • 作者:天山老妖S 鏈接:http://blog.51cto.com/9291927 一、觸發器簡介 1、觸發器簡介 觸發器是和表關聯的特殊的存儲過程,可以再插入,刪除或修改表中的數據時觸發執行,比資料庫本身標準的功能有更精細和更複雜的數據控制能力。 2、觸發器的優點 A、安全性 可以基於資料庫的值使 ...
  • 歡迎大家前往 "騰訊雲+社區" ,獲取更多騰訊海量技術實踐乾貨哦~ 本文由 "騰訊雲資料庫 TencentDB" 發表於 "雲+社區專欄" 王甲坤,騰訊高級工程師、騰訊雲關係型 "資料庫MySQL" 負責人,擁有多年客戶端、資料庫研發經驗。在IOS客戶端、 "MySQL" 、 "PostgreSQL ...
  • 語句: 翻譯成中文就是: 刪除,“table1”中,id 不在此範圍的所有記錄。此範圍是,篩選出,以field1分組的,所有組別中id的最小的一個。 更直接點就是,以field1分組,選出分組中id最小的一條記錄,然後剩下的全部刪除。 理解不正確的話,請指點一二。 ...
  • http://putpan.com/fs/by4i9b7ebnbs3hbu6/ 需要IT編程經典書籍資源大合集百度網盤鏈接的加qq 2057904338,另本人願意有償帶小白學python,幫助你答疑解惑,幫助你解決問題,指導你找工作,帶你入行。相信我有人帶著你的話可以少走彎路,成功入行拿高薪。北京 ...
  • 判斷字元串是否為正整數,0開始的的數字不算。 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[svf_IsPositiveInteger] ( @string NVARCHAR(MAX) ) RETURN ...
  • 手機上的資源畢竟有限,為了獲取更豐富的信息,就得到遼闊的互聯網大海上衝浪。對於App自身,也要經常與伺服器交互,以便獲取最新的數據顯示到界面上。這個客戶端與服務端之間的信息交互,基本使用HTTP協議進行通信,即App訪問伺服器的HTTP介面來傳輸數據。HTTP介面調用在Java代碼中可不是一個輕鬆的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...