第八章 - 运用手机多媒体

使用通知

创建通知渠道

每条通知对应一个通知渠道。

创建通知渠道的步骤:

  1. 使用NotificationManager对通知进行管理
    getSystemService():接收一个字符串参数用于确定获取系统的哪个服务。

    1. NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  2. 使用NotificationChannel类构建一个通知渠道,并调用NotificationMananger的createNotificationChannel()方法完成创建
    创建通知的步骤:

    1. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
    2. String channelId = "First";
    3. String channelName = "通知消息";
    4. int importance = NotificationManager.IMPORTANCE_HIGH;
    5. NotificationChannel channel = new NotificationChannel(channelId,channelName,importance);
    6. manager.createNotificationChannel(channel);
    7. }

    通知的基本用法

    1. 使用Builder构造器创建Notificaition对象。(为了保证系统版本的兼容性,通过NotificationCompat类进行创建)
    2. 在build方法前连缀任意的设置方法。
    3. 调用NotificationManager的notify()方法让通知显示出来。
      1. notify()方法接收两个参数,参数1是一改id,参数2是Notification对象。
  1. 设置PendingIntent,让通知可以被点击。
    1. 创建一个intent。
    2. 调用PendingIntent的方法把intent传入生成一个PendingIntent对象。
    3. 调用setContentIntent设置方法。


demo:

  1. package com.example.myapplication;
  2. import android.app.NotificationChannel;
  3. import android.app.NotificationManager;
  4. import android.app.PendingIntent;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.graphics.BitmapFactory;
  8. import android.os.Build;
  9. import android.os.Bundle;
  10. import android.view.View;
  11. import android.widget.Button;
  12. import androidx.appcompat.app.AppCompatActivity;
  13. import androidx.core.app.NotificationCompat;
  14. public class Notification extends AppCompatActivity implements View.OnClickListener{
  15. private NotificationManager manager;
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_notification);
  20. manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  21. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
  22. String channelId = "First";
  23. String channelName = "通知消息";
  24. int importance = NotificationManager.IMPORTANCE_HIGH;
  25. NotificationChannel channel = new NotificationChannel(channelId,channelName,importance);
  26. manager.createNotificationChannel(channel);
  27. }
  28. Button sendNotice = (Button) findViewById(R.id.send_notice);
  29. sendNotice.setOnClickListener(this);
  30. }
  31. @Override
  32. public void onClick(View v) {
  33. switch (v.getId()){
  34. case R.id.send_notice:
  35. Intent intent = new Intent(this, NotificationTest.class);
  36. PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
  37. android.app.Notification notification = new NotificationCompat.Builder(this,"First")
  38. .setContentTitle("媳妇找你聊天了!")
  39. .setContentText("媳妇找你聊天了!")
  40. .setWhen(System.currentTimeMillis())
  41. .setSmallIcon(R.mipmap.ic_launcher)
  42. .setContentIntent(activity)
  43. .setAutoCancel(true)
  44. .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
  45. .build();
  46. manager.notify(1,notification);
  47. break;
  48. default:
  49. break;
  50. }
  51. }
  52. }

调用摄像头

调用摄像头

  1. Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
  2. intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
  3. startActivityForResult(intent,TAKE_PHOTO);

播放多媒体文件

播放音频

在Android中播放音频一般都是使用MediaPlayer类来实现的,它对多种格式的音频文件提供了非常全面的控制方法,下表列出了Media Player类中一些较为常用的控制方法。

image-20210802100527454.png

MediaPlayer工作流程:

  • 创建出一个MediaPlayer对象
  • 调用setDataSource()方法设置音频文件的路径
  • 调用prepare()方法使MediaPlayer进入到准备状态
  • 调用start()方法就可以开始播放音频,调用pause()方法就回暂停播放,调用reset()方法就会停止播放。

demo:播放音乐

  1. package com.example.myapplication;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import android.media.MediaPlayer;
  4. import android.os.Bundle;
  5. import android.widget.Button;
  6. public class PlayAudioActivity extends AppCompatActivity {
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_play_audio);
  11. Button play = findViewById(R.id.play);
  12. Button pause = findViewById(R.id.pause);
  13. Button stop = findViewById(R.id.stop);
  14. MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.music);
  15. play.setOnClickListener(v -> {
  16. mediaPlayer.start();
  17. });
  18. pause.setOnClickListener(v -> {
  19. if (mediaPlayer.isPlaying())
  20. mediaPlayer.pause();
  21. });
  22. stop.setOnClickListener(v -> {
  23. if (mediaPlayer.isPlaying())
  24. mediaPlayer.stop();
  25. });
  26. }
  27. }

在做这个demo的时候遇到的困难:

一开始写的代码一直报E/MediaPlayer: Error (-38,0)这个错,网上查询各种解决办法且投入一定的时间后也没解决,无奈之下重写,使用简简单单的代码先实现播放功能。从中得到的教训:作为练习的demo只是让自己熟悉功能,如果一开始耗费大量时间去写较为高级的会得不偿失,例如拖慢学习进度。

播放视频

播放视频主要由VideoView类实现。

主要方法:
image-20210803105422827.png

demo:

  1. package com.example.myapplication;
  2. import androidx.annotation.NonNull;
  3. import androidx.appcompat.app.AppCompatActivity;
  4. import androidx.core.app.ActivityCompat;
  5. import androidx.core.content.ContextCompat;
  6. import android.Manifest;
  7. import android.content.pm.PackageManager;
  8. import android.net.Uri;
  9. import android.os.Bundle;
  10. import android.os.Environment;
  11. import android.view.View;
  12. import android.widget.Button;
  13. import android.widget.Toast;
  14. import android.widget.VideoView;
  15. import java.io.File;
  16. public class PlayVideoActivity extends AppCompatActivity implements View.OnClickListener {
  17. private VideoView videoView;
  18. @Override
  19. protected void onCreate(Bundle savedInstanceState) {
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.activity_play_video);
  22. videoView = findViewById(R.id.video_view);
  23. Button play = findViewById(R.id.play);
  24. Button pause = findViewById(R.id.pause);
  25. Button replay = findViewById(R.id.replay);
  26. play.setOnClickListener(this);
  27. pause.setOnClickListener(this);
  28. replay.setOnClickListener(this);
  29. if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
  30. ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
  31. }else {
  32. initVideoPath();
  33. }
  34. }
  35. private void initVideoPath() {
  36. File file = new File(Environment.getExternalStorageDirectory(), "test.mp4");
  37. videoView.setVideoPath(file.getPath());
  38. }
  39. @Override
  40. public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  41. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  42. switch (requestCode){
  43. case 1:
  44. if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
  45. initVideoPath();
  46. }else {
  47. Toast.makeText(this,"拒绝权限将无法使用程序",Toast.LENGTH_SHORT).show();
  48. finish();
  49. }
  50. break;
  51. default:
  52. }
  53. }
  54. @Override
  55. public void onClick(View v) {
  56. switch (v.getId()){
  57. case R.id.play:
  58. if (!videoView.isPlaying()){
  59. videoView.start();
  60. }break;
  61. case R.id.pause:
  62. if (videoView.isPlaying()){
  63. videoView.pause();
  64. }
  65. break;
  66. case R.id.replay:
  67. if (videoView.isPlaying()){
  68. videoView.resume();
  69. }
  70. break;
  71. }
  72. }
  73. @Override
  74. protected void onDestroy() {
  75. super.onDestroy();
  76. if (videoView != null){
  77. videoView.suspend();
  78. }
  79. }
  80. }

注意:MP4文件要放在手机存储的根目录下。