Android7.0系统,5.0系统,以及5.0以下系统选择本地图片路径转换问题

来源:互联网 发布:淘宝网冬季女装棉衣 编辑:程序博客网 时间:2024/06/05 04:57

使用Fileprovider之前需要在mainfest文件中配置配置如下:

<provider    android:name="android.support.v4.content.FileProvider"    android:authorities="applicationId.fileprovider"    android:exported="false"    android:grantUriPermissions="true"    >    <meta-data        android:name="android.support.FILE_PROVIDER_PATHS"        android:resource="@xml/file_paths"        /></provider>

这里依赖的是v4包下的FileProvider
applicationId.fileprovider 配置这个属性的时候要与
FileProvider.getUriForFile(this, “applicationId.fileprovider”, photoFile);方法中的要一直可以随意写
@xml/file_paths需要在res\xml\file_paths创建代码如下:

<?xml version="1.0" encoding="utf-8"?><paths xmlns:android="http://schemas.android.com/apk/res/android">    <external-path path="" name="camera_photos" />    <external-path name="my_images" path="Android/data/com.example.wmz.network/files/Pictures/" />    <external-path name="images" path="Pictures/" />    <external-path name="dcim" path="DCIM/" /></paths>

所以这篇文章写下自己当时遇到的坑,完整代码如下:

