第八章 丰富你的程序-运用手机多媒体
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); // 根据图片路径显示图片 }
相关文章推荐
- 第八章 丰富你的程序,运用手机多媒体
- 第二行代码学习笔记——第八章:丰富你的程序——运行手机多媒体
- 第 8 章 丰富你的程序,运用 手机多媒体
- 丰富你的程序,运用手机多媒体
- 丰富你的程序,运用手机多媒体
- 阅读郭林《第一行代码》的笔记——第8章 丰富你的程序,运用手机多媒体
- 丰富你的程序,运用手机多媒体
- 学习笔记(十)运用通知和手机多媒体
- Android运用手机多媒体
- Android基础总结(10)——手机多媒体的运用:通知、短信、相机、视频播放
- Android之运用手机多媒体
- Android学习笔记——手机多媒体运用
- 06运用手机多媒体
- 小议如何控制学生机结束学生端多媒体控制平台程序
- Collection -> .Net集合类型大全,只要灵活运用可以节省很多开发时间和提高程序运行效率
- J2ME手机游戏引擎程序结构简述
- Case 在做留言本程序中的运用...
- 写完手机程序
- VBScript脚本运用(脚本程序与宿主程序的交互)
- Case 在做留言本程序中的运用...