1. 程式人生 > >獲取android的拍照和自定義多選相簿

獲取android的拍照和自定義多選相簿

    獲取系統的相機功能拍照這個不難,但是需要注意的是,拍照返回後的照片如果沒有指定儲存的路徑,那麼系統將自動儲存到sd卡中,得到的是拍完照的縮圖,會失幀,顯示有些模糊,所以在呼叫系統相機拍完照後我們要指定一個路徑,將它存起來,需要的時候再去拿,呼叫相簿這裡當時需要的是相簿的多選,但是系統相簿只能單選,所以自定義了一個相簿,是直接startActivity的,我們來看看獲取相簿和系統相機的Intent是怎麼寫的。

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("新增顏色");
String[] items = {"
從相簿選取", "拍照"}; builder.setNegativeButton("取消", null); builder.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case CHOOSE_PICTURE:// 選擇本地照片Intent intent = new Intent(SampleSendActivity.this,SampleCameraActivity.class
); startActivityForResult(intent, ACTION_IMAGE_PICTURE); break; case TAKE_PICTURE:// 拍照Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); /** * 每次拍照新建一個照片檔案 */ String name = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg"
; File file = new File("/sdcard/myImage/"); file.mkdirs();// 建立資料夾 mFilePath = "/sdcard/myImage/"+name; // 載入路徑 Uri uri = Uri.fromFile(new File(mFilePath)); // 指定儲存路徑,這樣就可以儲存原圖了 intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // 拍照返回圖片 startActivityForResult(intent, ACTION_IMAGE_CAMEREA); break; } } }); builder.create().show();

現在我們來看看呼叫系統相簿後去獲取指定的file,直接通過路徑顯示在imageview中

if (requestCode == ACTION_IMAGE_CAMEREA&& resultCode == Activity.RESULT_OK) {
   String storageState = Environment.getExternalStorageState();
   if (!storageState.equals(Environment.MEDIA_MOUNTED)) {
      return;
}// /sdcard
mFilePath = "/storage/emulated/0" + mFilePath.substring(7);
BitmapUtil.loadUriImage(SampleSendActivity.this, mFilePath, tagHolder.iv_pinkaddpig);
   //這裡的bitmaputil是我自己寫的,就是通過路徑載入到imageview中,可以忽略}

     再來看看自定義多選相簿的實現

public class SampleCameraActivity extends Activity implements OnImageDirSelected {
    private ProgressDialog mProgressDialog;
/**
     * 儲存資料夾中的圖片數量
*/
private int mPicsSize;
/**
     * 圖片數量最多的資料夾
*/
private File mImgDir;
/**
     * 所有的圖片
*/
private List<String> mImgs;
    private GridView mGirdView;
    private MyAdapter mAdapter;
/**
     * 臨時的輔助類,用於防止同一個資料夾的多次掃描
*/
private HashSet<String> mDirPaths = new HashSet<String>();
/**
     * 掃描拿到所有的圖片資料夾
*/
private List<ImageFloder> mImageFloders = new ArrayList<ImageFloder>();
    private RelativeLayout mBottomLy;
    private TextView mChooseDir;
    private TextView mImageCount;
    int totalCount = 0;
    private int mScreenHeight;
    private ListImageDirPopupWindow mListImageDirPopupWindow;
    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            mProgressDialog.dismiss();
// View繫結資料
data2View();
// 初始化展示資料夾的popupWindw
initListDirPopupWindw();
}
    };
    private TextView tv_samplecamera_confirm;
    private TextView tv_return;
/**
     * View繫結資料
*/
private void data2View() {
        if (mImgDir == null) {
            Toast.makeText(getApplicationContext(), "擦,一張圖片沒掃描到",
Toast.LENGTH_SHORT).show();
            return;
}
        mImgs = Arrays.asList(mImgDir.list());
/**
         * 可以看到資料夾的路徑和圖片的路徑分開儲存,極大的減少了記憶體的消耗;
*/
mAdapter = new MyAdapter(getApplicationContext(), mImgs,
R.layout.view_cameragrid_item, mImgDir.getAbsolutePath());
mAdapter.setIamgeNull();
mGirdView.setAdapter(mAdapter);
mImageCount.setText(totalCount + "");
};
/**
     * 初始化展示資料夾的popupWindw
     */