public class PhotoActivity extends Activity implements View.OnClickListener {    public Button mButton;    public Button mButtonPic;    public ImageView mImageView;    //临时文件    private String mPublicPhotoPath;    private String path;    private Uri uri;    private static final int REQ_GALLERY = 333;    private static final int REQUEST_CODE_PICK_IMAGE = 222;    public int mWidth;    public int mHeight;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_photo);        initView();    }    private void initView() {        mButton = ((Button) findViewById(R.id.bt));        mButtonPic = ((Button) findViewById(R.id.btpic));        mImageView = ((ImageView) findViewById(R.id.iv));        mButton.setOnClickListener(this);        mButtonPic.setOnClickListener(this);    }    //当点击bt的时候将获取系统的拍照功能,必将拍照之后的照片显示在ImageView中    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.bt:                //获取拍照的权限                showTakePicture();                break;            case R.id.btpic:                //获取相册中的照片                getImageFromAlbum();                break;        }    }
###这里使用的是第三方的框架动态的申请权限依赖这个库就行,用法很简单就不多去讲解了     compile 'com.lovedise:permissiongen:0.0.6'//获取拍照的权限private void showTakePicture() {    PermissionGen.with(PhotoActivity.this)            .addRequestCode(100)            .permissions(                    Manifest.permission.CAMERA,                    Manifest.permission.WRITE_EXTERNAL_STORAGE,                    Manifest.permission.READ_EXTERNAL_STORAGE            )            .request();}//权限申请的回调@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {    PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);}//权限申请成功的回调@PermissionSuccess(requestCode = 100)public void doSomething() {    //开启拍照功能    startTake();}@PermissionFail(requestCode = 100)public void doFailSomething() {    //权限申请失败的处理}private void startTake() {    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);    //判断是否有相机应用    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {        //创建临时图片文件        File photoFile = null;        try {            photoFile = createPublicImageFile();        } catch (IOException e) {            e.printStackTrace();        }        //设置Action为拍照        if (photoFile != null) {            takePictureIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);            //这里加入flag            takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);            Uri photoURI = FileProvider.getUriForFile(this, "applicationId.fileprovider", photoFile);            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);            startActivityForResult(takePictureIntent, REQ_GALLERY);        }    }    //将照片添加到相册中    galleryAddPic(mPublicPhotoPath, this);}/** * 获取相册中的图片 */public void getImageFromAlbum() {    Intent intent = new Intent(Intent.ACTION_PICK);    intent.setType("image/*");//相片类型    startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);}/** * 创建临时图片文件 * * @return * @throws IOException */private File createPublicImageFile() throws IOException {    File path = null;    if (hasSdcard()) {        path = Environment.getExternalStoragePublicDirectory(                Environment.DIRECTORY_DCIM);    }    Date date = new Date();    String timeStamp = getTime(date, "yyyyMMdd_HHmmss", Locale.CHINA);    String imageFileName = "Camera/" + "IMG_" + timeStamp + ".jpg";    File image = new File(path, imageFileName);    mPublicPhotoPath = image.getAbsolutePath();    return image;}/** * 判断sdcard是否被挂载 * * @return */public static boolean hasSdcard() {    if (Environment.getExternalStorageState().equals(            Environment.MEDIA_MOUNTED)) {        return true;    } else {        return false;    }}/** * 获取时间的方法 * @param date * @param mode * @param locale * @return */private String getTime(Date date, String mode, Locale locale) {    SimpleDateFormat format = new SimpleDateFormat(mode, locale);    return format.format(date);}/** * 将照片添加到相册中 */public static void galleryAddPic(String mPublicPhotoPath, Context context) {    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);    File f = new File(mPublicPhotoPath);    Uri contentUri = Uri.fromFile(f);    mediaScanIntent.setData(contentUri);    context.sendBroadcast(mediaScanIntent);}/** * 拍照之后获取结果的方法 * @param requestCode * @param resultCode * @param data */@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    //获取mImageView的宽高    mWidth = mImageView.getWidth();    mHeight = mImageView.getHeight();    switch (requestCode) {        //拍照        case REQ_GALLERY:            if (resultCode != Activity.RESULT_OK) return;            uri = Uri.parse(mPublicPhotoPath);            path = uri.getPath();            break;        //获取相册的图片        case REQUEST_CODE_PICK_IMAGE:            if (data == null) return;            uri = data.getData();            int sdkVersion = Integer.valueOf(Build.VERSION.SDK);            if (sdkVersion >= 19) {  // 或者 android.os.Build.VERSION_CODES.KITKAT这个常量的值是19                path = this.uri.getPath();//5.0直接返回的是图片路径 Uri.getPath is :  /document/image:46 ,5.0以下是一个和数据库有关的索引值                // path_above19:/storage/emulated/0/girl.jpg 这里才是获取的图片的真实路径                path =getPath_above19(PhotoActivity.this, this.uri);            } else {                path = getFilePath_below19(PhotoActivity.this, this.uri);            }            break;    }    mImageView.setImageBitmap(getSmallBitmap(path, mWidth, mHeight));}/** * 获取小于api19时获取相册中图片真正的uri * @param context * @param uri * @return */public static String getFilePath_below19(Context context,Uri uri) {    //这里开始的第二部分,获取图片的路径:低版本的是没问题的,但是sdk>19会获取不到    String[] proj = {MediaStore.Images.Media.DATA};    //好像是android多媒体数据库的封装接口,具体的看Android文档    Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);    //获得用户选择的图片的索引值    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);    //将光标移至开头 ,这个很重要,不小心很容易引起越界    cursor.moveToFirst();    //最后根据索引值获取图片路径   结果类似:/mnt/sdcard/DCIM/Camera/IMG_20151124_013332.jpg    String path = cursor.getString(column_index);    return path;}/** * 获取大于api19时获取相册中图片真正的uri * @param context * @param uri * @return */@TargetApi(Build.VERSION_CODES.KITKAT)public  static String getPath_above19(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;}public 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;}public static boolean isExternalStorageDocument(Uri uri) {    return "com.android.externalstorage.documents".equals(uri.getAuthority());}public static boolean isDownloadsDocument(Uri uri) {    return "com.android.providers.downloads.documents".equals(uri.getAuthority());}public static boolean isMediaDocument(Uri uri) {    return "com.android.providers.media.documents".equals(uri.getAuthority());}public static boolean isGooglePhotosUri(Uri uri) {    return "com.google.android.apps.photos.content".equals(uri.getAuthority());}/** * 图片的压缩 * @param options * @param reqWidth * @param reqHeight * @return */public 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;}/** * 根据路径获得突破并压缩返回bitmap用于显示 * @param filePath * @return */public static Bitmap getSmallBitmap(String filePath, int reqWidth, int reqHeight) {    final BitmapFactory.Options options = new BitmapFactory.Options();    //只返回图片的大小信息    options.inJustDecodeBounds = true;    BitmapFactory.decodeFile(filePath, options);    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);    options.inJustDecodeBounds = false;    return BitmapFactory.decodeFile(filePath, options);}}                               
阅读全文
1 0
原创粉丝点击