android 手机拍照、相册选择照片并显示

本文介绍安卓调用摄像头拍照并显示照片的思路。通过给按钮添加点击事件,创建File对象存储图片,将其转换为Uri对象,构建Intent指定拍照动作和输出地址,启动活动调用相机拍照,拍完照结果返回onActivityResult()方法,最后将照片uri转化为Bitmap显示。
关键代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn1;

    private Uri imageUri;

    private ImageView picture;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn1 = (Button)findViewById(R.id.btn1);   //发送通知
        Button takePhoto = (Button)findViewById(R.id.takePhoto);//拍照
        Button selectPhoto = (Button)findViewById(R.id.selectPhoto);//相册选择
        picture = (ImageView)findViewById(R.id.image);
        btn1.setOnClickListener(this);
        takePhoto.setOnClickListener(this);
        selectPhoto.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.btn1:

                Intent intent = new Intent(this,NotificationActivity.class);
                PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
                NotificationManager manger = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                Notification notification = new NotificationCompat.Builder(this)
                        .setContentTitle("This is content title")
                        .setContentText("this is content text")
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setContentIntent(pi)
                        .setAutoCancel(true)
                        .setVibrate(new long[]{0,1000})
                        .build();
                manger.notify(1,notification);
                break;

            case R.id.takePhoto:
                File outputImage = new File(Environment.getExternalStorageDirectory(),
                        "tempImage" + ".jpg");
                try {
                    if (outputImage.exists()) {
                        outputImage.delete();
                    }
                    outputImage.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Intent intent1 = new Intent("android.media.action.IMAGE_CAPTURE");

                if (Build.VERSION.SDK_INT < 24) {
                    // 从文件中创建uri
                    imageUri = Uri.fromFile(outputImage);
                    intent1.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                } else {
                    //兼容android7.0 使用共享文件的形式
                    ContentValues contentValues = new ContentValues(1);
                    contentValues.put(MediaStore.Images.Media.DATA, outputImage.getAbsolutePath());
                    //检查是否有存储权限,以免崩溃

                    if(!checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) return;
                    imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
                    intent1.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                }
                startActivityForResult(intent1, 1);
                break;

            case R.id.selectPhoto:
                      Intent intent2 = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                      startActivityForResult(intent2,2);

            default:
                break;

        }
    }

    private boolean checkPermission( String permissions){
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            //申请WRITE_EXTERNAL_STORAGE权限
            Toast.makeText(this,"请开启存储权限",Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;


    }
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case 1:
                if (resultCode == RESULT_OK) {
                    setImage(imageUri);
                }
                break;
            case 2:
                if (resultCode == RESULT_OK) {

                        Uri uri = data.getData();
                        setImage(uri);

                }

        }
    }

    private void setImage(Uri uri){

        try {
            Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
                    .openInputStream(uri));
            picture.setImageBitmap(bitmap);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}

 

思路解析:

 

给button按钮增加点击事件,调用摄像头

1、首先这里创建了一个 File对象,用于存储摄像头拍下的图片,这里我们把图片命名为 tempImage.jpg ,并 将 它 存 放 在 手 机 SD 卡 的 根 目 录 下 , 调 用 Environment 的 getExternalStorageDirectory()方法获取到的就是手机 SD 卡的根目录 
2、然后再调用 Uri 的 fromFile()方法将 File 对象转换成 Uri对象,这个 Uri对象标识着 tempImage.jpg 这张图片 的唯一地址 
3、接着构建出一个Intent对象,并将这个Intent的action指定为android.media.action. IMAGE_CAPTURE,再调用 Intent的 putExtra()方法指定图片的输出地址,这里填入刚刚得 到的 Uri 对象,最后调用 startActivityForResult()来启动活动 
4、由于我们使用的是一个隐式 Intent,系统会找出能够响应这个 Intent的活动去启动,这样照相机程序就会被打开,拍下的 照片将会输出到 tempImage.jpg中 
5、我们是使用 startActivityForResult()来启动活动的,因此拍完照后会有结果返回 到 onActivityResult()方法中。 

6、最后将照片uri转化为Bitmap,进行显示。

对于拍摄照片我们可以直接调用系统自带的相机拍照,一般情况下无需我们自己开发相机拍照。 1、当点击按钮后我们可以通过Intent意图启动系统相机 @Override public void onClick(View v) { Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); String temName=new DateFormat().format("yyMMdd_hhmmss",System.currentTimeMillis())+"_"+(Math.random()*100)+".jpg"; //文件名 image_path=path+File.separator+temName; File file=new File(image_path); if(file.exists()){ file.delete(); } Uri u=Uri.fromFile(file); intent.putExtra(MediaStore.EXTRA_OUTPUT, u); startActivityForResult(intent, 0); } 在这里设置 intent.putExtra(MediaStore.EXTRA_OUTPUT, u);非常重要,如果不设置这个参数那么我们获取到的图片只是一个经过压缩后的缩略图,只有设置这个才能得到拍摄后的原图。 2、在startActivityForResult(intent, 0);后我们需要重写onActivityResult(int requestCode, int resultCode, Intent data)方法,如果设置了MediaStore.EXTRA_OUTPUT那么我们在这里data返回的是null。 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode==RESULT_OK){ File file=new File(image_path); try { Uri uri = Uri.fromFile(file); BitmapFactory.Options options=new BitmapFactory.Options(); options.inJustDecodeBounds=true; BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); options.inSampleSize=4; options.inJustDecodeBounds=false; Bitmap map=BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), map, null, null); sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,uri)); image.setImageBitmap(map); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 蓝色部分是对图片进行简单的压缩处理,如果不进行处理会出现内存溢出。 红色部分是将图片保存在DCIM文件夹下。 绿色部分是发生一个广播通知系统重新扫描制定文件,这样我们就可以在图库本地图片中看到拍摄的图片。 3、最后记得在清单文件中加入调用系统相机和保存文件权限 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值