Android第一行代码--多媒体

运用手机多媒体

通知(Notification)

创建通知的详细步骤

  • 首先需要一个NotificationManager对通知进行管理。
1
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
  • 接着使用Builder构造器来创建Notification对象
1
Notification notification = new NotificationCompat.Builder(context).build();
  • 设置许多方法丰富Notification对象
1
2
3
4
5
6
7
Notification notification = new NotificationCompat.Builder(context)
.setContentTile("This is content titile")//用于指定通知的标题内容
.setContextText("This is content")//指定通知的正文内容
.setWhen(System.currentTimeMillis())//通知被创建的时间
.setSmallIcon(R.drawable.small_icon)//设置通知的小图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.large_icon))//设置通知的大图标
.build();
  • 使用notify()方法可以让通知显示出来
    • 参数一:id,保证每个通知所指定的id都是不同的
    • 参数二:Notification对象
1
manager.notify(1,notification);

NotificationTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void onClick(View v) {
switch (v.getId()){
case R.id.send_notice:
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("this is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.build();
notificationManager.notify(1,notification);
break;
default:
break;
}

PendingIntent

PendingIntent倾向于在某个合适的时机去执行某个动作。这里第一行代码也比喻为延迟执行的Intent

PendingIntent可以用几种方法提供实例

  • getActivity()方法
  • getBroadcast()方法
  • getService()方法

这几个方法接收参数相同

  • 参数一:Context
  • 参数二:一般用不到,传入0
  • 参数三:Intent对象
  • 参数四:用于确定PendingIntent的行为
    • FLAG_ONE_SHOT
    • FLAG_NOCREATE
    • FLAG_CANCEL_CURRENT
    • FLAG_UPDATE_CURRENT
    • 通常传0即可
1
2
3
4
                Intent intent = new Intent(this, NotificationActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
...
.setContentIntent(pi)

消失显示在系统通知栏的图标

1
2
3
4
//方法一
.setAutoCancel(true)
//方法二
manager.cancel(1);
  • setSound()方法用于在通知发出的时候播放一段音频。
    • 参数一:接收一个Uri参数
1
.setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
  • 通知到来的时候让手机进行振动
1
2
3
4
5
6
7
8
9
10
11
12
/*
下标为0表示手机静止的时长
下标为1表示手机振动的时长
下标为2表示手机静止的时长
...
以此类推
*/
.setVibrate(new long[]{0,1000,1000,1000})
/*
还需要添加权限
*/
<uses-permission android:name="android.permission.VIBRATE"/>
  • 通知时控制手机LED灯的显示
1
2
3
4
5
6
/*
第一个参数用于指定LED灯的颜色
第二个参数用于指定LED灯亮起的时长
第三个参数用于指定LED灯暗去的时长
*/
.setLights(Color.GREEN,1000,1000)
  • 通知的默认效果
1
.setDefaults(NotificationCompat.DEFAULT_ALL)
  • 显示通知长段文字
1
.setStyle(new NotificationCompat.BigTextStyle().bigText("....."))
  • 显示一张大图片
1
.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.big_image)))
  • 设置通知的重要程度
    • PRIORITY_DEFAULT默认的重要程度
    • PRIORITY_MIN表示最低的重要程度
    • PRIORITY_LOW表示较低的重要程度
    • PRIORITY_HIGH表示较高的重要程度
    • PRIORITY_MAX表示最高的重要程度,这类通知消息必须要让用户立刻看到
1
.setPriority(NotificationCompat.PRIORITY_MAX)

调用摄像头和相册

