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

使用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();
}
//权限申请的回调
@Override
public 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
 */
@Override
protected 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值