Android 10 調用系統圖庫和相機 裁剪 並且返回圖片

Android 10上動用相機和圖庫 並且返回裁剪圖片遇到的問題 記錄一下:各種報錯,

1.exposed beyond app through Intent.getData()

2.java.lang.IllegalArgumentException: URI is not absolute

3.android.os.FileUriExposedException: file:///storage/emulated/0

4.exposed beyond app through ClipData.Item.getUri()

網上找了一大圈,報錯原因 大概如下 ,動態權限沒有申請, Android N(對應sdk24)(版本7.0)及以上對訪問文件權限收回,還有其他之類的錯誤原因,直接上代碼 ,在Android 10 ,Android 8.1,Android5.1真機上已驗證ok

AndroidManifest.xml新增 code

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

file_paths文件 path=".",我的理解是Environment.getExternalStorageDirectory()所在的目錄,name可以任意取

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">

    <external-path
        name="images"
        path="."/>
</paths>

 

類代碼

package test.xxx.com.myapplication;

import android.Manifest;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
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.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;


public class AddM1Activity extends AppCompatActivity {

    private EditText name1;
    private EditText number1;
    private ImageView icon;
    private Button bt_save, bt_cancel;
    private AlertDialog.Builder builder;
    private AlertDialog dialog;
    public static final int NONE = 0;
    public static final int CAMERA = 11;// 拍照
    public static final int PHOTO =22;
    public static final int CAMERAZOOM = 33; // 相機拍照縮放
    public static final int PHOTOZOOM = 44;//照片縮放
    public static final int PHOTORESOULT = 55;// 結果
    public static final String IMAGE_UNSPECIFIED = "image/*";
    private static final String TAG = "AddM1Activity";

    private static final int WRITE_PERMISSION = 0x01;
    private Uri uritempFile=null;




    private String cameraSavePath=null;