private void initListDirPopupWindw() {
        mListImageDirPopupWindow = new ListImageDirPopupWindow(
                (int) LayoutParams.MATCH_PARENT, (int) (mScreenHeight * 0.7),
mImageFloders, LayoutInflater.from(getApplicationContext())
                .inflate(R.layout.view_cameralist_dir, null));
mListImageDirPopupWindow.setOnDismissListener(new OnDismissListener() {

            @Override
public void onDismiss() {
                // 設定背景顏色變暗
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1.0f;
getWindow().setAttributes(lp);
}
        });
// 設定選擇資料夾的回撥
mListImageDirPopupWindow.setOnImageDirSelected(this);
}

    @Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_camera);
DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
mScreenHeight = outMetrics.heightPixels;
getActionBar().hide();
initView();
getImages();
initEvent();
}

    /**
     * 利用ContentProvider掃描手機中的圖片,此方法在執行在子執行緒中 完成圖片的掃描,最終獲得jpg最多的那個資料夾
*/
private void getImages() {
        if (!Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            Toast.makeText(this, "暫無外部儲存", Toast.LENGTH_SHORT).show();
            return;
}
        // 顯示進度條
mProgressDialog = ProgressDialog.show(this, null, "正在載入...");
        new Thread(new Runnable() {
            @Override
public void run() {
                String firstImage = null;
Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver mContentResolver = SampleCameraActivity.this
.getContentResolver();
// 只查詢jpegpng的圖片
Cursor mCursor = mContentResolver.query(mImageUri, null,
MediaStore.Images.Media.MIME_TYPE + "=? or "
+ MediaStore.Images.Media.MIME_TYPE + "=?",
                        new String[]{"image/jpeg", "image/png"},
MediaStore.Images.Media.DATE_MODIFIED);
Log.e("TAG", mCursor.getCount() + "");
                while (mCursor.moveToNext()) {
                    // 獲取圖片的路徑
String path = mCursor.getString(mCursor
                            .getColumnIndex(MediaStore.Images.Media.DATA));
Log.e("TAG", path);
// 拿到第一張圖片的路徑
if (firstImage == null)
                        firstImage = path;
// 獲取該圖片的父路徑名
File parentFile = new File(path).getParentFile();
                    if (parentFile == null)
                        continue;
String dirPath = parentFile.getAbsolutePath();
ImageFloder imageFloder = null;
// 利用一個HashSet防止多次掃描同一個資料夾(不加這個判斷,圖片多起來還是相當恐怖的~~if (mDirPaths.contains(dirPath)) {
                        continue;
} else {
                        mDirPaths.add(dirPath);
// 初始化imageFloder
imageFloder = new ImageFloder();
imageFloder.setDir(dirPath);
imageFloder.setFirstImagePath(path);
}
                    int picSize = 0;
                    try{
                        picSize = parentFile.list(new FilenameFilter() {
                            @Override
public boolean accept(File dir, String filename) {
                                if (filename.endsWith(".jpg")
                                        || filename.endsWith(".png")
                                        || filename.endsWith(".jpeg"))
                                    return true;
                                return false;
}
                        }).length;
}catch (Exception e){
                        e.printStackTrace();
}
                    totalCount += picSize;
imageFloder.setCount(picSize);
mImageFloders.add(imageFloder);
                    if (picSize > mPicsSize) {
                        mPicsSize = picSize;
mImgDir = parentFile;
}
                }
                mCursor.close();
// 掃描完成,輔助的HashSet也就可以釋放記憶體了
mDirPaths = null;
// 通知Handler掃描圖片完成
mHandler.sendEmptyMessage(0x110);
}
        }).start();
}

    /**
     * 初始化View
     */
