Android Studio —— 多媒体

528 阅读5分钟

通知

  • 可以在活动或广播接收器创建

基本用法

  1. 通过调用getSystemService创建NotificationManager管理通知
    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
  2. 使用Builder构造器创建Notification对象
    Notification notification = new NotificationCompat.Builder(context).build();
    
    • Notification对象
    • 可以在最终的build()方法前连缀任意多的设置方法
    Notification notification = new NotificationCompat.Builder(context)
            .setContentTitle("This is content title")
            .setContentText("This is content text")
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.drawable.small_icon)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.large_icon))
            .build();
    
    • setContentTitle:指定通知的标题内容,下拉系统状态栏可以看到
    • setContentText:指定通知的正文内容,下拉系统状态栏可以看到
    • setWhen:指定通知被创建的时间,毫秒为单位,下拉系统状态栏时会显示在相应的通知上
    • setSmallIcon:设置通知的小图标,只能使用纯alpha图层的图片,显示在系统状态栏上
    • setLargeIcon:设置通知的大图标,下拉系统状态栏时看到
  3. 调用NotificationManagernotify()方法
    manager.notify(1, notification);
    
    • 第一个参数是唯一的id
    • 第二个参数是Notification对象
  4. 点击通知效果
    • PendingIntent:延迟执行的Intent
    • 通过getActivity()getBroadcast()getService获取
    • 第一个参数是Context
      第二个参数一般用不到,通常传入0即可
      第三个参数是Intent对象
      第四个参数用于确定PendingIntent的行为,有FLAG_ONE_SHOT FLAG_NO_CREATE FLAG_CANCEL_CURRENT FLAG_UPDATE_CURRENT4种值可选,通常传入0即可
    • NotificationCompat.Builder构造器种连缀setContentIntent()添加PendingIntent对象
    Intent intent = new Intent(this, NotificationActivity.class);
    PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    Notification notification = new NotificationCompat.Builder(this)
            .setContentTitle("This is content title")
            .setContentText("This is content text")
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.drawable.small_icon)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.large_icon))
            .setContentIntent(pi)
            .build();
    manager.notify(1, notification);
    
  5. 取消通知
    1. NotificationCompat.Builder种连缀setAutoCancel()方法
      Notification notification = new NotificationCompat.Builder(this)
              ...
              .setAutoCancel(true)
              .build();
      
    2. 显式调用NotificationManagercancel()方法
      NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      manager.cancel(1);  // 传入id
      

进阶技巧

  • 通知时播放音频
    • setSound()接收一个Uri参数
    • E.g.
      Notification notification = new NotificationCompat.Builder(this)
              ...
              .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
              .build();
      
  • 通知时振动
    • 属性vibrate是一个长整型的数组,用于设置手机静止和振动的时长,以毫秒为单位
    • 下标为0的值表示手机静止的时长,下标为1的值表示手机振动的时长,下标为2的值表示手机静止的时长,以此类推
    • E.g.
      Notification notification = new NotificationCompat.Builder(this)
              ...
              .setVibrate(new long[] {0, 1000, 1000, 1000})
              .build();
      
    • 声明权限 <user-permission android:name="android.permission.VIBRATE" />
  • 通知时闪烁LED灯
    • setLights()方法接收3个参数
      第一个参数指定LED灯的颜色
      第二个参数指定LED灯亮起的时长,以毫秒为单位
      第三个参数指定LED灯暗去的时长,以毫秒为单位
    • E.g.
      Notification notification = new NotificationCompat.Builder(this)
              ...
              .setLights(Color.GREEN, 1000, 1000)
              .build();
      
  • 默认通知效果
    Notification notification = new NotificationCompat.Builder(this)
              ...
              .setDefaults(NotificationCompat.DEAULT_ALL)
              .build();
    

高级功能

  • setStyle():构建富文本通知内容
    接收一个NotificationCompat.Style参数,用于构建具体的富文本信息
    • 显示长文字
      Notification notification = new NotificationCompat.Builder(this)
              ...
              .setStyle(new NotificationCompat.BigTextStyle().bigText("blabla"))
              .build();
      
    • 显示大图片
      Notification notification = new NotificationCompat.Builder(this)
              ...
              .setStyle(new NotificationCompat.BigPictureStyle().bigPicture
                  (BitmapFactory.decodeResource(getResources(), R.drawable.large_image))
              .build();
      
  • setPriority:设置通知的重要程度
    接收一个整型参数用于设置这条参数的重要程度,5个常量可选
    • PRIORITY_DEFAULT:默认的重要程度,和不设置效果相同
    • PRIORITY_min:最低的重要程度,系统可能只会在特定场景才显示这条通知
    • PRIORITY_LOW:较低的重要程度,系统可能会将这类通知缩小,或改变其显示的顺序,排在更重要的通知之后
    • PRIORITY_HIGH:较高的重要程度,系统可能会将这类通知放大,或改变其显示的顺序,排在比较靠前的位置
    • PRIORITY_MAX:最高的重要程度,必须立刻让用户看到,甚至需要用户做出响应操作
    • E.g.
      Notification notification = new NotificationCompat.Builder(this)
              ...
              .setPriority(NotificationCompat.PRIORITY_MAX)
              .build();
      

调用摄像头和相册

调用摄像头

  • 拍摄
    // 创建File对象,用于存储拍照后的图片
    File outputImage = new File(getExternalCacheDir(), "output_image.jpg");
    try {
        if (outputImage.exists()) {
            outputImage.delete();
        }
        outputImage.createNewFile();
    } catch (IOException e) {
        e.printStackTrace();
    }
    if (Build.VERSION.SDK_INT >= 24) {
          imageUri = FileProvider.getUriForFile(MainActivity.this, "com.example.cameraalbumtest.fileprovider", outputImage);
    } else {
        imageUri = Uri.fromFile(outputImage);
    }
    // 启动相机程序
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    startActivityForResult(intent, TAKE_PHOTO);
    
    • 创建了一个File对象,用于存放摄像头拍下的内容,并将图片存放在手机SD卡的应用关联缓存目录下
      • 应用关联缓存目录指SD卡中专门存放当前应用缓存数据的位置,调用getExternalCacheDir()可以得到目录
      • 具体路径是sdcard/Android/data/<package name>/cache
      • 从Android 6.0开始,读写SD卡被列为危险权限,存放在SD卡任何其他目录都要进行运行时权限处理
    • 如果系统版本低于Android 7.0,调用UrifromFile()方法将File对象转化为Uri对象
      这个Uri对象标识着图片的本地真实路径
    • 如果系统版本不低于Android 7.0,调用FileProvidergetUriForFile()方法将File对象转换成一个封装过的Uri对象
      • getUriForFile()接收三个参数
        第一个参数是Context对象
        第二个参数可以是任意唯一的字符串
        第三个参数是File对象
      • 从Android 7.0开始,直接使用本地真实路径的Uri被认为是不安全的,会抛出一个FileUriExposedException异常
      • FileProvider一种特殊的内容提供器,使用了和内容提供器类似的机制保护数据,可以选择性的将封装过的Uri共享给外部
    • 构建一个Intent对象,并将这个Intentaction指定为android.media.action.IMAGE_CAPTURE,再调用IntentputExtra()方法指定图片的输出地址(Uri)
    • 调用startActivityForResult()启动活动
  • 显示拍摄的图片
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch(requestCode) {
            case TAKE_PHOTO:
                if (resultCode == RESULT_OK) {
                    try {
                        // 将拍摄的照片显示出来
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
                            .openInputStream());
                        picture.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
    }