Android 实现头像修改(拍照+图库 裁剪),适配兼容7.0 8.0 9.0

目前在Android 应用中几乎都会有个人中心的界面,那么也就会有修改头像的基础功能,下面是我从项目中抽取的头像修改的核心代码,实现了拍照、图库两种方式,实现了裁剪功能,并且适配了7.0、8.0、9.0的系统。

1、在AndroidManifest.xml中配置

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.thinta.testwork.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths_public" />
</provider>

2、在res中配置

在res目录下新建xml文件夹,新建一个名为file_paths_public的xml文件,文件内容如下:

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

3、核心代码

 /**
     * 获取图片
     * @param activity 上下文
     * @param i 0为图库 1为拍照
     */
    private fun getPhoto(activity: Activity, i: Int) {
        when (i) {
            0 -> {

                var intent = Intent()
                intent.setType("image/*")
                intent.setAction(Intent.ACTION_GET_CONTENT);
                activity.run {
                    startActivityForResult(intent, 100)
                }


            }
            1 -> {
                var cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                if (cameraIntent.resolveActivity(mActivity.getPackageManager()) != null) {
                    mTmpFile =
                        File(FileUtils.createRootPath(mActivity) + "/" + System.currentTimeMillis() + ".jpg")
                    FileUtils.createFile(mTmpFile)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        cameraIntent.putExtra(
                            MediaStore.EXTRA_OUTPUT,
                            FileProvider.getUriForFile(
                                mActivity,
                               "com.thinta.testwork.fileprovider",
                                mTmpFile
                            )
                        );
                    } else {
                        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
                    }
                    activity.startActivityForResult(cameraIntent, 101)
                }
            }
        }
    }



fun getPhotoPath(requestCode: Int, resultCode: Int, data: Intent?) {
        if(resultCode == Activity.RESULT_OK){
            when(requestCode){
                100 -> {
                    val imagePath: String? = handleImage(data)
                    crop(imagePath!!)

                }
                101 -> {
                    crop(mTmpFile.absolutePath)
                }

                102 -> {
                    mphotoView.setImageURI(Uri.fromFile(mCropImageFile))
                }
            }
        }

    }

//获取裁剪的图片保存地址
    fun getmCropImageFile(): File? {
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            //File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),"temp.jpg");
            val file = File(
                mActivity.getExternalCacheDir(),
                System.currentTimeMillis().toString() + ".jpg"
            )
            return file
        }
        return null

    }

    fun getImageContentUri(file: File): Uri? {
        var filePath = file.absolutePath;
        var cursor = mActivity.contentResolver.query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            arrayOf(MediaStore.Images.Media._ID),
            MediaStore.Images.Media.DATA + "=? ",
            arrayOf(filePath), null
        )

        if (cursor != null && cursor.moveToFirst()) {
            var id = cursor.getInt(
                cursor
                    .getColumnIndex(MediaStore.MediaColumns._ID)
            )
            var baseUri = Uri.parse("content://media/external/images/media");
            return Uri.withAppendedPath(baseUri, "" + id);
        } else {
            if (file.exists()) {
                var values = ContentValues();
                values.put(MediaStore.Images.Media.DATA, filePath);
                return mActivity.getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
                );
            } else {
                return null;
            }
        }
    }

    fun crop(imagePath: String) {
        mCropImageFile = getmCropImageFile()!!
        val intent = Intent("com.android.camera.action.CROP");
        intent.setDataAndType(getImageContentUri(File(imagePath)), "image/*");
        intent.putExtra("crop", true);
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 500);
        intent.putExtra("outputY", 500);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCropImageFile))
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        mActivity.startActivityForResult(intent, 102);
    }


    fun getImagePath(uri: Uri?, selection: String?): String {
        var path= "" ;
        var cursor = mActivity.getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)) as String
            }
            cursor.close();
        }
        return path;
    }

    fun handleImage(data: Intent?): String {

        var  uri = data!!.getData();
        var imagePath = "";
        if (Build.VERSION.SDK_INT >= 19) {
            if (DocumentsContract.isDocumentUri(mActivity, uri)) {
                var  docId = DocumentsContract.getDocumentId(uri);
                if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
                    var id = docId.split(":")[1];
                    var selection = MediaStore.Images.Media._ID + "=" + id;
                    imagePath =
                        getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection)
                } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                    var contentUri = ContentUris.withAppendedId(Uri.parse("" +
                            "content://downloads/public_downloads"), docId.toLong(10))
                    imagePath = getImagePath(contentUri, null)
                }
            } else if ("content".equals(uri.getScheme())) {
                imagePath = getImagePath(uri, null)
            }
        } else {
            imagePath = getImagePath(uri, null)
        }
        return imagePath;
    }

4、FileUtils工具类

package com.thinta.testwork.util;


import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.util.Log;

import java.io.File;
/*****************************************************
 * 版权信息: 
 * 创建作者: 
 * 创建日期: 
 * ****************************************************
 * 更改记录: 更新人:    更新时间:    更新概要:
 *
 * ****************************************************
 *  类功能说明:
 * ****************************************************/
public class FileUtils {
    private static final String TAG = FileUtils.class.getSimpleName();

    /**
     * 创建根缓存目录
     *
     * @return
     */
    public static String createRootPath(Context context) {
        String cacheRootPath = "";
        if (isSdCardAvailable()) {
            // /sdcard/Android/data/<application package>/cache
            cacheRootPath = context.getExternalCacheDir().getPath();
        } else {
            // /data/data/<application package>/cache
            cacheRootPath = context.getCacheDir().getPath();
        }
        return cacheRootPath;
    }

    public static boolean isSdCardAvailable() {
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    }

    /**
     * 递归创建文件夹
     *
     * @param dirPath
     * @return 创建失败返回""
     */
    public static String createDir(String dirPath) {
        try {
            File file = new File(dirPath);
            if (file.getParentFile().exists()) {
                Log.i(TAG, "----- 创建文件夹" + file.getAbsolutePath());
                file.mkdir();
                return file.getAbsolutePath();
            } else {
                createDir(file.getParentFile().getAbsolutePath());
                Log.i(TAG, "----- 创建文件夹" + file.getAbsolutePath());
                file.mkdir();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dirPath;
    }

    /**
     * 递归创建文件夹
     *
     * @param file
     * @return 创建失败返回""
     */
    public static String createFile(File file) {
        try {
            if (file.getParentFile().exists()) {
                Log.i(TAG, "----- 创建文件" + file.getAbsolutePath());
                file.createNewFile();
                return file.getAbsolutePath();
            } else {
                createDir(file.getParentFile().getAbsolutePath());
                file.createNewFile();
                Log.i(TAG, "----- 创建文件" + file.getAbsolutePath());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String getApplicationId(Context appContext) throws IllegalArgumentException {
        ApplicationInfo applicationInfo = null;
        try {
            applicationInfo = appContext.getPackageManager().getApplicationInfo(appContext.getPackageName(), PackageManager.GET_META_DATA);
            if (applicationInfo == null) {
                throw new IllegalArgumentException(" get application info = null, has no meta data! ");
            }
            Log.d(TAG, appContext.getPackageName() + " " + applicationInfo.metaData.getString("APP_ID"));
            return applicationInfo.metaData.getString("APP_ID");
        } catch (PackageManager.NameNotFoundException e) {
            throw new IllegalArgumentException(" get application info error! ", e);
        }
    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值