《第一行代码》笔记(2)——调用相机

package com.zjw.mymultimedia2;

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.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

//8.3.1 p294 调用摄像头拍照
//布局里面一个Button调用摄像头,一个Image显示拍到的图片

//FileProvider要在清单文件注册
/*
代码如下
        <provider
            android:authorities="com.zjw.mymultimedia2.fileprovider"
            android:name="android.support.v4.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_path"/>
        </provider>
        其中
        name属性值是固定的
        authorities属性值要和getUriForFile()参数二里设置的唯一字符串相同
        <meta-data/>标签用来指定Uri的共享路径,引用了file_path.xml资源
 */
/*
创建file_path.xml资源
res下新建xml文件夹,里面创建file_path.xml文件
代码如下
<?xml version="1.0" encoding="utf-8"?>
<Paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="my_images"
        path=""/>
</Paths>
        其中
        external-path用来指定Uri共享
        name属性可以随便填
        path属性表示共享的具体路径,设置为空就是将整个SD卡进行共享
 */
/*
Android 4.0系统以前,访问SD卡应用关联目录需要声明权限,4.0后不用,做兼容还需声明
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 */
public class CallCamera extends AppCompatActivity {

    private Uri mImageUri;
    private static final int TAKE_PHOTO = 646;
    private Button mBtnTakePhoto;
    private ImageView mIvPicture;
    private static final String TAG = "zjw";

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

        //找到控件
        mBtnTakePhoto = (Button) findViewById(R.id.btn_take_photo);
        mIvPicture = (ImageView) findViewById(R.id.iv_picture);

        //点击事件
        mBtnTakePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //存储拍照后图片
                //将它存放在手机SD卡的应用关联缓存目录下
                //应用关联缓存目录:SD卡中专门用来存放当前应用缓存数据的位置
                //getExternalCacheDir():/sdcard/Android/data/<package name>/cache
                //从Android6.0开始,读写SD卡被列为高危权限,只you使用应用关联目录可以跳过运行时权限处理
                File outputImage = new File(getExternalCacheDir(), "output_image.jpg");
                Log.d(TAG, "onClick: " + "1_" + getExternalCacheDir().getAbsolutePath());
                try {
                    if (outputImage.exists()) {
                        outputImage.delete();
                    }
                    outputImage.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }


                //Android7.0开始,直接使用本地这是路径Uri被认为是不safe的,会报FileUriExposedException异常
                if (Build.VERSION.SDK_INT >= 24) {
                    //FileProvider一种特殊的内容提供器,可以选择性的将封装过得Uri共享给外部
                    //getUriForFile()将File对象转换为一个封装过的Uri
                    //参数一:Context
                    //参数二:任意唯一字符串
                    //参数三刚刚创建的File对象
                    mImageUri = FileProvider.getUriForFile(
                            CallCamera.this, "com.zjw.mymultimedia2.fileprovider", outputImage);
                } else {//版本低于Android7.0,这个Uri标识这张图片本地zhen实路径
                    mImageUri = Uri.fromFile(outputImage);
                    Log.d(TAG, "onClick: " + "2_" + mImageUri);
                }
                //调用相机
                //MediaStore.ACTION_IMAGE_CAPTURE
                //android.media.action.IMAGE_CAPTURE
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
                startActivityForResult(intent, TAKE_PHOTO);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case TAKE_PHOTO:
                if (resultCode == RESULT_OK) {
                    //将照片显示出来
                    try {
//                        InputStream is = getContentResolver().openInputStream(mImageUri);
//                        Bitmap bitmap = BitmapFactory.decodeStream(is);
//                        System.out.println(bitmap.getByteCount()+"czb");

                        //加载大图
                        InputStream is = getContentResolver().openInputStream(mImageUri);

                        BitmapFactory.Options opts = new BitmapFactory.Options();
                        // 不读取像素数组到内存中,仅读取图片的信息
                        opts.inJustDecodeBounds = true;
                        BitmapFactory.decodeStream(is, null, opts);
                        // 从Options中获取图片的分辨率
                        int imageHeight = opts.outHeight;
                        int imageWidth = opts.outWidth;
                        // 获取Android屏幕的服务
                        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
                        // 获取屏幕的分辨率,getHeight()、getWidth已经被废弃掉了
                        // 应该使用getSize(),但是这里为了向下兼容所以依然使用它们
                        int windowHeight = wm.getDefaultDisplay().getHeight();
                        int windowWidth = wm.getDefaultDisplay().getWidth();
                        // 计算采样率
                        int scaleX = imageWidth / windowWidth;
                        int scaleY = imageHeight / windowHeight;
                        int scale = 1;
                        // 采样率依照最大的方向为准
                        if (scaleX > scaleY && scaleY >= 1) {
                            scale = scaleX;
                        }
                        if (scaleX < scaleY && scaleX >= 1) {
                            scale = scaleY;
                        }
                        // 采样率
                        opts.inSampleSize = scale;
                        // false表示读取图片像素数组到内存中,依照设定的采样率
                        opts.inJustDecodeBounds = false;
                        is = getContentResolver().openInputStream(mImageUri);
                        Bitmap bitmap = BitmapFactory.decodeStream(is, null, opts);

                        Log.d(TAG, "onActivityResult: " + "3_" + bitmap.toString());
                        mIvPicture.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
    }

    private Toast mToast;

    public void showToast(String msg) {
        if (mToast == null) {
            mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        }
        mToast.setText(msg);
        mToast.show();
    }

}

转载于:https://my.oschina.net/u/3620480/blog/1477315

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值