private void initView() {
        mGirdView = (GridView) findViewById(R.id.id_gridView);
tv_samplecamera_confirm = (TextView) findViewById(R.id.tv_samplecamera_confirm);
mChooseDir = (TextView) findViewById(R.id.id_choose_dir);
tv_return = (TextView) findViewById(R.id.tv_return_samplecamera);
mImageCount = (TextView) findViewById(R.id.id_total_count);
mBottomLy = (RelativeLayout) findViewById(R.id.id_bottom_ly);
}

    private void initEvent() {
        tv_samplecamera_confirm.setOnClickListener(new OnClickListener() {

            @Override
public void onClick(View v) {
                ArrayList<String> imageList = mAdapter.getImageList();
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putStringArrayList("images", imageList);
intent.putExtras(bundle);
setResult(11, intent);
finish();
}
        });
tv_return.setOnClickListener(new OnClickListener() {
            @Override
public void onClick(View v) {
                finish();
}
        });
/**
         * 為底部的佈局設定點選事件,彈出popupWindow
         */
mBottomLy.setOnClickListener(new OnClickListener() {
            @Override
public void onClick(View v) {
                mListImageDirPopupWindow
.setAnimationStyle(R.style.anim_popup_dir);
mListImageDirPopupWindow.showAsDropDown(mBottomLy, 0, 0);
// 設定背景顏色變暗
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = .3f;
getWindow().setAttributes(lp);
}
        });
}

    public void selected(ImageFloder floder) {
        mImgDir = new File(floder.getDir());
mImgs = Arrays.asList(mImgDir.list(new FilenameFilter() {
            @Override
public boolean accept(File dir, String filename) {
                if (filename.endsWith(".jpg") || filename.endsWith(".png")
                        || filename.endsWith(".jpeg"))
                    return true;
                return false;
}
        }));
/**
         * 可以看到資料夾的路徑和圖片的路徑分開儲存,極大的減少了記憶體的消耗;
*/
mAdapter = new MyAdapter(getApplicationContext(), mImgs,
R.layout.view_cameragrid_item, mImgDir.getAbsolutePath());
mGirdView.setAdapter(mAdapter);mImageCount.setText(floder.getCount() + "");
mChooseDir.setText(floder.getName());
mListImageDirPopupWindow.dismiss();
}
}

   來看看呼叫後的效果


相簿呼叫後返回的是包含相片的本地路徑字串

ArrayList<String> imageArrayList = bundle.getStringArrayList("images");

原始碼下載:

http://download.csdn.net/download/jacky_can/9878331

相關推薦

獲取android拍照定義相簿

    獲取系統的相機功能拍照這個不難,但是需要注意的是,拍照返回後的照片如果沒有指定儲存的路徑,那麼系統將自動儲存到sd卡中,得到的是拍完照的縮圖,會失幀,顯示有些模糊,所以在呼叫系統相機拍完照後我們要指定一個路徑,將它存起來,需要的時候再去拿,呼叫相簿這裡當時需要的是相

Android開發技巧——定義的ListView

這篇其實應該是屬於寫自定義單選或多選的ListView的基礎教程,無奈目前許多人對此的實現大多都繞了遠路,反而使得這正規的寫法倒顯得有些技巧性了。 本文原創,轉載請註明在CSDN上的出處: http://blog.csdn.net/maosidiaoxian/article

jq定義下拉列表框

多選 img 插件 國家 http 分享 class 下拉 blog 多選選擇國家插件 https://gitee.com/richard1015/dropDownList jq自定義多選下拉列表框

vue定義樣式

自定義多選框樣式 平時一直用的框架中的樣式,這次不行了 要自己寫。 做個筆記記錄一下 很久沒寫這中樣式了 設計要求的樣式 其實那個勾並不是checkbox,而是一個i標籤,給他的兩邊設定border

iview表格定義

