android调用相册和摄像头_网页调用摄像头拍照

android调用相册和摄像头_网页调用摄像头拍照Android调用系统的拍照,打开相册功能1添加权限:uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>uses-permissionandroid:name="android.permission.CAMERA"/>2设置标志(回传码)//

大家好,又见面了,我是你们的朋友全栈君。

Android调用系统的拍照,打开相册功能


1 添加权限:


<!-- 往SDCard写入数据权限 --> 
<uses-permission android:name="android.permission. WRITE_EXTERNAL_STORAGE" /> 
<!--请求访问使用照相设备-->
<uses-permission android:name="android.permission.CAMERA" />

2 设置标志(回传码)

 // 拍照回传码
public final static int CAMERA_REQUEST_CODE = 0;
  // 相册选择回传吗
    public final static int GALLERY_REQUEST_CODE = 1;

若多个地方使用了这个拍照功能 可以放在公共类中,设置为全局变量


3 在相应的java类中:

  // 拍照的照片的存储位置
    private String mTempPhotoPath;
    // 照片所在的Uri地址
    private Uri imageUri;

4 点击拍照事件中:
动态申请权限:

 //第二个参数是需要申请的权限
                if (ContextCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {   //权限还没有授予,需要在这里写申请权限的代码
                    // 第二个参数是一个字符串数组,里面是你需要申请的权限 可以设置申请多个权限
                    // 最后一个参数是标志你这次申请的权限,该常量在onRequestPermissionsResult中使用到
                    ActivityCompat.requestPermissions(MainActivity.this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                            GlobalVariable.CAMERA_REQUEST_CODE);

                }else { //权限已经被授予,在这里直接写要执行的相应方法即可
                    takePhoto();
                }

5 拍照实现方法

private void takePhoto(){
        // 跳转到系统的拍照界面
        Intent intentToTakePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // 指定照片存储位置为sd卡本目录下
        // 这里设置为固定名字 这样就只会只有一张temp图 如果要所有中间图片都保存可以通过时间或者加其他东西设置图片的名称
        // File.separator为系统自带的分隔符 是一个固定的常量
        mTempPhotoPath = Environment.getExternalStorageDirectory() + File.separator + "photo.jpeg";
        // 获取图片所在位置的Uri路径 *****这里为什么这么做参考问题2***** 
                /*imageUri = Uri.fromFile(new File(mTempPhotoPath));*/
        imageUri = FileProvider.getUriForFile(MainActivity.this,
                MainActivity.this.getApplicationContext().getPackageName() +".my.provider",
                new File(mTempPhotoPath));
        //下面这句指定调用相机拍照后的照片存储的路径
        intentToTakePhoto.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(intentToTakePhoto, GlobalVariable.CAMERA_REQUEST_CODE);
    }

6 打开本地相册事件中:
动态获取权限:

 if (ContextCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {   //权限还没有授予,需要在这里写申请权限的代码
                    // 第二个参数是一个字符串数组,里面是你需要申请的权限 可以设置申请多个权限
                    // 最后一个参数是标志你这次申请的权限,该常量在onRequestPermissionsResult中使用到
                    ActivityCompat.requestPermissions(MainActivity.this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                            GlobalVariable.CAMERA_REQUEST_CODE);

                }else { //权限已经被授予,在这里直接写要执行的相应方法即可
                    choosePhoto();
                }

7 打开相册方法实现

private void choosePhoto(){
        Intent intentToPickPic = new Intent(Intent.ACTION_PICK, null);
        // 如果限制上传到服务器的图片类型时可以直接写如:"image/jpeg 、 image/png等的类型" 所有类型则写 "image/*"
        intentToPickPic.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg");
        startActivityForResult(intentToPickPic, GlobalVariable.GALLERY_REQUEST_CODE);
    }

8 界面回调方法 用于将得到的照片处理

//当拍摄照片完成时会回调到onActivityResult 在这里处理照片的裁剪
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        fragment4ImageView0 = findViewById(R.id.fragment4ImageView0);
        if (resultCode == MainActivity.RESULT_OK) {
            switch (requestCode) {
                case GlobalVariable.CAMERA_REQUEST_CODE: {
                    // 获得图片
                    try {
                         //该uri就是照片文件夹对应的uri
                        Bitmap bit = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                        // 给相应的ImageView设置图片 未裁剪
                        fragment4ImageView0.setImageBitmap(bit);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                }
                case GlobalVariable.GALLERY_REQUEST_CODE: {
                    // 获取图片
                    try {
                         //该uri是上一个Activity返回的
                        imageUri = data.getData();
                        if(imageUri!=null) {
                            Bitmap bit = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                            Log.i("bit", String.valueOf(bit));
                            fragment4ImageView0.setImageBitmap(bit);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

这里直接将得到的照片放在ImageView上 要裁剪,参考:
http://blog.csdn.net/weixin_37577039/article/details/79186862


9 权限申请回调方法

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
    {

        if (requestCode == GlobalVariable.CAMERA_REQUEST_CODE)
        {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                takePhoto();
            } else
            {
                // Permission Denied
                Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }

        if (requestCode == GlobalVariable.GALLERY_REQUEST_CODE)
        {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                choosePhoto();
            } else
            {
                // Permission Denied
                Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

问题一:
Attempt to invoke virtual method ‘void android.widget.ImageView.setImageBitmap(android.graphics.Bitmap)’ on a null object reference

Bitmap bit = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
fragment4ImageView0.setImageBitmap(bit);

解决:
先检查右边,是否为空的
还是不行 检查左边 是否有findViewById

如果是在onActivityResult中设置的setImage 即使在onCreate中findView 了也是不行的 要在onActivityResult中findView


问题2:
拍照 Android N 版本遇到的问题:
android.os.FileUriExposedException: file:///storage/emulated/0/photo.jpeg exposed beyond app through ClipData.Item.getUri()
解决:
用 FileProvider去打开目录
1 创建一个类 继承FileProvider

public class GenericFileProvider extends FileProvider { 
   
}

2 Manifest.xml的application中:
添加:

<provider  android:name=".Utils.GenericFileProvider" android:authorities="${applicationId}.my.provider" android:exported="false" android:grantUriPermissions="true">
            <meta-data  android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/>
        </provider>

3 res/xml目录下 若没有 xml目录则创建

创建 provider_paths.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>

4 使用:

/*imageUri = Uri.fromFile(new File(mTempPhotoPath));*/
替换成:
imageUri = FileProvider.getUriForFile(MainActivity.this,
                        MainActivity.this.getApplicationContext().getPackageName() +".my.provider",
                        new File(mTempPhotoPath));

静默升降摄像头问题 若使用了下面的代码 则可能会导致手机升降摄像头 这样会让用户觉得你私自调用了摄像头 泄漏了他的隐私 要注意~

1.摄像头调用:用户没有拍照操作,但app调用到Camera1.open()时,会静默升降摄像头;
2.麦克风调用:用户没有录音操作,但app在后台调用AudioRecord时,会让系统认为是在录音,状态栏就有红色录音提示
麦克风录音提示图:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/125285.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 数论狄利克雷定理_shx函数

    数论狄利克雷定理_shx函数狄利克雷函数dirac在Matlab中使用Syntaxd=dirac(x)d=dirac(n,x)d=dirac(x)representstheDiracdeltafunctionofx.d=dirac(n,x)representsthenthderivativeoftheDiracdeltafunctionatx.dirac(t)这表示关于ttt的狄利克雷函数dirac(1,t)dirac(2,t)因此,这两个分别表示关于

    2022年9月4日
    0
  • 100套大数据可视化炫酷大屏Html5模板

    100套大数据可视化炫酷大屏Html5模板100套大数据可视化炫酷大屏Html5模板;包含行业:社区、物业、政务、交通、金融银行等,全网最新、最多,最全、最酷、最炫大数据可视化模板。源码地址 giteehttps://gitee.com/iGaoWei/big-data-view githubhttps://github.com/iGaoWei/BigDataView 使用说明 直接下载,使用浏览器访问静态页面即可。 git拉取代码$gitclonehttps://gitee….

    2022年9月7日
    0
  • python中取整数的方法(python中取整符号)

    Python中的round()有两个参数,第一个参数是需要处理的数,第二个参数是数位精度,默认为0。round(3.4)##3round(3.5)##4而有时候会出现奇怪的情况,比如:round(3.24,1)#是四舍五入##3.2round(3.26,1)#是四舍五入##3.3round(3.25,1)#不是四舍五入##3.2######################…

    2022年4月12日
    66
  • 什么是互联网,以太网,广域网,局域网的代码_局域网和广域网和城域网的区别

    什么是互联网,以太网,广域网,局域网的代码_局域网和广域网和城域网的区别计算器网络

    2022年10月9日
    0
  • [高通MSM8953_64][Android10]移除开机进入充电界面

    [高通MSM8953_64][Android10]移除开机进入充电界面文章目录开发平台基本信息问题描述解决方法开发平台基本信息芯片:MSM8953_64版本:Android10kernel:msm-4.9问题描述在移植开发Android10的时候,一开始是用debug版本编译调试的,一直都很正常,然后,准备提交测试的时候,编译user版本却无法正常进入系统,一直在开机logo跟充电界面循环跳转。这是因为设备进入了关机充电模式导致的,在lk阶段,将充电界面屏蔽,即可正常进入系统。解决方法diff–gita/bootable/bootloader

    2022年10月20日
    0
  • flutter 配置文件_怎么配置mysql的环境变量

    flutter 配置文件_怎么配置mysql的环境变量废话不多说,这篇文章仅仅作为自己的备忘。在安装flutter的时候,由于要配置环境变量,在windows上面倒还好,什么都是可视化的操作,自然不会有多大的问题,然而在mac上面,由于对mac不是很熟悉,就环境变量的配置都纠结了好久,每次配好之后重启一下,环境变量就不知所踪,百度了好久,最后才找到解决方案,当然,大神可以略过,这篇文章也只针对mac菜鸟。touch~/.bash_profile…

    2022年10月30日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号