笔记_第八章 多媒体的使用

第八章 多媒体的使用

  • 通知的使用

    • 首先需要获取NotificationManager对通知进行管理

      • NotificationManager manager = getSystemService(Context.NOTIFICATION_SERVICE);

    • 使用support库中 提供的NotificationCompat类来创建notification的对象

      • Notification notification = NotificationCompat

        .Builder(context)

        .setContentTitle("XXXXX00")

        .setContentText("xxxxxxx")

        .setWhen(System.currentTimeMillis())

        .setSmallIcon(R.drawable.small_icon)

        .setLargeIcon(BitMapFactory.decodeResource(

        getResource(),

        R.drawable.large_icon))

        .build();

    • 调用NotificationManager 的 notify方法让通知显示

      • 参数1:id,需要每个通知的id都不一样

      • 参数2:刚刚创建的notification的对象

    • PendingIntent的使用,用于响应用户点击通知事件

      • 创建PendingIntent对象:PengdingIntent.getActivity(this,0,intent,0);

        • 其中this是context上下文,intent是启动活动的意图,另外两个参数填入0就可以了

        • 然后通过在创建notification对象的时候.setContentIntent(pi)传入这个pendingIntent对象

    • 点击通知后取消

      • 默认是不会取消通知的,需要在创建notification的时候setAutoCancel(true)或者在新开启的活动或者广播或者服务中调用NotificationManager 对象的cancel(ID) 来手动取消,这里的ID是通知的ID

    • 通知的高级技巧

      • .....主要是一些在通知中显示长文本或者显示图片等技巧

  • 摄像头和相册

    • 从照相机获取图片

      //从摄像头获取图片
      //新建一个图片文件,路径是sd卡中的缓存目录
      File outputImage = new File(getExternalCacheDir(), "output_image.jpg");
      try {
          //如果文件已经存在则删除并重新创建一个新文件
          if (outputImage.exists()) {
              outputImage.delete();
          }
          outputImage.createNewFile();
      } catch (IOException e) {
          e.printStackTrace();
      }
      //这里可能是不同SDK的api不兼容的文件,区分24上下的api,作用是获取图片文件的资源定位,相当于指针,通过uri就可以安全访问这个文件
      if (Build.VERSION.SDK_INT>=24){
          imageUri = FileProvider.getUriForFile(MainActivity.this, "com.hrh.cameraalbumtest.fileprovider", outputImage);
      }else{
          imageUri = Uri.fromFile(outputImage);
      }
      //创建一个intent意图,通过action指明要打开照相机的活动,并且通过putExtra指定了照相机的捕获结果存放在外部文件,路径是uri,指向了图片文件,然后打开活动。
      Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
      intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
      startActivityForResult(intent,TAKE_PHOTO);
      @Override
      protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          switch (requestCode){
              case TAKE_PHOTO:
      ​
                  if (resultCode == RESULT_OK){
                      try {
                          //当回调方法被调用时,图片已经被加载到那个图片文件中,通过uri访问这个文件,并得到输入流交给位图工厂解析得到位图对象,这样imageView可以通过位图对象来显示拍摄的结果.
                          Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                          picture.setImageBitmap(bitmap);
                      } catch (FileNotFoundException e) {
                          e.printStackTrace();
                      }
                  }
                  break;
              default:
                  break;
          }
      }

      因为用到了fileProvider 需要在manifest中配置

      <application
          android:allowBackup="true"
          android:icon="@mipmap/ic_launcher"
          android:label="@string/app_name"
          android:roundIcon="@mipmap/ic_launcher_round"
          android:supportsRtl="true"
          android:theme="@style/AppTheme">
          ...
          <provider
              android:authorities="com.hrh.cameraalbumtest.fileprovider"
              android:name="androidx.core.content.FileProvider"
              android:exported="false"
              android:grantUriPermissions="true"
              >
              <meta-data
                  android:name="android.support.FILE_PROVIDER_PATHS"
                  android:resource="@xml/file_paths"
                  />
      ​
          </provider>
          
          ...
      </application>

      其中meta-data中的resource是配置provider能够访问到的文件目录范围,fileprovider通过给定的file文件对象的文件路径来找到对应的图片文件,并将它封装为uri对象返回,因此这个文件的路径一定要被provider访问到,但是有时候会发生未知的错误

      @xml/fiile_paths

      <?xml version="1.0" encoding="utf-8"?>
      <paths xmlns:android="http://schemas.android.com/apk/res/android">
          <root-path
              name="my_images"
              path=""/>
      </paths>

      在这里 root-path表示整个应用的根目录,虽然他不推荐使用但是这里不这样做就找不到文件,还有其他选项例如 files-path对应的目录是getFilesDir的目录,cache-path对应的目录是getCacheDir等等。

    • 从相册获取图片

      • 访问相册属于危险权限,需要进行动态运行时权限申请,代码如下,openAlbum是自定义的打开相册的方法

        if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        }else{
            openAlbum();
        }
      • 申请权限对应的回调方法为onRequestPermissionsResult,代码如下

        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        ​
            switch (requestCode){
                case 1:
                    if (grantResults.length>0&&(grantResults[0] == PackageManager.PERMISSION_GRANTED)){
                        openAlbum();
                    }else{
                        Toast.makeText(this,"you denied the permission",Toast.LENGTH_SHORT).show();
                    }
                    break;
                default:
            }
        ​
        }
      • 如果用户接受授权,接下来是打开相册的方法,openAlbum:

        private void openAlbum() {
            Intent intent = new Intent("android.intent.action.GET_CONTENT");
            intent.setType("image/*");
            startActivityForResult(intent,CHOOSE_PHOTO);
        }
      • 对应的启动活动并返回结果的回调是onActivityResult,代码如下:

        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            //super.onActivityResult(requestCode, resultCode, data);
            super.onActivityResult(requestCode, resultCode, data);
            switch (requestCode) {
                ...
                case CHOOSE_PHOTO:
                    if (resultCode == RESULT_OK) {
                        if (data != null) {
                            handleImageOnKitKat(data);
                            //handleImageBeforeKitKat(data);
                        }
                    }
                default:
                    break;
            }
        }
      • 由于在安卓系统7.0之后打开相册返回的Intent data中,通过Uri getData()得到的uri对象不是真实的uri,也就是说无法通过这个uri对象直接访问图片文件,需要经过解析才能得到真实的uri,解析的代码不是很懂,有点复杂,代码如下:

        private void handleImageOnKitKat(Intent data) {
            String imagePath = null;
            Uri uri = data.getData();
            if (DocumentsContract.isDocumentUri(this,uri)){
                String docId = DocumentsContract.getDocumentId(uri);
                if ("com.android.providers.media.documents".equals(uri.getAuthority())){
                    String id = docId.split(":")[1];
                    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.parseLong(docId));
                    imagePath = getImagePath(contentUri,null);
                }
        ​
            }else if ("content".equalsIgnoreCase(uri.getScheme())){
                imagePath = getImagePath(uri,null);
            }else if ("file".equalsIgnoreCase(uri.getScheme())){
                imagePath = uri.getPath();
            }
            displayImage(imagePath);
        }

        具体是通过判断uri的不同类型进行重新包装,然后调用自定义的getImagePath和displayImage方法来展示图片,这两代码如下:

        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;
        }
        private void displayImage(String imagePath){
            if (imagePath!=null){
                Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
                picture.setImageBitmap(bitmap);
            }else{
                Toast.makeText(this,"fail to get image",Toast.LENGTH_SHORT).show();
        ​
            }
        }
    • 播放音频

      • MediaPlayer类的使用

        • 创建MediaPlayer的对象

        • 调用setDataSource方法设置音频的路径

        • 调用prepare进行播放的准备工作

        • 调用start开始播放音频

        • 调用pause暂停播放

        • 调用stop停止播放

        • 调用reset重置

        • 调用getDuration获取音频的时长

        • 最后释放资源需要调用stop方法和release方法

      • 使用之前需要动态申请权限

      • 不需要在布局中创建布局

    • 播放视频

      • VideoView类的使用

      • 需要添加布局 < VideoView id="video_view" />

      • 很多方法和mediaPlayer都很类似

      • 最后释放资源的方法是suspend,和mediaplayer不一样

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值