调用摄像头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
...
public void onClick(View v) {
//用于存放摄像头拍摄的照片
//getExternalCacheDir()用于获取应用关联缓冲目录
//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){
/*
参数一:context
参数二:唯一的字符串
参数三:File对象
*/
imageUri = FileProvider.getUriForFile(MainActivity.this,"com.example.cameraalbumtest.fileprovider",outputImage);

}
else{
//将File对象转化为Uri对象
imageUri = Uri.fromFile(outputImage);
}
//隐式intent,action为android.media.action.IMAGE_CAPTURE
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//指定图片存储的路径
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
//启动activity
startActivityForResult(intent,TAKE_PHOTO);
}
});
...
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode){
case TAKE_PHOTO:
if(resultCode == RESULT_OK){
try{
//将拍摄的图片解析成Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
//将Bitmap对象使用imageView呈现出来
picture.setImageBitmap(bitmap);
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
break;
default:
break;
}

配置文件

1
2
3
4
5
6
7
8
9
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.cameraalbumtest.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>

file_paths.xml

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path
name="my_images"
path="."/>
</paths>

调用相册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
chooseFromAlbum.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//检查是否有写外部存储的权限
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
//若没有则请求获取,利用String[]{}写入需要获得的权限
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}else {
openAlbum();
}
}
});
...
private void openAlbum(){
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent,CHOOSE_PHOTO);
}
...
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] 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;
}
}
...
case CHOOSE_PHOTO:
if(resultCode == RESULT_OK){
if(Build.VERSION.SDK_INT>=19){
handleImageOnKitKat(data);
}
else{
handleImageBeforeKitKat(data);
}
}
break;
...
//指示Lint应将此类型视为针对给定API级别,无论项目的target版本是多少
@TargetApi(19)
private void handleImageOnKitKat(Intent data){
String imagePath = null;
/*
getData()检索intent正在操作的数据
Uri代表要操作的数据
*/
Uri uri = data.getData();
/*
DocumentsContract用于定义documents provider和平台之间的连接
isDocumentUri()方法用于测试给定的Uri是否为DocumentsProvider支持的Document
*/
if(DocumentsContract.isDocumentUri(this,uri)){
/*
Uri:content://com.android.providers.media.documents/document/image%3A447
*/

//如果是document类型的Uri,则通过document id处理

/*
在4.4之前Uri的形式Uri : content://media/extenral/images/media/17766
在4.4之后Uri的形式content://com.android.providers.media.documents/document/image%3A82482
参考https://blog.csdn.net/yancychas/article/details/76695136
4.4之后的Uri经过了documents的封装
*/

/*
这里取出的docId为image:447,即取出document后面的值
*/

String docId = DocumentsContract.getDocumentId(uri);

/*
getAuthority()方法用于获取URI中authority的部分的解码
*/
if("com.android.providers.media.documents".equals(uri.getAuthority())){
//取出id值
String id = docId.split(":")[1];
/*
MediaStore用于连接medio provider 与应用程序
MediaStore.Images用于收集所有MIME类型的images
MIME类型是媒体类型
*/
String selection = MediaStore.Images.Media._ID + "=" + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
}else if("content".equalsIgnoreCase(uri.getScheme())){
/*
uri.getScheme()用于获取主机号
*/
imagePath = getImagePath(uri,null);
}else if("file".equalsIgnoreCase(uri.getScheme())){
imagePath = uri.getPath();
}
displayImage(imagePath);

}
}
private void handleImageBeforeKitKat(Intent data){
Uri uri = data.getData();
String imagePath = getImagePath(uri,null);
displayImage(imagePath);
}
private String getImagePath(Uri uri,String selection){
String path = null;
/*
query()方法用于检索数据
参数一:uri 类型Uri 为检索的内容
参数二:projection 类型String 要返回的列表
参数三:queryArgs 类型Bundle 包含操作所需的附加消息
参数四:cancellationSignal 取消正在进行的操作信号
*/
Cursor cursor = getContentResolver().query(uri,null,selection,null,null);
if(cursor != null){
if(cursor.moveToFirst()){
/*
getColumnIndex(String columnName)用于获取指定列的下标
*/
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
System.out.println(path);
}
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();
}
}
}

播放多媒体文件

播放音频

  • 首先需要创建MeidaPlayer对象
  • 接着调用setDataSource()方法设置音频文件的路径
  • 再调用prepare()方法使MediaPlayer进入到准备状态
  • 调用start()方法开始播放音频
  • 调用pause()方法暂停播放
  • 调用reset()方法就会停止播放
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    private void initMediaPlayer(){
try{
// System.out.println(Environment.getExternalStorageDirectory());
File file = new File("/storage/emulated/0/Pictures","music.mp3");
mediaPlayer.setDataSource(file.getPath());
mediaPlayer.prepare();//这里不能漏掉,否则会报错
}catch (Exception e){
e.printStackTrace();
}
}

@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){
initMediaPlayer();
}else{
Toast.makeText(this,"拒绝权限将无法继续使用",Toast.LENGTH_SHORT).show();
finish();
}
break;
default:
}
}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.play:
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
}
break;
case R.id.stop:
if(mediaPlayer.isPlaying()){
mediaPlayer.reset();
initMediaPlayer();
}
break;
case R.id.pause:
if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
default:
break;
}

}

@Override
protected void onDestroy() {
super.onDestroy();
if(mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
}
}
}

播放视频

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private VideoView videoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoView = findViewById(R.id.video_view);
Button play = (Button)findViewById(R.id.play);
Button pause = (Button)findViewById(R.id.pause);
Button replay = (Button)findViewById(R.id.replay);
play.setOnClickListener(this);
pause.setOnClickListener(this);
replay.setOnClickListener(this);
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{
initVideoPath();
}
}
private void initVideoPath(){
File file = new File("/storage/emulated/0/Pictures","movie.mp4");
videoView.setVideoPath(file.getPath());
}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.play:
if(!videoView.isPlaying()){
videoView.start();
}
break;
case R.id.pause:
if(videoView.isPlaying()){
videoView.pause();
}
case R.id.replay:
if(videoView.isPlaying()){
videoView.resume();
}
break;
}

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 1:
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
initVideoPath();
}
else{
Toast.makeText(MainActivity.this,"拒绝权限无法使用程序",Toast.LENGTH_SHORT).show();
}
}
}

@Override
protected void onDestroy() {
super.onDestroy();
if(videoView!=null){
videoView.suspend();
}
}
}


Android第一行代码--多媒体
https://h0pe-ay.github.io/Android第一行代码--运用手机多媒体/
作者
hope
发布于
2023年6月27日
许可协议