1. 程式人生 > >Android 儲存圖片到系統圖庫 -- 利用 “系統儲存螢幕截圖” 的方法實現

Android 儲存圖片到系統圖庫 -- 利用 “系統儲存螢幕截圖” 的方法實現

儲存圖片到系統圖庫是個很常見的功能,今天第一次做的時候,遇到了一些問題,就是儲存到了相簿之後,在部分機型上無法立即顯示,原因就是相簿資料沒有更新。百度了一下,發現這個問題還是很常見的,網上也有不少的解決辦法。

在參考了:http://blog.csdn.net/xu_fu/article/details/39158747,這篇文章之後總算是實現了。而在文章最後,作者提到了系統截圖功能的原始碼,裡面同樣有儲存到圖片的系統圖庫的功能,作者貼出了相關原始碼,於是嘗試著以該原始碼的解決思路來實現儲存圖片的系統圖庫的功能,事實證明,該方法確實能很好的解決相簿資料更新的問題,下面做一下記錄,方便學習和交流。

首先貼出系統截圖功能中儲存圖片到相簿的部分原始碼:

Context context = params[0].context;  
        Bitmap image = params[0].image;  
        Resources r = context.getResources();  
  
        try {  
            // Create screenshot directory if it doesn't exist  
            mScreenshotDir.mkdirs();  
  
            // media provider uses seconds for DATE_MODIFIED and DATE_ADDED, but milliseconds  
            // for DATE_TAKEN  
            long dateSeconds = mImageTime / 1000;  
  
            // Save the screenshot to the MediaStore  
            ContentValues values = new ContentValues();  
            ContentResolver resolver = context.getContentResolver();  
            values.put(MediaStore.Images.ImageColumns.DATA, mImageFilePath);  
            values.put(MediaStore.Images.ImageColumns.TITLE, mImageFileName);  
            values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, mImageFileName);  
            values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, mImageTime);  
            values.put(MediaStore.Images.ImageColumns.DATE_ADDED, dateSeconds);  
            values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, dateSeconds);  
            values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");  
            values.put(MediaStore.Images.ImageColumns.WIDTH, mImageWidth);  
            values.put(MediaStore.Images.ImageColumns.HEIGHT, mImageHeight);  
            Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);  
  
            OutputStream out = resolver.openOutputStream(uri);  
            image.compress(Bitmap.CompressFormat.PNG, 100, out);  
            out.flush();  
            out.close();  
  
            // update file size in the database  
            values.clear();  
            values.put(MediaStore.Images.ImageColumns.SIZE, new File(mImageFilePath).length());  
            resolver.update(uri, values, null, null);  
  
             
        } catch (Exception e) {  
             
        }  


佈局檔案什麼的就不說了,這裡就是一個ImageView,然後設定一張圖片就行了。

從上面的部分原始碼中可以看到,在儲存圖片的時候,引數是Bitmap 物件,而我這裡儲存ImageView中顯示的圖片到系統圖庫,在XML中直接設定的時候是一個Drawable 物件,這裡就需要進行一下轉化,這裡的程式碼是:

<pre name="code" class="java"> BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
<span style="white-space:pre">	</span>Bitamp bmp = drawable.getBitmap();
更多有關Drawable 和 Bitmap之間的轉換,請參考這裡:http://blog.csdn.net/june5253/article/details/7826597。
其他的不多說了,主要看看實現儲存圖片到系統圖庫的方法,請看下面的程式碼:
<pre name="code" class="java">private void saveImageToGallery(Context context, Bitmap bitmap) {
        // Create screenshot directory if it doesn't exist
        String dirName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + "MImages";
        File fileDir = new File(dirName);
        if (!fileDir.exists()) {
            fileDir.mkdir();
        }
        long mImageTime = System.currentTimeMillis();//取當前系統時間
        // media provider uses seconds for DATE_MODIFIED and DATE_ADDED, but milliseconds
        // for DATE_TAKEN
        long dateSeconds = mImageTime / 1000;
        String mImageFileName = dateSeconds + ".png"; //以儲存時間命名
        String mImageFilePath = dirName + File.separator + mImageFileName; //注意這裡的mImageFilePath是: 目錄名稱+檔名
        int mImageWidth = bitmap.getWidth();
        int mImageHeight = bitmap.getHeight();

        // Save the screenshot to the MediaStore
        ContentValues values = new ContentValues();
        ContentResolver resolver = context.getContentResolver();
        values.put(MediaStore.Images.ImageColumns.DATA, mImageFilePath);
        values.put(MediaStore.Images.ImageColumns.TITLE, mImageFileName);
        values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, mImageFileName);
        values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, mImageTime);
        values.put(MediaStore.Images.ImageColumns.DATE_ADDED, dateSeconds);
        values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, dateSeconds);
        values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
        values.put(MediaStore.Images.ImageColumns.WIDTH, mImageWidth);
        values.put(MediaStore.Images.ImageColumns.HEIGHT, mImageHeight);
        Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

        try {
            OutputStream out = resolver.openOutputStream(uri);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // update file size in the database
        values.clear();
        values.put(MediaStore.Images.ImageColumns.SIZE, new File(mImageFilePath).length());
        resolver.update(uri, values, null, null);     
    }
需要說明和注意的地方,已經用中文進行了註釋,這樣就OK了,在上面這段程式碼執行後,就可以在系統的DCIM目錄下,生成一個MImages目錄,儲存的圖片就在該目錄下,同時可以在系統圖庫應用中看到名為MImages的相簿,就跟系統截圖的Screenshots相簿一樣。






相關推薦

Android 儲存圖片系統 -- 利用系統儲存螢幕” 的方法實現

