Android调用相机与相册的方法2

简介: Android调用相机与相册的方法

Android调用相机与相册的方法1:https://developer.aliyun.com/article/1473506

代码实现

DialogManager.java

package top.gaojc.util;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;

import com.xuexiang.xui.widget.dialog.DialogLoader;

import static com.xuexiang.xutil.app.ActivityUtils.startActivity;

public class DialogManager {

    // 请求权限对话框
    public static void permissionDialog(Context myContext, String str) {
        DialogLoader.getInstance().showConfirmDialog(
                myContext, "提示", str, "去设置",
                (dialog, which) -> {
                    //引导用户到设置中去进行设置
                    Intent intent = new Intent();
                    intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                    intent.setData(Uri.fromParts("package", myContext.getPackageName(), null));
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                    dialog.dismiss();
                },
                "取消",
                (dialog, which) -> {
                    dialog.dismiss();
                }
        );
    }
}

dialog_bottom_menu.xml

底部dialog:dialog_bottom_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_take_photo"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="拍摄"
        android:textColor="@android:color/background_dark"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@android:color/darker_gray" />

    <TextView
        android:id="@+id/tv_take_pic"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="相册选择"
        android:textColor="@android:color/background_dark"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:background="@android:color/darker_gray" />

    <TextView
        android:id="@+id/tv_cancel"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="取消"
        android:textColor="@android:color/background_dark"
        android:textSize="16sp" />

</LinearLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/img"
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:layout_gravity="center"
        android:background="@drawable/img"/>

</FrameLayout>

MainActivity.java

package top.gaojc;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.request.RequestOptions;
import com.gaojc.top.util.DialogManager;
import com.yalantis.ucrop.UCrop;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.runtime.Permission;

import java.io.File;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.content.FileProvider;

public class MainActivity extends Activity {

    private ImageView img;

    public static final int REQUEST_CODE_CAMERA = 103; //相机
    public static final int REQUEST_CODE_ALBUM = 102; //相册

    private Uri photoUri;//记录图片地址

    private Context context = MainActivity.this;

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

        img = findViewById(R.id.img);

        img.setOnClickListener(v -> {
            // 底部dialog
            showBottomDialog();
        });
    }

    // 判断是否有相机权限
    private void ifHaveCameraPermission() {
        /**
         * AndPermission.hasPermissions:判断是否有相对应的权限
         *      Permission.Group.CAMERA:摄像权限
         */
        if (!AndPermission.hasPermissions(this, Permission.Group.CAMERA)) {
            /**
             * AndPermission:引用权限相关库
             *      onGranted:允许权限
             *      onDenied:拒绝权限
             */
            // 动态申请权限
            AndPermission.with(this).runtime().permission(Permission.Group.CAMERA)
                    .onGranted(permissions -> {
                        openCamera();
                    })
                    .onDenied(denieds -> {
                        if (denieds != null && denieds.size() > 0) {
                            for (int i = 0; i < denieds.size(); i++) {
                                if (!shouldShowRequestPermissionRationale(denieds.get(i))) {
                                    DialogManager.permissionDialog(this, "没有拍摄和录制权限!");
                                    break;
                                }
                            }
                        }
                    }).start();
        } else {
            // 有权限 打开相机
            openCamera();
        }
    }

    // 打开相机
    private void openCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Build.VERSION.SDK_INT:获取当前系统sdk版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // 适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri
            String fileName = String.format("fr_crop_%s.jpg", System.currentTimeMillis());
            File cropFile = new File(this.getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName);
            photoUri = FileProvider.getUriForFile(this, this.getPackageName() + ".FileProvider", cropFile);//7.0
        } else {
            photoUri = getDestinationUri();
        }
        // android11以后强制分区存储,外部资源无法访问,所以添加一个输出保存位置,然后取值操作
        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        startActivityForResult(intent, REQUEST_CODE_CAMERA);
    }

    // 判断是否有文件存储权限
    private void ifHaveAlbumPermission(Activity activity) {
        //  Permission.Group.STORAGE:文件存储权限
        if (!AndPermission.hasPermissions(activity, Permission.Group.STORAGE)) {
            // Request permission
            AndPermission.with(activity).runtime().permission(Permission.Group.STORAGE).onGranted(permissions -> {
                openAlbum();
            }).onDenied(denieds -> {
                if (denieds != null && denieds.size() > 0) {
                    for (int i = 0; i < denieds.size(); i++) {
                        if (!activity.shouldShowRequestPermissionRationale(denieds.get(i))) {
                            DialogManager.permissionDialog(activity, "没有访问存储权限!");
                            break;
                        }
                    }
                }
            }).start();
        } else {
            openAlbum();
        }
    }

    // 打开相册
    private void openAlbum() {
        Intent intent = new Intent();
        // intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);//支持多选图片
        intent.setType("image/*");
        intent.setAction("android.intent.action.GET_CONTENT");
        intent.addCategory("android.intent.category.OPENABLE");
        startActivityForResult(intent, REQUEST_CODE_ALBUM);
    }


    @RequiresApi(api = Build.VERSION_CODES.Q)
    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case REQUEST_CODE_ALBUM:
                    doCrop(data.getData());
                    break;
                case REQUEST_CODE_CAMERA:
                    doCrop(photoUri);
                    break;
                case UCrop.REQUEST_CROP:
                    // 加载圆形图片
                    Glide.with(context).load(UCrop.getOutput(data)).apply(RequestOptions.bitmapTransform(new CircleCrop())).into(img);
