Android 拍照7.0适配(源码)

Android 拍照7.0适配(源码)

从Android 7.0开始,一个应用提供自身文件给其它应用使用时,如果给出一个file://格式的URI的话,应用会抛出FileUriExposedException。

解决方法:FileProvider方式


源码(没封装)

public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks{
    @BindView(R.id.bt_choice)
    TextView bt_choice;
    @BindView(R.id.bt_take)
    TextView bt_take;
    @BindView(R.id.ll_select)
    LinearLayout ll_select;
    @BindView(R.id.iv_test)
    ImageView iv_test;

    private static String photoName;

    private static File f_save;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @OnClick({R.id.bt_take,R.id.bt_choice})
    public void onClick(View view){
        switch (view.getId()){
            case R.id.bt_choice:
                if(hasMashroom()){
                    EasyPermissions.requestPermissions(this,"需要访问网络",2000,new String[] {
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE});
                    chosePhoto(MainActivity.this,1);
                }else {
                    chosePhoto(MainActivity.this,1);
                }
                break;
            case R.id.bt_take:
                if(hasMashroom()){
                    EasyPermissions.requestPermissions(this,"需要访问网络",2000,new String[] {Manifest
                            .permission.CAMERA,
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE});
                    takePhoto(MainActivity.this,2);
                }else {
                    takePhoto(MainActivity.this,2);
                }
                break;
        }
    }

    public static boolean hasMashroom() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {

    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {

    }
    private static void takePhoto(Activity activity, int cameraRequestCode){
        Intent intent1 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // 下面这句指定调用相机拍照后的照片存储的路径
        Uri uri;
        String path = Environment.getExternalStorageDirectory()+ "/mycap/";
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
        photoName=System.currentTimeMillis()+".jpg";
        f_save = new File(path, photoName);
        if (hasMashroom()) {
            intent1.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            uri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName()+ ".provider", f_save);

        } else {
            uri = Uri.fromFile(f_save);
        }

        intent1.putExtra(MediaStore.EXTRA_OUTPUT, uri);


        activity.startActivityForResult(intent1, cameraRequestCode);
    }

    private static void chosePhoto(Activity activity,int photoRequestCode){

        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        //  activity.startActivityForResult(intent, photoRequestCode);
        ComponentName componentName = intent.resolveActivity(activity.getPackageManager());
        if (componentName != null) {
            activity.startActivityForResult(intent, photoRequestCode);
        }
    }
    Uri cropUri;
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case 2:
                cropUri = cropPicture(MainActivity.this,f_save);
                if(null == data){
                    Log.i("info", "======拍照回来=data=null==22222222");
                }else {
                    if (null == data && null == data.getData()) {
                        Log.i("info", "======拍照回来=data.getData()=nullo==");
                    } else {
                        if (null == parsePicturePath(this, data.getData())) {
                            Log.i("info", "======拍照回来获取路径null==");
                        }
                    }
                }
                break;
            case 1:
                if (data != null){
                    cropUri = cropPicture(this,new File(parsePicturePath(this, data.getData())));
                 }
                break;
                default:break;
        }
    }

    public static Uri cropPicture(Activity mActivity,File file) {
        //        String cropImageName = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault()).format(new Date()) +
        //                "-1-" + System.currentTimeMillis() + ".jpg";
        //file 是资源
        String cropImageName ="mycropimge.jpg";
        String path=mActivity.getExternalCacheDir()+"/basePic/";
        File pathFile=new File(path);
        //这里要创建目录 不然部分手机不支持
        if (!pathFile.exists())
        {
            pathFile.mkdirs();
        }

        File cropFile = new File(pathFile, cropImageName);



        Intent intent = new Intent("com.android.camera.action.CROP");

        //注意到此处使用的file:// uri类型.
        //Uri cropUri= Uri.fromFile(cropFile);
        Uri cropUri ;//剪裁
        Uri sourceUri;//资源

        if (hasMashroom()) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            sourceUri = FileProvider.getUriForFile(mActivity, mActivity.getApplicationContext().getPackageName()+ ".provider", file);
            //            sourceUri  = getImageContentUri(mActivity, file);
            cropUri= Uri.fromFile(cropFile);
        } else {
            sourceUri= Uri.fromFile(file);
            cropUri = Uri.fromFile(cropFile);
        }

        intent.setDataAndType(sourceUri, "image/*"); //此处有问题
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 200);
        intent.putExtra("outputY", 200);
        intent.putExtra("return-data", true);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        ComponentName componentName = intent.resolveActivity(mActivity.getPackageManager());
        if (componentName != null) {
            mActivity.startActivityForResult(intent, 3);
        }
        return cropUri;
    }


    public static String parsePicturePath(Context context, Uri uri) {

        if (null == context || uri == null)
            return null;

        boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        // DocumentUri
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageDocumentsUri
            if (isExternalStorageDocumentsUri(uri)) {
                String docId = DocumentsContract.getDocumentId(uri);
                String[] splits = docId.split(":");
                String type = splits[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + File.separator + splits[1];
                }
            }
            // DownloadsDocumentsUri
            else if (isDownloadsDocumentsUri(uri)) {
                String docId = DocumentsContract.getDocumentId(uri);
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                return getDataColumn(context, contentUri, null, null);
            }
            // MediaDocumentsUri
            else if (isMediaDocumentsUri(uri)) {
                String docId = DocumentsContract.getDocumentId(uri);
                String[] split = docId.split(":");
                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;
                }
                String selection = "_id=?";
                String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            if (isGooglePhotosContentUri(uri))
                return uri.getLastPathSegment();
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;

    }

    private static boolean isExternalStorageDocumentsUri(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    private static boolean isDownloadsDocumentsUri(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    private static boolean isMediaDocumentsUri(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    private static boolean isGooglePhotosContentUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {

        Cursor cursor = null;
        String column = "_data";
        String[] projection = {column};
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            try {
                if (cursor != null)
                    cursor.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;

    }
}

布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context="com.youngch.android.taskphoto.MainActivity">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="vertical">
            <ImageView
                android:layout_width="200dp"
                android:layout_height="200dp"
                android:id="@+id/iv_test"
                android:background="@mipmap/ic_launcher"/>
            <LinearLayout
                android:layout_width="match_parent"
                android:orientation="vertical"
                android:id="@+id/ll_select"
                android:layout_height="wrap_content">
                <TextView
                    android:layout_width="match_parent"
                    android:textSize="18sp"
                    android:gravity="center"
                    android:layout_marginTop="10dp"
                    android:layout_height="wrap_content"
                    android:background="@color/colorPrimary"
                    android:id="@+id/bt_take"
                    android:text="拍照"/>
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textSize="18sp"
                    android:layout_marginTop="10dp"
                    android:background="@color/colorAccent"
                    android:gravity="center"
                    android:id="@+id/bt_choice"
                    android:text="选择照片"/>
            </LinearLayout>
        </LinearLayout>
    </ScrollView>
</LinearLayout>

文件路径设置

在项目res文件夹下创建xml文件夹
这里写图片描述

在里面新建file_path.xml文件,如上图

文件中的内容为:

<?xml version="1.0" encoding="utf-8"?>
    <paths>
    <external-path name="external_files" path="."/>
    <cache-path
        name="cache_files"
        path="."/>
    </paths>

清单文件设置

在application标签下配置provider,如下

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

代码关联就是在上面源码中的这一句

 uri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName()+ ".provider", f_save);

路还很长,慢慢走

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值