获取系统的相机功能拍照这个不难,但是需要注意的是,拍照返回后的照片如果没有指定存储的路径,那么系统将自动保存到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();
                // 只查询jpeg和png的图片
                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的拍照和自定义多选相册相关推荐

  1. takephoto 框架_GitHub - Smecking/TakePhoto: 一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库...

    TakePhoto是一款用于在Android设备上获取照片(拍照或从相册.文件中选择).裁剪图片.压缩图片的开源工具库,目前最新版本4.0.2. 3.0以下版本及API说明,详见TakePhoto2. ...

  2. android 获取对话框对象,Android 基本Dialog和自定义Dialog

    Android 基本Dialog和自定义Dialog Dialog类是对话框的基类,但你应该避免直接实例化Dialog ,可以使用子类 1.AlertDialog 此对话框可以显示标题,最多三个按钮, ...

  3. android实现拍照、相册选图、裁剪功能,兼容7.0以及小米

    现在一般的手机应用都会有上传头像的功能,我在实现这个功能的时候遇到很多问题,这里专门记录一下. add 2018/5/10 21:05 先列举一下我出现过的问题: 1.运行时权限 2.调用系统相机拍照 ...

  4. android 图片拍照,Android获取图片拍照时间

    为什么写这篇文章是因为今早有个需求需要获取图片拍照时的时间进行一些处理,有些方法参数名忘记了,所以谷歌百度了一下,Android 图片 时间,Android 图片 拍照 时间,这几个关键字居然无法搜索 ...

  5. django获取html复选框,扩展Django Admin tabular.html自定义复选框操作

    我有两个表被告和被告_Potential class Defendant(models.Model): fullname = models.CharField(max_length = 100, nu ...

  6. 【100个 Unity踩坑小知识点】| Unity调用API ,动态获取Android权限,附带所有Android权限表格

    Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 . 包括游戏开发.美术.建筑.汽车设计.影视在内的所有创作者,借助 Unity 将创意 ...

  7. Android 摄像头拍照显示 相册显示 图片裁剪绘制显示

    声明: 学习这个之前, 建议先学习下内容提供器. 使用的是Android系统自带的裁剪功能. 本人真机(华为荣耀9 Android8.0)测试, 先上效果图(拍照和从相册选, 一样的效果): .1. ...

  8. android 相机拍照返回,Android6.0机型上调用系统相机拍照返回的resultCode值始终等于0的问题...

    版权声明:本文为博主原创文章,未经博主允许不得转载. 正常情况下调用系统相机拍照: 如果拍照后点击的是"确定"图标,返回的resultCode = -1(Activity.RESU ...

  9. android 自定义带输入框的dialog,Android 基本Dialog和自定义Dialog

    Android 基本Dialog和自定义Dialog Dialog类是对话框的基类,但你应该避免直接实例化Dialog ,可以使用子类 1.AlertDialog 此对话框可以显示标题,最多三个按钮, ...

最新文章

  1. python selenium 自动登录_windows7 python3.63使用selenium+webdriver 实现自动登录使用过程...
  2. WinForm登录模块设计开发
  3. [蓝桥杯][2018年第九届真题]全球变暖(DFS)
  4. php 公众号验证回调方法_如何进行公众号文章收集 两种收集方法详解
  5. jdbc连接oracle数据库
  6. Slog57_玩转NPM之NPM_package的制作发布和使用
  7. html代码大全贴音乐,网页音乐代码大全
  8. NumPy Beginner's Guide 2e 带注释源码 七、NumPy 特殊例程
  9. zabbix使用JMX监控tomcat性能
  10. unity,生成的mac版游戏切场景时卡死解法
  11. 基于sklearn分析特征工程(特征预处理、特征选择、降维)
  12. epson l201 l200清零软件 中文版 l111 l101清零软件 L350 L353 清零软件
  13. 云流化技术应用之K12VR云课堂
  14. html如何在字段前面空格怎么打,css特殊空格符号 nbsp前面那个怎么打
  15. 超维空间鸿蒙大宇,高维空间的存在不仅能够统一基本力,还为时空穿越提供了可能!...
  16. pc机属于模拟专用微型计算机,《春11计算机基础》期末试题
  17. Java--IDEA之Tomcat重启之后无法活化
  18. 自建OTA服务器实现设备固件自动更新
  19. docker-compose详解
  20. 解决shiro重定向URL中出现sessionID的情况localhost:8080/toLogin;jsessionid=D5C1EE61B97EE2D7098F58A837B82BD4

热门文章

  1. ASP.NET中的AutoPostBack和IsPostBack以及EnableViewState三者的运用以及区别
  2. 网络与新媒体专业有前途吗
  3. java getcolumns_Java DatabaseMetaData.getFunctionColumns方法代碼示例
  4. tyvj 4752 数学逻辑题
  5. Python+Django毕业设计校园食堂订餐系统(程序+LW+部署)
  6. jdbc ResultSetMetaData获取tableName问题
  7. java正则表达式参数替换,正则表达式替换(String对象的replace)方法笔记
  8. MYSQL--架构--MGR--理论--01--MGR是什么
  9. 【基于分数的模型与扩散模型的区别与联系】score-based generative models总结
  10. 外设驱动库开发笔记46:MAX31855热偶变送器驱动