//                    Glide.with(context).load(UCrop.getOutput(data)).into(img);//方形图像
                    break;
            }
        }
        if (resultCode == UCrop.RESULT_ERROR) {
            final Throwable cropError = UCrop.getError(data);
        }
    }

    // 裁剪方法
    private void doCrop(Uri data) {
        UCrop.of(data, getDestinationUri())//当前资源,保存目标位置
                .withAspectRatio(1f, 1f)//宽高比
                .withMaxResultSize(500, 500)//宽高
                .start(this);
    }

    private Uri getDestinationUri() {
        String fileName = String.format("fr_crop_%s.jpg", System.currentTimeMillis());
        File cropFile = new File(this.getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName);
        return Uri.fromFile(cropFile);
    }

    private void showBottomDialog() {
        // 使用Dialog、设置style
        final Dialog dialog = new Dialog(this, R.style.DialogTheme);
        // 设置布局
        View view = View.inflate(this, R.layout.dialog_bottom_menu, null);
        dialog.setContentView(view);

        Window window = dialog.getWindow();
        // 设置弹出位置
        window.setGravity(Gravity.BOTTOM);
        // 设置弹出动画
        window.setWindowAnimations(R.style.main_menu_animStyle);
        // 设置对话框大小
        window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        dialog.show();

        dialog.findViewById(R.id.tv_take_photo).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 判断是否有相机权限
                ifHaveCameraPermission();
                dialog.dismiss();
            }
        });

        dialog.findViewById(R.id.tv_take_pic).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 判断是否有文件存储权限
                ifHaveAlbumPermission((Activity) context);
                dialog.dismiss();
            }
        });

        dialog.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.dismiss();
            }
        });

    }
}
目录
相关文章
|
3月前
|
存储 Shell Android开发
基于Android P,自定义Android开机动画的方法
本文详细介绍了基于Android P系统自定义开机动画的步骤,包括动画文件结构、脚本编写、ZIP打包方法以及如何将自定义动画集成到AOSP源码中。
62 2
基于Android P,自定义Android开机动画的方法
|
3月前
|
Android开发
基于android-11.0.0_r39,系统应用的手动签名方法和过程
本文介绍了基于Android 11.0.0_r39版本进行系统应用手动签名的方法和解决签名过程中遇到的错误,包括处理`no conscrypt_openjdk_jni-linux-x86_64`和`RegisterNatives failed`的问题。
142 2
|
4天前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
29 15
Android 系统缓存扫描与清理方法分析
|
2月前
|
ARouter 测试技术 API
Android经典面试题之组件化原理、优缺点、实现方法?
本文介绍了组件化在Android开发中的应用,详细阐述了其原理、优缺点及实现方式,包括模块化、接口编程、依赖注入、路由机制等内容,并提供了具体代码示例。
39 2
|
3月前
|
Android开发
Android在rootdir根目录创建自定义目录和挂载点的方法
本文介绍了在Android高通平台的根目录下创建自定义目录和挂载点的方法,通过修改Android.mk文件并使用`LOCAL_POST_INSTALL_CMD`变量在编译过程中添加目录,最终在ramdisk.img的系统根路径下成功创建了`/factory/bin`目录。
156 1
|
3月前
|
开发工具 uml git
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
本文分享了下载AOSP源码的方法,包括如何使用repo工具和处理常见的repo sync错误,以及配置Python环境以确保顺利同步特定版本的AOSP代码。
332 0
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
|
3月前
|
测试技术 API Android开发
Android经典实战之简化 Android 相机开发:CameraX 库的全面解析
CameraX是Android Jetpack的一个组件,旨在简化相机应用开发,提供了易于使用的API并支持从Android 5.0(API级别21)起的设备。其主要特性包括广泛的设备兼容性、简洁的API、生命周期感知、简化实现及方便的集成与测试。通过简单的几个步骤即可实现如拍照、视频录制等功能。此外,还提供了最佳实践指导以确保应用的稳定性和性能。
56 0
|
3月前
|
Android开发
Android项目架构设计问题之onFirstItemVisibleChanged方法的调用如何解决
Android项目架构设计问题之onFirstItemVisibleChanged方法的调用如何解决
38 0
|
21天前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
5天前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
21 5