当前位置:   article > 正文

Android调用相机与相册的方法

Android调用相机与相册的方法

操作流程

点击拍摄

点击头像(我这里使用的是ImageView控件),然后点击拍摄,去申请权限,允许则打开相机 拍摄 然后进去裁剪框 选取合适的位置合适的大小 点击√,即设置成功

效果图

在这里插入图片描述

点击相册选择

点击头像,点击相册选择,允许权限则进去图库,选择图片 截取图片,设置成功

效果图

在这里插入图片描述

拒绝权限的情况

点击禁止则无操作,勾选禁止后不再提示,则弹出自定义dialog提示框,点击取消即关闭dialog,点击去设置则进入应用设置页面

效果图

在这里插入图片描述

功能实现

项目配置

1.先在项目根目录的build.gradle的repositories添加:

allprojects {
     repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

【注意】切记不要跳过这一步,因为XUI目前只发布在jitpack平台上,跳过这一步会导致ERROR: Failed to resolve: com.github.xuexiangjys:XUI:x.x.x错误!!!

2.在build.gradle(:app)的dependencies添加:

	// 裁剪相关
    implementation 'com.github.yalantis:ucrop:2.2.6'
    // XUI dialog相关
    implementation 'com.github.xuexiangjys:XUI:1.1.9'
    implementation 'com.github.xuexiangjys.XUtil:xutil-core:2.0.0'
    // 权限相关
    implementation 'com.yanzhenjie:permission:2.0.2'
    // 加载图片
    implementation 'com.github.bumptech.glide:glide:4.13.1'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.添加提示dialog样式

如果使用弹出提示的XUI自定义dialog则需要在AndroidManifest.xml中application的主题添加样式
在这里插入图片描述

添加以下样式:

<style name="Theme.HeadPhotoTest" parent="XUITheme.Phone">

    <!-- 自定义自己的主题样式 -->

    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:textAllCaps">false</item>

</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后Ctrl点进colors.xml添加以下属性:

<color name="colorPrimary">#2196F3</color>
<color name="colorPrimaryDark">#121C4C</color>
<color name="colorAccent">#2196F3</color>
  • 1
  • 2
  • 3

4.添加底部dialog样式

如果需要使用底部弹出dialog则需要在AndroidManifest.xml在application的主题中添加以下样式代码:

	<!-- dialog样式 -->
    <style name="DialogTheme" parent="@android:style/Theme.Dialog">
        <!-- 边框 -->
        <item name="android:windowFrame">@null</item>
        <!-- 是否浮现在activity之上 -->
        <item name="android:windowIsFloating">true</item>
        <!-- 半透明 -->
        <item name="android:windowIsTranslucent">true</item>
        <!-- 无标题 -->
        <item name="android:windowNoTitle">true</item>
        <item name="android:background">@android:color/transparent</item>
        <!-- 背景透明 -->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 模糊 -->
        <item name="android:backgroundDimEnabled">true</item>
        <!-- 遮罩层 -->
        <item name="android:backgroundDimAmount">0.5</item>
    </style>
    
	<!-- dialog的动画 -->
    <style name="main_menu_animStyle">
        <item name="android:windowEnterAnimation">@drawable/dialog_in_anim</item>
        <item name="android:windowExitAnimation">@drawable/dialog_out_anim</item>
    </style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
底部dialog弹出动画(dialog_in_anim.xml)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fromXDelta="0"
        android:fromYDelta="1000"
        android:toXDelta="0"
        android:toYDelta="0" />
</set>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
底部dialog关闭动画(dialog_out_anim.xml)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="1000" />
</set>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.添加权限

AndroidManifest.xml中加入以下权限代码:

	<!-- 请求拍摄权限-->
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- 读写设备照片及文件-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • 1
  • 2
  • 3
  • 4

6.在AndroidManifest.xml中添加剪切activity活动

如果用到剪切功能需要添加,不用剪切功能则不需要添加

	<activity
        android:name="com.yalantis.ucrop.UCropActivity"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
  • 1
  • 2
  • 3
  • 4

代码实现

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();
                }
        );
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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();
            }
        });

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
不使用剪切框(点击拍摄直接替换)

把这个剪切方法注释掉,onActivityResult回调中的代码修改为以下方式即可
在这里插入图片描述

使用方形图片方法

圆形图片代码注释,方形图像取消注释即可
在这里插入图片描述

多选图片
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
  • 1
效果图

在这里插入图片描述

demo下载

演示demo下载

~~~~~~~~~~~~~~~~~~~

如有遗漏或有任何问题可添加博主微信反馈

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/175347
推荐阅读
相关标签
  

闽ICP备14008679号