    String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STORAGE};
    List<String> mPermissionList = new ArrayList<>();
    private static final int PERMISSION_REQUEST = 1010;


    private void initPermission(){
        mPermissionList.clear();
        /**
         * 判斷哪些權限未授予
         */
        for (int i = 0; i < permissions.length; i++) {
            if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                mPermissionList.add(permissions[i]);
            }
        }
        /**
         * 判斷是否爲空
         */
        if (mPermissionList.isEmpty()) {//未授予的權限爲空,表示都授予了
        } else {//請求權限方法
            String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//將List轉爲數組
            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST);
        }
    }


    private Message message = null;
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1000:
                    Bitmap bitmap = (Bitmap) msg.obj;

                    icon.setImageBitmap(bitmap);

                    break;
                case 1001:
                    icon.setImageBitmap(BitmapFactory.decodeResource(
                            getResources(), R.mipmap.ic_add_contact_holo_light));

                default:
                    break;
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_m1);
        name1 = (EditText) findViewById(R.id.quick_name);
        number1 = (EditText) findViewById(R.id.quick_number);
        icon = (ImageView) findViewById(R.id.iv_icon);
        bt_save = (Button) findViewById(R.id.bt_save);
        bt_cancel = (Button) findViewById(R.id.bt_cancel);

        initPermission();




        File f = new File(Environment.getExternalStorageDirectory()
                , "qwert.jpg");
        if (f.exists()) {
            // Bitmap bitmap=BitmapFactory.decodeFile(f.getPath());
            // icon.setImageBitmap(bitmap);

        }


        name1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        number1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        icon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectOperator();
            }
        });
        bt_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                
            }
        });
        bt_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }
    private void saveimage(Bitmap bmp){
        File f = new File(Environment.getExternalStorageDirectory()
                , "qwert.jpg");
        try {
            FileOutputStream fos = new FileOutputStream(f);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
            System.out.println("111111111111111111==="+f.length());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        Intent intent =getIntent();
        String action=intent.getStringExtra("android_manage_type");

        if(action!=null)
        {
            if(action.equals("add"))
            {
                setTitle(R.string.add_m1_tilte);
                name1.setText("");
                number1.setText("");
            }
        }

    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        if(dialog!=null){
            dialog.dismiss();
        }
    }



    private void openCamera(){
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        cameraSavePath =Environment.getExternalStorageDirectory()+ File.separator + "Android"+File.separator+"xx.jpg";
        File f_camera =new File(cameraSavePath);
        Uri uri_camera;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
		//test.xxx.com.myapplication.fileprovider 是在清單文件配置的 android:authorities
            uri_camera = FileProvider.getUriForFile(this, "test.xxx.com.myapplication.fileprovider", f_camera);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            System.out.println("openCamera   cameraSavePath length=="+f_camera.length());
        }else {
            uri_camera = Uri.fromFile(f_camera);
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri_camera);
        startActivityForResult(intent, CAMERA);
    }


    private void choosePhoto() {
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                IMAGE_UNSPECIFIED);
        startActivityForResult(intent, PHOTO);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST:
                break;
            default:
                break;
        }



        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    }


    private void startPhotoZoom2(Uri uri) {
        // 調用系統中自帶的圖片剪裁
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");

        uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory()+ File.separator + "Android" + "/icon_temp1.jpg");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);

        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);

        intent.putExtra("crop", "true");
        // aspectX aspectY 是寬高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪圖片寬高
        intent.putExtra("outputX", 250);
        intent.putExtra("outputY", 250);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, PHOTOZOOM);


    }

    /**
     * 調用系統裁剪的方法
     */
    private void startPhoneZoom(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intent.setDataAndType(uri, "image/*");
        //是否可裁剪
        intent.putExtra("corp", "true");
        //裁剪器高寬比
        intent.putExtra("aspectY", 1);
        intent.putExtra("aspectX", 1);
        //設置裁剪框高寬
        intent.putExtra("outputX", 150);
        intent.putExtra("outputY", 150);


     //  Uri temp =Uri.parse(cameraSavePath); //Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + System.currentTimeMillis() + ".jpg");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

            Uri temp =Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath()+ File.separator + "Android"+File.separator+"xx.jpg");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, temp);
        }


        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        //返回數據
        intent.putExtra("return-data", true);
        startActivityForResult(intent, CAMERAZOOM);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        System.out.println("onActivityResult== requestCode="+requestCode+" data ="+data);
        // 讀取相冊縮放圖片
        if (requestCode == PHOTO) {
            startPhotoZoom2(data.getData());
        }else if(requestCode==PHOTOZOOM){
            File file = null;
            try {
                file = new File(new URI(uritempFile.toString()));
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
            System.out.println("uritempFile.toString()=="+uritempFile.toString()+"  "+file.length());
            Bitmap photo = BitmapFactory.decodeFile(file.toString());
            saveimage(photo);

            message =new Message();
            message.what=1000;
            message.obj =photo;
            handler.sendMessageDelayed(message, 100);
        }else if(requestCode==CAMERAZOOM){
            Bitmap photo=null;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
                File file = null;
                Uri temp =Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath()+ File.separator + "Android"+File.separator+"xx.jpg");
                try {
                    file = new File(new URI(temp.toString()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
               photo = BitmapFactory.decodeFile(file.toString());

            }else{
                File f =new File(cameraSavePath);
                System.out.println("文件大小 =="+f.length());
               photo = BitmapFactory.decodeFile(f.toString());

            }
            saveimage(photo);
            message =new Message();
            message.what=1000;
            message.obj =photo;
            handler.sendMessageDelayed(message, 100);



            System.out.println("qqqqqqqqqq  =");


        }else if(requestCode==CAMERA){
            //相機返回結果
            File mAvatarFile = new File(cameraSavePath);
            Uri uri;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                //test.xxx.com.myapplication.fileprovider 是在清單文件配置的 android:authorities
                uri = FileProvider.getUriForFile(this, "test.xxx.com.myapplication.fileprovider", mAvatarFile);

                System.out.println("open camera 2222222 mAvatarFile length=="+mAvatarFile.length());
            }else {
                uri = Uri.fromFile(mAvatarFile);
            }
            startPhoneZoom(uri);
            System.out.println("uritempFile.toString()==");
        }

        super.onActivityResult(requestCode, resultCode, data);
    }



    private void selectOperator(){
        List<String> list = new ArrayList<String>();
        list.add(0, getString(R.string.title_gallery));
        list.add(1, getString(R.string.title_camera));
        if (new Utils(this).icon_temp_01_exists()) {
            list.add(2, getString(R.string.title_remove));
        }
        builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.slelect_title));
        builder.setItems(list.toArray(new String[list.size()]), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == 0) {

                    choosePhoto();
                } else if (which == 1) {
                    openCamera();

                }else{
                    /*new Utils(AddM1Activity.this)
                            .deleteIcon_temp_01();
                    //deleteIcon_temp();

                    message =new Message();
                    message.what=1001;
                    handler.sendMessageDelayed(message, 100);*/
                }

            }
        });
        builder.setCancelable(true);//
        builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                System.out.println("clicked----"+keyCode);
                dialog.dismiss();
                //	finish();
                return false;
            }
        });
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                System.out.println("click onCancel");

            }
        });
        builder.create().show();
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章