儲存圖片到系統圖庫是個很常見的功能,今天第一次做的時候,遇到了一些問題,就是儲存到了相簿之後,在部分機型上無法立即顯示,原因就是相簿資料沒有更新。百度了一下,發現這個問題還是很常見的,網上也有不少的解決辦法。 在參考了:http://blog.csdn.net/xu_fu/

android 獲取螢幕並呼叫系統分享

呼叫的系統自帶的分享而不是接入的第三方sdk 第一步: 獲取螢幕截圖 // 獲取螢幕(包括導航 View dView =AddressDetailsActivity.this.getWindow().getDecorView(); dVi

JAVA B/S系統實現客戶端螢幕,Java版的QQ

簡介:本方法首先需要抓到螢幕的整個圖象,將圖象顯示在一個JFrame中,再將JFrame全屏顯示,這樣就模擬出了一個桌面,Java也就可以獲得滑鼠的作用區域從而實現桌面中的小範圍截圖。Java實現QQ螢幕截圖功能(跨平臺螢幕截圖功能,支援windows,OSX,Linux...) 程式目錄結構如下:

利用 Chrome 原生功能網頁全

node chrom command 鼠標 切換 需要 網頁 mman and 打開你想截圖的網頁了,然後按下 F12(macOS 是 option + command + i)調出開發者工具,接著按「Ctrl + Shift + P」(macOS 是 command +

android 關於螢幕的幾種辦法

年末較閒,就上個星期查詢各方面的資料關於android截圖事情,自已也測試一些程式碼,已改改進或者優化。接下來進行總結一下。其實,如果真正android系統截圖是需要root許可權的。但要使用者使用都root,似乎不可能,體驗性太差了。這期間我稍微觀察了QQ的截圖。QQ的截

C#:電腦螢幕 , RGB轉灰度圖片

using System; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; namespace test { public partial class Form1 : Form

VC螢幕儲存為Bmp檔案

新建一個MFC基於對話方塊的應用程式,在介面上放一個Button,為其實現點選事件,程式碼如下: void CScreenShotDlg::OnBtnScreenshot() { RECT rect = {0, 0, 1900, 1000}; HBITMAP hbmp

Android獲取View的,包括各種Layout的

Layout生效後才能使用 /** * 獲取Layout截圖 * * @return 所需區域的截圖 */ private Bitmap getBitmap() { rel_content.setDrawing

VC螢幕(將螢幕指定區域存成圖片)

HBITMAP CLoadpicDlg::CopyScreenToBitmap(LPRECT lpRect) {  HDC hScrDC, hMemDC;   // 螢幕和記憶體裝置描述表   HBITMAP hBitmap,hOldBitmap;   // 點陣圖控

android禁止螢幕

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);

Android 整個手機螢幕和去除狀態列

一、去除狀態列截圖 //整個手機螢幕的檢視 View view = getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildDrawingCache(); Bitmap bit

FrameBuffer中獲取Android螢幕

引子 我們知道,DDMS可以很容易的獲取Android 手機 的螢幕截圖,那麼它是怎麼做到的呢?  其實,android手機上有一個叫做FrameBuffer的裝置,影象資訊都是通過FrameBuffer寫到手機螢幕上去的。因此可以通過讀取此裝置中的資料來獲取當前正在顯示的影象。當然DDMS也是這麼做到

Android 程式碼實現螢幕功能

private void screenshot() { // 獲取螢幕 View dView = getWindow().getDecorView(); dView.setDrawingCacheEnabled(true); dView.buildDrawingCac

android螢幕,android怎麼擷取整個螢幕

View view= getWindow().getDecorView(); int width = getResources().getDisplayMetrics().widthPixels ; int height = getResources().getDisplayMetrics().heightP

Android壓縮圖片到100K以下並保持不失真的高效方法

 在開發Android企業應用時,會經常上傳圖片到伺服器,而我們公司目前維護的一個專案便是如此。該專案是通過私有apn與伺服器進行互動的,聯通的還好,但移動的速度實在太慢,客戶在使用軟體的過程中,由於上傳的資訊中可能包含多張圖片,會經常出現上傳圖片失敗的問題,為了解決這個

Android 小筆記 Uri獲取絕對路徑 、路徑轉Bitmap、獲取螢幕

1. Uri獲取絕對路徑 public static String getRealPathFromURI(Context mContext, Uri contentUri) { St

基於Appium+java進行Android自動化測試:列表定位、用例失敗、長按、滑動、依賴、切換~

一、appium中對元素的定位方法的使用 場景:元素的定位,常利用resource-id、index、name(text)等屬性進行定位。如下圖所示,列表專案的index、resource-id、class、package等屬性均相同,無法利用常用屬性進行區分。直接根據r

Android提高應用的安全性, 禁止螢幕

在玩交通銀行的客戶端的時候, 發現一個很人性化的功能: 禁止螢幕截圖. 於是決定看看這個功能是怎麼實現的. Google了一番, 發現實現的方式就是在setContentView()方法前加上: getWindow().setFlags(LayoutPara

利用Google Chrome滾動,擷取整個網頁

利用Google Chrome滾動截圖 1. 在Chrome瀏覽器中開啟一個網址,比如www.master8687.cn,然後再頁面中滑鼠右鍵,選擇 檢查 項。 2. 在左側的裝置選擇區

android後臺獲取當前螢幕(screencap.cpp修改)

    本文基於android6.0。首先找到screencap在Android原始碼中的位置,若不清楚,可以通過在android目錄下通過命令find . -namescreencap.cpp。本文直接給出路徑/android/frameworks/base/cmds/s