列中定義: { title: '是否簡訊通知', key: 'isSmsnotify', render: (h, params) => { return h( 'div', this.$refs.myTable.$scop

【轉】WPF定義控制元件與樣式(8)-ComboBox與定義控制元件MultComboBox

一.前言   申明:WPF自定義控制元件與樣式是一個系列文章,前後是有些關聯的,但大多是按照由簡到繁的順序逐步釋出的等。   本文主要內容: 下拉選擇控制元件ComboBox的自定義樣式及擴充套件; 自定義多選控制元件MultiComboBox; 二.下拉選擇控制元件ComboBox的自

JS獲取元素屬性定義屬性

昨天有同事問我,怎麼獲取自定義元素的屬性,我意識到這個確實是個 問題,所有總結一下自己的心得。 獲取元素的屬性分為兩種型別: 1-獲取元素常見的屬性(class,id,type,

定義

說明:作為一個Java後端程式設計師,有時候也需要自己去寫些前端程式碼,所以將工作中用到的一些小知識做記錄分享。 1.自定義單選框(有圖片) * ①先看效果圖: * ②再獻上完整程式碼: <!DOCTYPE html> <html> &l

Android使用開源框架完成城市列表三級聯動(從服務端獲取資料來源定義json資料來源)

Android-PickerView使用步驟:1.新增Jcenter倉庫 Gradle依賴:compile 'com.contrarywind:Android-PickerView:4.1.4'2.在Activity中新增如下程式碼:package com.xueqing.r

15/8/27/預設定義Toast/簡單、選項、單AlterDialog

Toast Toast分為預設的和自定義佈局的Toast 1.Toast是獨立, 不依賴於Activity,但是不能對他進行操作,因此通常用於提示資訊, 2.預設的Toast比較簡單其程式碼如下: Toast toast=Toast.mak

android定義相機、連續(自動)聚焦、點(觸控)聚焦、變焦、拍照定義裁剪、旋轉

最近做了一個圖片識別、以及搜尋的小專案,其中有一個模組是拍照以及拍照後對圖片進行剪下,開始用的系統的相機和裁剪,由於系統的相機和裁剪多出了一些不必要的步驟和啟動慢等等帶給使用者的體驗不好,故自己寫了一個,下面給大家簡要介紹下: 自定義相機:定義SurfaceView得到Su

Android零基礎入門第39節:ListActivity定義列表項

arraylist component save 高速 ram 如果 view設置 ren 屬性 相信通過前兩期的學習,以及會開發最簡單的一些列表界面了吧,那麽本期接著來學習更多方法技巧。 一、使用ListActivity 如果程序的窗口僅僅需要

Android中引入佈局定義控制元件

首先是引入佈局: 1.我們自己新建一個layout,就是一個標題欄。 2.然後在我們的mainactivity_layout中使用一個語句就可以實現。 <?xml version="1.0" encoding="utf-8"?> <LinearLayout

Android應用--簡 美音樂播放器獲取專輯圖片(定義列表介面卡)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android Studio3.0定義apk輸出路徑檔名

在專案的gradle檔案的android中新增如下配置 // 自定義apk輸出路徑和檔名,as3.0需要修改為一下寫法 applicationVariants.all { variant -> variant.outputs.all {

Android RecyclerView 詳解 RecyclerView的動畫實現(移除、新增、改變、移動)定義動畫的實現

一丶新增刪除時候的重新整理問題 先上一下效果圖吧 1.為了方便起見我們還是先新增三個按鈕分別實現新增刪除和改變 2.在Adapter中寫呼叫方法並進行重新整理 public void remove(int position){ list.re

Android的基本元件定義檢視

Android的基本元件 1 Activity 1.1 Activity代表手機的一個螢幕 1.2 一個Android程式由多個Activity組成,即:一個Android程式由多屏內容組成 1.3 Activity相當於一個展板

藉助Spring定義註解完成資料來源配置

前一段時間研究了一下spring多資料來源的配置和使用,為了後期從多個數據源拉取資料定時進行資料分析和報表統計做準備。由於之前做過的專案都是單資料來源的,沒有遇到這種場景,所以也一直沒有去了解過如何配置多資料來源。 後來發現其實基於spring來配置和使用多資

android 註解學習筆記二: 元註解定義註解

首先看一個自定義的註解: 1、自定義註解 public @interface MyAnnotation { int age(); } 可見定義一個註解非常簡單,只需要使用@interface關鍵字來定義即可。 同時我們可以看到,註解的內部可以定義變

android 8.0 定義控制元件onmesure獲取寬度為0

最近專案需要適配8.0版本,自定義控制元件出現了下面的問題 第一次顯示此彈窗字型出現了偏移,找到原因是textpaint在繪製文字的時候 canvas.drawText(itemText, x + (controlWidth / 2) -textRect.width