栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

简单说说Android中如何使用摄像头和相册

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

简单说说Android中如何使用摄像头和相册

很多 APP 应用都有用户头像功能,用户既可以调用摄像头马上拍一张美美的自拍,也可以打开相册选取一张心仪的照片作为头像。

1 调用摄像头

布局文件:




  
  

活动类代码:

public class MainActivity extends AppCompatActivity {

  private static final String TAG = "MainActivity";

  public static final int OPEN_PHOTO_REQUEST_CODE = 1;
  private Uri imgUrl = null;
  private ImageView imageView;


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


    //为按钮添加【打开摄像头】事件
    findViewById(R.id.open_photo).setonClickListener(new View.onClickListener() {
      @Override
      public void onClick(View v) {
 File file = new File(getExternalCacheDir(), "imageView.jpg");//存储照片
 if (file.exists()) {
   file.delete();
 }
 try {
   file.createNewFile();
 } catch (IOException e) {
   e.printStackTrace();
 }


 if (Build.VERSION.SDK_INT >= 24) {//版本高于 7.0
   imgUrl = FileProvider.getUriForFile(MainActivity.this, "net.deniro.camera.fileProvider", file);
 } else {
   imgUrl = Uri.fromFile(file);
 }

 //打开摄像头
 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
 intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUrl);//指定图片输出地址
 startActivityForResult(intent, OPEN_PHOTO_REQUEST_CODE);
      }
    });

    //显示拍摄的照片
    imageView = (ImageView) findViewById(R.id.img);


  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "requestCode: " + requestCode);
    Log.d(TAG, "imgUrl: " + imgUrl);
    switch (requestCode) {
      case OPEN_PHOTO_REQUEST_CODE:
 if (resultCode == RESULT_OK) {
   try {//解析图片并显示
     Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imgUrl));
     imageView.setImageBitmap(bitmap);
   } catch (FileNotFoundException e) {
     e.printStackTrace();
   }
 }
 break;
      default:
 break;
    }
  }
}

getExternalCacheDir() 可以获取 SD 卡中专门用于存放当前应用缓存数据的位置。Android6.0+ 开始,读取存放在 SD 卡中的任何其它目录都被列为危险权限,因此需要设定运行时权限才可以操作,这里使用了与应用关联的目录,所以就可以跳过这一步。

getUriForFile() 方法接收三个参数:Context对象、任意唯一的字符串与 File对象。从 android 7.0+ 系统开始,直接使用本地真实的路径被认为是不安全的,会抛出一个 FileExposedException 异常,而 FileProvider 是一种特殊的内容提供器,它使用与内容提供器类似的机制对数据进行保护。

在 AndroidManifest.xml 中注册刚才定义的内容提供器:


  
  

android:authorities 就是我们在 FileProvider.getUriForFile() 方法中传入的第二个参数。

使用 指定了 Uri 的共享路径,在此引用了 xml 资源。

在 IDEA 中可以通过快捷键 ctrl + enter 直接在 xml 文件夹下创建文件:

快捷创建

默认为 xml 文件夹

file_paths.xml:



  
  
  
  

Android 4.4 之前,还需要设置访问 SD 卡应用的关联目录权限:

 

拍照后效果:

2 从相册中选取照片

直接从相册中选取一张现有的照片比打开摄像头拍一张照片更加常用,因此,一个好的 app,应该将这两种方式都实现。

修改布局文件,加入【打开相册】按钮:


在活动类中加入打开相册选取照片的处理逻辑:


public static final int CHOOSE_PHOTO_REQUEST_CODE = 2;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  ...
  //打开相册
  findViewById(R.id.choose_photo).setonClickListener(new View.onClickListener() {
    @Override
    public void onClick(View v) {
      if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
 ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
     CHOOSE_PHOTO_REQUEST_CODE);
      } else {
 openAlbum();
      }
    }
});

private void openAlbum() {
  Intent intent = new Intent("android.intent.action.GET_CONTENT");
  intent.setType("image
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  switch (requestCode) {
    case CHOOSE_PHOTO_REQUEST_CODE:
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
 openAlbum();
      } else {
 Toast.makeText(this, "被拒绝啦", Toast.LENGTH_SHORT).show();
      }
      break;
    default:
      break;
  }
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  Log.d(TAG, "requestCode: " + requestCode);
  Log.d(TAG, "imgUrl: " + imgUrl);
  switch (requestCode) {
    case OPEN_PHOTO_REQUEST_CODE:
      if (resultCode == RESULT_OK) {
 try {//解析图片并显示
   Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imgUrl));
   imageView.setImageBitmap(bitmap);
 } catch (FileNotFoundException e) {
   e.printStackTrace();
 }
      }
      break;
    case CHOOSE_PHOTO_REQUEST_CODE:
      if (Build.VERSION.SDK_INT >= 19) {//4.4 及以上系统
 handleFor4_4(data);
      } else {
 handleForBefore4_4(data);
      }
      break;
    default:
      break;
  }
}


private void handleForBefore4_4(Intent data) {
  display(getImagePath(data.getData(),null));
}


@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void handleFor4_4(Intent data) {
  String imagePath = null;
  Uri uri = data.getData();//需要解析
  if (documentsContract.isdocumentUri(this, uri)) {//是 document 类型,使用 document id 来处理
    String documentId = documentsContract.getdocumentId(uri);
    String mediadocumentAuthority = "com.android.providers.media.documents";
    String downloaddocumentAuthority = "com.android.providers.downloads.documents";
    if (mediadocumentAuthority.equals(uri.getAuthority())) {//media 格式
      String id = documentId.split(":")[1];//数字格式的 ID
      String selection = MediaStore.Images.Media._ID + "=" + id;
      imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
    } else if (downloaddocumentAuthority.equals(uri.getAuthority())) {
      Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
      imagePath = getImagePath(contentUri, null);
    }
  } else if ("content".equalsIgnoreCase(uri.getScheme())) {//content 类型 uri
    imagePath = getImagePath(uri, null);
  } else if ("file".equalsIgnoreCase(uri.getScheme())) {//file 类型,则直接获取路径
    imagePath = uri.getPath();
  }
  display(imagePath);
}


private void display(String path) {
  if(path==null){
    Toast.makeText(this, "无法获取图片", Toast.LENGTH_SHORT).show();
  }else{
    imageView.setImageBitmap(BitmapFactory.decodeFile(path));
  }


}


private String getImagePath(Uri uri, String selection) {
  String path = null;
  Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
  if (cursor != null) {
    if (cursor.moveToFirst()) {
      path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
    }
    cursor.close();
  }
  return path;
}

这里请求了 WRITE_EXTERNAL_STORAGE 权限,以为相册中的照片一般是存放在 SD 卡上的,所以从 SD 卡中读取照片需要申请权限。WRITE_EXTERNAL_STORAGE 表示读写 SD 卡的能力权限。

为了兼容新老版本的手机(以 Android 4.4 为分水岭),因为 Android 4.4+ 的版本返回的 Uri 需要解析才可以使用。

点击【打开相册】按钮,会弹出读取 SD 卡的权限申请:

选取照片后的效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/156099.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号