在很多项目中,要使用到相机的拍照、相册的预览、选择;今天在这里就总结一下使用方法;废话不多说,上代码了!

一:调用Android 原生相机拍照:

 /**     * 调用系统相机拍照     */    public void getPicFromCamera() {        private Uri mOriginUri;        private String mCurrentPath;        private File tempFile;        //用于保存调用相机拍照后所生成的文件        //照片的路径        mCurrentPath = FileUtil.getImgpath(String.valueOf(System.currentTimeMillis()));        //跳转到调用系统相机        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        //判断版本        if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA) !=                PackageManager.PERMISSION_GRANTED) {            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission                    .CAMERA}, 1);            Toast.makeText(mContext, "请前往设置中打开拍照", Toast.LENGTH_SHORT).show();        } else {            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {                mOriginUri = FileProvider.getUriForFile(getApplication(), getApplication()                                .getPackageName() + ".FileProvider",                        new File(mCurrentPath));                intent.putExtra(MediaStore.EXTRA_OUTPUT, mOriginUri);            } else {                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));            }            startActivityForResult(intent, CAMERA_REQUEST_CODE);        }    }

其中 getPackageName() + ".FileProvider",一定要与清单文件中的报名一致(具体生成步骤,往下看)。

FileUtil中生成文件的方法:

并解决拍照回调的resultCode返回都是0的问题,就是生成文件的时候,要加上file.getParentFile(),

原因是在创建拍照文件的时候路 file不存在,调用 file.mkdirs() , 最终创建的xxx.jpeg 是文件夹而非文件。

详细的原因,给大家推荐一个地址:https://blog.csdn.net/qq_21199331/article/details/83042001

  //获取图片存储的根目录    public static String getImgDIrectory() {        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ?                mSdRootPath + IMG_PATH : mDataRootPath + IMG_PATH;    }    public static String getImgpath(String imgName) {        File file = new File(getImgDIrectory());        if (!file.exists()) {            file.getParentFile().mkdirs(); // getParentFile()            //注意此处创建文件调用getParentFile()再调用    mkdirs()        }        return getImgDIrectory() + imgName + IMG_SUFFIX;    }

其中还要有Android 版本的判断,来使用系统的文件共享FileProvider,配置如下:

1、在清单文件中添加:

                             

2、在res目录下创建xml文件,在xml中创建file_paths.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>                

二:相册选择照片:(使用知乎的图片选择器,更多的api,可以查看源文档)

导入依赖:

//图片选择器    api 'com.zhihu.android:matisse:0.4.3'
 /*        从相册中选择照片     */    public void selectMyPhoto() {        if (ContextCompat.checkSelfPermission(mContext, Manifest.permission                .READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission                    .READ_EXTERNAL_STORAGE}, 1);            Toast.makeText(mContext, "请前往设置中打开读取权限", Toast.LENGTH_SHORT).show();        } else {            Matisse.from(this)                    .choose(MimeType.allOf())//图片类型                    .countable(true)//true:选中后显示数字;false:选中后显示对号                    .maxSelectable(9)//可选的最大数                    .capture(false)//选择照片时,是否显示拍照                    .captureStrategy(new CaptureStrategy(true, "com.project.evaluationmobile" +                            ".FileProvider"))//参数1 true表示拍照存储在共有目录,false表示存储在私有目录;参数2与                    // AndroidManifest中authorities值相同,用于适配7.0系统 必须设置                    .imageEngine(new GlideEngine())//图片加载引擎                    .forResult(REQUEST_CODE_CHOOSE);//        }    }

好了,接下来就是回调了。相关的结实都在注释中写出来了。

@Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);         List result;                switch (requestCode) {            case REQUEST_CODE_CHOOSE: // 选择照片                if (resultCode == RESULT_OK) {                    // 所选择的图片的uri的集合                    result = Matisse.obtainResult(data);                    Log.d("photo", result.toString() + "++++++++++===========");                    for (int i = 0; i < result.size(); i++) {                       // 可以通过for循环来得到我们所选中图片的uri,来进行相应的操作                    }                }                break;            case CAMERA_REQUEST_CODE:// 相机拍照                if (resultCode == RESULT_OK) {                    // 图片拍照完成,图片的路径就是我们一开始定义的路径:mCurrentPath                    // 依次来完成相应的操作                }                break;            default:        }    }

,在这方面,难免会遇到文件的处理、Uri等。在文章的后边,我会添加上我使用的两个工具类,希望对各位有用!

三、图片的预览、查看

这里给大家一个网址,自己查看吧。

https://blog.csdn.net/PenTablet/article/details/88552819

 

好了,接下来,就是我使用的两个工具类了,

FileUtil:
package com.project.evaluationmobile.util;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.net.Uri;import android.os.Environment;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;/*** * */public class FileUtil {    //SD卡根路径    private static String mSdRootPath = Environment.getExternalStorageDirectory().getPath();    //手机的缓存根目录    private static String mDataRootPath = "";    //保存图片的目录    private final static String IMG_PATH = "/Evaluation/image";    private final static String IMG_SUFFIX = ".png";    public FileUtil(Context context) {        mDataRootPath = context.getCacheDir().getPath();    }    //获取图片存储的根目录    public static String getImgDIrectory() {        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ?                mSdRootPath + IMG_PATH : mDataRootPath + IMG_PATH;    }    public static String getImgpath(String imgName) {        File file = new File(getImgDIrectory());        if (!file.exists()) {            file.getParentFile().mkdirs(); // getParentFile()            // 一定要加上这个参数,防止生成的不是文件夹,来解决resultCode返回都是0的问题        }        return getImgDIrectory() + imgName + IMG_SUFFIX;    }    //图片保存到本地,--返回图片的路径    public static String saveImg(ByteArrayOutputStream bos) {        FileOutputStream fos = null;        String path = getImgpath(String.valueOf(System.currentTimeMillis()));        File file = new File(path);        try {            if (!file.exists()) {                file.createNewFile();            }            fos = new FileOutputStream(file);            fos.write(bos.toByteArray());            fos.flush();        } catch (IOException e) {            path = "";            e.printStackTrace();        } finally {            try {                if (fos != null)                    fos.close();                if (bos != null)                    bos.close();            } catch (IOException e) {                e.printStackTrace();            }        }        return path;    }    public static boolean saveImageToGallery(Context context, Bitmap bmp) {        // 首先保存图片        String storePath = getImgpath(String.valueOf(System.currentTimeMillis()));        File appDir = new File(storePath);        if (!appDir.exists()) {            appDir.mkdir();        }        String fileName = System.currentTimeMillis() + ".jpg";        File file = new File(appDir, fileName);        try {            FileOutputStream fos = new FileOutputStream(file);            //通过io流的方式来压缩保存图片            boolean isSuccess = bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);            fos.flush();            fos.close();            //把文件插入到系统图库            //MediaStore.Images.Media.insertImage(context.getContentResolver(), file            // .getAbsolutePath(), fileName, null);            //保存图片后发送广播通知更新数据库            Uri uri = Uri.fromFile(file);            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));            if (isSuccess) {                return true;            } else {                return false;            }        } catch (IOException e) {            e.printStackTrace();        }        return false;    }}
ImageUtil:
package com.project.evaluationmobile.util;import android.content.ContentUris;import android.content.Context;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.Build;import android.os.Environment;import android.provider.DocumentsContract;import android.provider.MediaStore;import android.util.Log;import java.io.ByteArrayOutputStream;/** * @ClassName: ${type_name} * @Description: ${todo} * @author: ${libiao} * @date: ${date} ${time} * ${tags} */public class ImageUtil {    private static String Tag = "PATH";    public static String getSmallBitmap(String filePath) {        Log.d(Tag, "图片处理开始");        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeFile(filePath, options);        options.inSampleSize = calculateInSampleSize(options, 1280, 720);        Log.d(Tag, "图片分辨率压缩后" + options.inSampleSize + "");        options.inJustDecodeBounds = false;        //避免出现内存溢出的情况,进行相应的属性设置。        options.inPreferredConfig = Bitmap.Config.RGB_565;        options.inDither = true;        Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);        return compressAndSave(bitmap);    }    // 计算图片的缩放值    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {        final int height = options.outHeight;        final int width = options.outWidth;        int inSampleSize = 1;        if (height > reqHeight || width > reqWidth) {            final int heightRatio = Math.round((float) height / (float) reqHeight);            final int widthRatio = Math.round((float) width / (float) reqWidth);            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;        }        return inSampleSize;    }    // 这里是根据质量压缩.可以吧图片压缩到100K以下,然后保存到本地文件    private static String compressAndSave(Bitmap image) {        ByteArrayOutputStream baos = new ByteArrayOutputStream();        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中        int options = 100;        Log.d(Tag, baos.toByteArray().length / 1024 + "KB");        System.out.println(baos.toByteArray().length / 1024 + "KB");        while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩            baos.reset();// 重置baos即清空baos            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中            options -= 10;// 每次都减少10        }        Log.d(Tag, "图片处理完成" + baos.toByteArray().length / 1024 + "KB");        String path = FileUtil.saveImg(baos);        image.recycle();        Log.d(Tag, "压缩后的图片路径" + path);        image = null;        // 在这里已经压缩到100以下了,但是只要调用了decodeStream就又会涨到200K,所以在操作之前把图片先保存到本地        // 如果需要返回一个bitmap对象,则调用如下方法        // ByteArrayInputStream isBm = new        // ByteArrayInputStream(baos.toByteArray());        // 把压缩后的数据baos存放到ByteArrayInputStream中        // Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);        // 把ByteArrayInputStream数据生成图片        return path;    }    /**     * @param context     * @param uri     * @return     * @Title: getPhotoPath     * @Description: 根据Uri得到该图片的路径(兼容4.4)     * @return: String     */    public static String getPhotoPath(final Context context, final Uri uri) {        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;        // DocumentProvider        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {            // ExternalStorageProvider            if (isExternalStorageDocument(uri)) {                final String docId = DocumentsContract.getDocumentId(uri);                final String[] split = docId.split(":");                final String type = split[0];                if ("primary".equalsIgnoreCase(type)) {                    return Environment.getExternalStorageDirectory() + "/" + split[1];                }            }            // DownloadsProvider            else if (isDownloadsDocument(uri)) {                final String id = DocumentsContract.getDocumentId(uri);                final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));                return getDataColumn(context, contentUri, null, null);            }            // MediaProvider            else if (isMediaDocument(uri)) {                final String docId = DocumentsContract.getDocumentId(uri);                final String[] split = docId.split(":");                final String type = split[0];                Uri contentUri = null;                if ("image".equals(type)) {                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;                } else if ("video".equals(type)) {                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;                } else if ("audio".equals(type)) {                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;                }                final String selection = "_id=?";                final String[] selectionArgs = new String[]{split[1]};                return getDataColumn(context, contentUri, selection, selectionArgs);            }        }        // MediaStore (and general)        else if ("content".equalsIgnoreCase(uri.getScheme())) {            // Return the remote address            if (isGooglePhotosUri(uri))                return uri.getLastPathSegment();            return getDataColumn(context, uri, null, null);        }        // File        else if ("file".equalsIgnoreCase(uri.getScheme())) {            return uri.getPath();        }        return null;    }    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {        Cursor cursor = null;        final String column = "_data";        final String[] projection = {column};        try {            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);            if (cursor != null && cursor.moveToFirst()) {                final int index = cursor.getColumnIndexOrThrow(column);                return cursor.getString(index);            }        } finally {            if (cursor != null)                cursor.close();        }        return null;    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is ExternalStorageProvider.     */    private static boolean isExternalStorageDocument(Uri uri) {        return "com.android.externalstorage.documents".equals(uri.getAuthority());    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is DownloadsProvider.     */    private static boolean isDownloadsDocument(Uri uri) {        return "com.android.providers.downloads.documents".equals(uri.getAuthority());    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is MediaProvider.     */    private static boolean isMediaDocument(Uri uri) {        return "com.android.providers.media.documents".equals(uri.getAuthority());    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is Google Photos.     */    private static boolean isGooglePhotosUri(Uri uri) {        return "com.google.android.apps.photos.content".equals(uri.getAuthority());    }}

好了,今天就分享到这里,谢谢~~

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Android(安卓)studio 通过xml文件设置点击按钮按钮时更换背景,松
  6. [知识] ADB工具(Android(安卓)Debug Bridge) 详解,使用方法
  7. Android(安卓)真机布局查看
  8. 使用Git之后出现android library引用失败
  9. android provider 基础介绍

随机推荐

  1. Android(安卓)客户端通过内置API(HttpClie
  2. android开发新浪微博客户端
  3. Android 手绘 - 支持保存为图片
  4. Android常用控件之ExpandableList的使用
  5. Windows Mobile 和 Android(安卓)对比分
  6. Activity 属性设置大全
  7. 解决gradle下载慢,下载失败的办法
  8. android创建漂亮对话框
  9. Android 4.0 开发者指南(27) —— Resour
  10. Android+JNI调用–文件操作