您的位置:首页 > 其它

第八章 丰富你的程序-运用手机多媒体

2016-12-13 10:44 441 查看

Notification 通知

可以在activity、服务、广播接收者中发送一个通知

调用摄像头拍照

把拍的照片放在应用关联缓存目录中,通过getExternalCacheDir()可以得到这个目录:sdcard/Android/data/包名/cache用它可以绕过读写sd卡的权限。(但是4.4以前依旧需要权限)

创建一个file,如果存在,就删除,并且createNewFile,不存在则直接createNewFile。

将file转换成uri——该文件的真实路径

android7.0之前直接用Uri.fromFile即可

7.0开始认为这样不安全,会抛出FileUriExposedException异常。需要调用FileProvider.getUriForFile方法,转换成一个封装过的Uri对象。(需要注册内容提供器)

构建一个intent,把上面的Uri作为Extra,put进去,key为MediaStore.EXTRA_OUTPUT。action为android.media.action.IMAGE_CAPTURE.

这样就会在拍完之后,把照片保存到那个Uri的文件里,可以在onActivityResult中取出来。

==注意== :在启动相机的时候,如果指定了MediaStore.EXTRA_OUTPUT,那么相机会把图片保存到这个uri中,如果没指定,会在onActivityResult中的data返回一个key为data的bitmap,是缩略图

==问题== 不知道为什么,如果我指定了uri,再onActivityResult中不能及时拿到数据,需要等待。(经验证,郭霖的demo也有该问题,所以以后最好用缩略图,实在不行就写一个task,循环获取)

从相册中选取图片

由于图片在外部存储,所以需要有读取sd卡的权限,6.0的运行时权限,所以需要做如下处理

if (ContextCompat.checkSelfPermission(Context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) !=PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(Context, new String[]{ Manifest.permission. WRITE_EXTERNAL_STORAGE }, 1);
} else {
//打开相册
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//打开相册
} else {
Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
}
break;
}
}


接下来是打开相册的逻辑

private void openAlbum() {
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_PHOTO); // 打开相册
}


然后在onActivityResult中进行处理,4.4以上和以下系统处理方式是不同的,4.4以上不会直接返回一个真实的uri,所以需要我们解析

if (resultCode == RESULT_OK) {
// 判断手机系统版本号
if (Build.VERSION.SDK_INT >= 19) {
// 4.4及以上系统使用这个方法处理图片
handleImageOnKitKat(data);
} else {
// 4.4以下系统使用这个方法处理图片
handleImageBeforeKitKat(data);
}
}


首先写两个工具方法

private String getImagePath(Uri uri, String selection) {
String path = null;
// 通过Uri和selection来获取真实的图片路径
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;
}

private void displayImage(String imagePath) {
if (imagePath != null) {
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
picture.setImageBitmap(bitmap);
} else {
Toast.makeText(this, "failed to get image", Toast.LENGTH_SHORT).show();
}
}


对于4.4以下,直接可以拿到图片的真实uri

private void handleImageBeforeKitKat(Intent data) {
Uri uri = data.getData();
String imagePath = getImagePath(uri, null);
displayImage(imagePath);
}


对于4.4以上,需要先把包装过的uri进行解析

private void handleImageOnKitKat(Intent data) {
String imagePath = null;
Uri uri = data.getData();
Log.d("TAG", "handleImageOnKitKat: uri is " + uri);
if (DocumentsContract.isDocumentUri(this, uri)) {
// 如果是document类型的Uri,则通过document id处理
String docId = DocumentsContract.getDocumentId(uri);
if("com.android.providers.media.documents".equals(uri.getAuthority())) {
String id = docId.split(":")[1]; // 解析出数字格式的id
String selection = MediaStore.Images.Media._ID + "=" + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
magePath = getImagePath(contentUri, null);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
// 如果是content类型的Uri,则使用普通方式处理
imagePath = getImagePath(uri, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
// 如果是file类型的Uri,直接获取图片路径即可
imagePath = uri.getPath();
}
displayImage(imagePath); // 根据图片路径显示图片
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: