Android調用相機、相冊上傳頭像並裁剪

Android7.0之後調用相機相冊就要申請相應的權限,所以首先要先申請相機相冊的使用權限

添加依賴:

  //動態權限申請庫
    implementation 'pub.devrel:easypermissions:1.3.0'

在MainActivity中獲取權限:

private String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
 //獲取權限
    private void getPermission() {
        if (EasyPermissions.hasPermissions(this, permissions)) {
            //已經打開權限
            Toast.makeText(this, "已經申請相關權限", Toast.LENGTH_SHORT).show();
        } else {
            //沒有打開相關權限、申請權限
            EasyPermissions.requestPermissions(this, "需要獲取您的相冊、照相使用權限", 1, permissions);
        }

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //框架要求必須這麼寫
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }


    //成功打開權限

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

        Toast.makeText(this, "相關權限獲取成功", Toast.LENGTH_SHORT).show();
    }
    //用戶未同意權限

    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        Toast.makeText(this, "請同意相關權限,否則功能無法使用", Toast.LENGTH_SHORT).show();
    }

然後在onCreate()方法中 調用getPermission()來申請權限。

配置Manifest.xml:

首先是配置必要的權限

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--調用相機權限-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <uses-permission android:name="android.permission.CAMERA" />

然後是添加provider


        <provider
        android:name="android.support.v4.content.FileProvider"

        android:authorities="你的包名.fileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
            <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"
            />
        </provider>

因爲我的項目的sdk版本爲29,因此會有不一樣:

如果sdk版本是29的話,要在MainActivity中添加以下代碼解決閃退問題:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy(builder.build());
        }

這裏引用了一個資源文件file_paths,需要在res裏面添加:

file_paths:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="camera_photos" path="."  /> <!--.代表任意目錄-->
</paths>

下面是完整代碼:

activity_main.xml很簡單,就一個圖片:

<?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"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>

</LinearLayout>

MainActivity.java:

package com.example.uploadicon;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import pub.devrel.easypermissions.EasyPermissions;

public class MainActivity extends AppCompatActivity {
    private String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private ImageView iv_icon;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getPermission();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy(builder.build());
        }
        iv_icon = findViewById(R.id.iv_icon);
        iv_icon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showListDialog();
            }
        });
    }


    //獲取權限
    private void getPermission() {
        if (EasyPermissions.hasPermissions(this, permissions)) {
            //已經打開權限
            Toast.makeText(this, "已經申請相關權限", Toast.LENGTH_SHORT).show();
        } else {
            //沒有打開相關權限、申請權限
            EasyPermissions.requestPermissions(this, "需要獲取您的相冊、照相使用權限", 1, permissions);
        }

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //框架要求必須這麼寫
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }


    //成功打開權限

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

        Toast.makeText(this, "相關權限獲取成功", Toast.LENGTH_SHORT).show();
    }
    //用戶未同意權限

    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        Toast.makeText(this, "請同意相關權限,否則功能無法使用", Toast.LENGTH_SHORT).show();
    }


    private void showListDialog() {
        final String[] items = { "拍照","從相冊中選擇" };
        AlertDialog.Builder listDialog =
                new AlertDialog.Builder(this);
        listDialog.setTitle("更改頭像");
        listDialog.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // which 下標從0開始
                // ...To-do

                switch (which){
                    case 0:
                        selectCamera();
                        break;

                    case 1:
                        selectPhoto();
                        break;
                }

            }
        });
        listDialog.show();
    }



    private static final int GET_BACKGROUND_FROM_CAPTURE_RESOULT = 1;
    private static final int RESULT_REQUEST_CODE = 2;
    private static final int TAKE_PHOTO =3;
    private Uri photoUri;   //相機拍照返回圖片路徑
    private File outputImage;

    //選擇相機
    private void selectCamera(){

        //創建file對象,用於存儲拍照後的圖片,這也是拍照成功後的照片路徑
        outputImage = new File(this.getExternalCacheDir(),"camera_photos.jpg");
        try {
            //判斷文件是否存在,存在刪除,不存在創建
            if (outputImage.exists()){
                outputImage.delete();
            }
            outputImage.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        photoUri = Uri.fromFile(outputImage);

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        startActivityForResult(intent, TAKE_PHOTO);

    }


    public static final String STR_IMAGE = "image/*";
    //選擇相冊
    private void selectPhoto(){

        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, STR_IMAGE);
        startActivityForResult(intent, GET_BACKGROUND_FROM_CAPTURE_RESOULT);


    }


    private Uri cropImgUri;

    //裁剪圖片
    public void cropRawPhoto(Uri uri) {
        //創建file文件,用於存儲剪裁後的照片
        File cropImage = new File(Environment.getExternalStorageDirectory(), "crop_image.jpg");
        String path = cropImage.getAbsolutePath();
        try {
            if (cropImage.exists()) {
                cropImage.delete();
            }
            cropImage.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        cropImgUri = Uri.fromFile(cropImage);
        Intent intent = new Intent("com.android.camera.action.CROP");
//設置源地址uri
        intent.setDataAndType(photoUri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 200);
        intent.putExtra("outputY", 200);
        intent.putExtra("scale", true);
//設置目的地址uri
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cropImgUri);
//設置圖片格式
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("return-data", false);
        intent.putExtra("noFaceDetection", true); // no face detection
        startActivityForResult(intent, RESULT_REQUEST_CODE);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (resultCode != RESULT_OK) return;

        switch (requestCode){

            case GET_BACKGROUND_FROM_CAPTURE_RESOULT:   //相冊返回
                photoUri = data.getData();
                cropRawPhoto(photoUri);
                break;


            case TAKE_PHOTO://   拍照返回
                cropRawPhoto(photoUri);
                break;

            case RESULT_REQUEST_CODE:   //裁剪完照片
                if (cropImgUri !=null) {
                    try {
                        Bitmap headImage = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(cropImgUri));
                        iv_icon.setImageBitmap(headImage);

                        getFile(headImage); //把Bitmap轉成File
//                        UpLoadIcon(getFile(headImage));   //上傳圖片文件到服務器


                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }else {
                    Toast.makeText(this,"cropImgUri爲空!",Toast.LENGTH_SHORT).show();
                }
                break;

        }


        super.onActivityResult(requestCode, resultCode, data);


    }

    //把bitmap轉成file
    public File getFile(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
        File file = new File(Environment.getExternalStorageDirectory() + "/temp.jpg");
        try {
            file.createNewFile();
            FileOutputStream fos = new FileOutputStream(file);
            InputStream is = new ByteArrayInputStream(baos.toByteArray());
            int x = 0;
            byte[] b = new byte[1024 * 100];
            while ((x = is.read(b)) != -1) {
                fos.write(b, 0, x);
            }
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }



}

demo鏈接:https://download.csdn.net/download/qq_38306233/11655962

暫時沒有git,有空再看下怎麼上傳git,沒搞過不會哈哈哈哈哈。

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