Android入门(使用多媒体)
使用通知功能
通知渠道:自Android8.0后引入的新概念。每个应用程序可以自由的创建当前应用应该拥有哪些通知渠道。而这些通知渠道的控制权掌握在用户手中。用户可以选择是否响铃、是否振动或者是否要关闭这个渠道的通知。
对于应用而言,,通知渠道一旦创建就不可修改。所以一定要设计好有哪些渠道需要设计。
通知渠道的基本使用
首先需要一个
NotificationManager
对通知进行管理。可以通过调用Context的getSystemService()方法获取。这个方法接收一个参数用于确定获取系统的那个服务,如:val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
。Context.NOTIFICATION_SERVICE就是通知服务构建通知渠道:使用NotificationChannel类构建一个通知渠道,并调用NotificationManager的createNotificationChannel()方法完成创建。由于这些类是在Android8.0后添加的,因此使用前要先判断版本。
1
2
3
4if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, channelName, importance)
manager.createNotificationChannel(channel)
}创建一个通知渠道至少需要渠道ID、渠道名称以及重要等级这3个参数
通知的重要等级主要有IMPORTANCE_HIGH、IMPORTANCE_DEFAULT、IMPORTANCE_LOW、IMPORTANCE_MIN这几种通知一般都在后台的service去实现,前端的activity,或者broadcast使用的较少。
通知的默认使用方法
就版本的不同,8.0前和8.0后使用的方法不一样。所以AndroidX库中提供了兼容的API。AndroidX库中提供了一个NotificationCompat类,使用这个类的构造器创建Notification对象,就可以保证我们可以在所有的android上正常工作了。
- 使用构造器构造
Notification
对象,val notification = NotificationCompat.Builder(context, channelId).build()
,它接收两个参数,一个context,一个渠道id。需要和我们在创建通知渠道时指定的渠道ID相匹配才行。 - 上一步的通知只是一个空通知,什么都没有,而我们可以通过以下方法添加内容:
- setContentTitle()方法用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容。
- setContentText()方法用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容。
- setSmallIcon()方法用于设置通知的小图标,注意,只能使用纯alpha图层的图片进行设置,小图标会显示在系统状态栏上。
- setLargeIcon()方法用于设置通知的大图标,当下拉系统状态栏时,就可以看到设置的大图标了。
就以上方法完成后,可以通过调用NotificationManager的notify()方法将通知显示出来了。notify()方法接收两个参数:第一个参数是id,要保证为每个通知指定的id都是不同的;第二个参数则是Notification对象,这里直接将我们刚刚创建好的Notification对象传入即可。
这是一段样例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("normal", "normal", NotificationManager.IMPORTANCE_DEFAULT)
manager.createNotificationChannel(channel)
}
binding.sendNotice.setOnClickListener {
val notice = NotificationCompat.Builder(this, "normal")
.setContentTitle("This is my title")
.setContentText("This is 贺政涛's content")
.setSmallIcon(R.drawable.img_1)
.setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.img_1))
.build()
manager.notify(1, notice)
}
}
}系统会自动判断是否已经存在通知渠道,如果存在的话,它就不会再次创建了
PendingIntent
pendingintent和intent很多地方都是类似的。区别在于,Intent倾向于立即执行某个动作,而PendingIntent倾向于在某个合适的时机执行某个动作,也可以把PendingIntent简单地理解为延迟执行的Intent。
它可以通过几个默认的静态方法构建如:getActivity()方法、getBroadcast()方法,还是getService()方法。这些方法接受的参数都是一样的,第一个参数是context,第二个参数用不到,设为0即可。第三个参数是一个intent对象,需要自己创建。
第四个参数用于确定PendingIntent的行为,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT这4种值可选。
然后需要连接通知的pendingintent只需要在构建时再连缀一个setcontentIntent()即可
设计再点击通知后,该通知自动消失:一种是在
NotificationCompat.Builder中再连缀一个setAutoCancel()方法,一种是显式地调用NotificationManager的cancel()方法将它取消。
通知进阶
- 通知构造器有一个方法setStyle()。这个方法可以设置富文本。可以实现以下功能:
- 让通知可以放很长的文本,而不会被系统隐藏
- 可以再通知内容中放入图片
- 通知的重要程度:决定了通知是会以横幅的形式出现还是通知栏响一下
调用摄像头和相册
摄像头
1 | package top.zfxt.cameraalbumtest |
我们还需要在AndroidManifest.xml
中声明fileProvider
1 | <provider |
这是定义的xml路径文件
1
2
3
4
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="/" />
</paths>
访问相册
1 | binding.fromAlbumBtn.setOnClickListener { |
播放多媒体文件
mediaPlayer
Android常用的用来处理音频文件的是MediaPlayer类。
以上是一些常用的控制方法。
工作流程:
- 首先需要创建一个MediaPlayer对象,然后调用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
39class MainActivity : AppCompatActivity() {
private val mediaplayer = MediaPlayer()
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initMediaPlayer()
binding.play.setOnClickListener {
if (!mediaplayer.isPlaying) {
mediaplayer.start()
}
}
binding.pause.setOnClickListener {
if (mediaplayer.isPlaying) {
mediaplayer.pause() // 暂停播放
}
}
binding.stop.setOnClickListener {
if (mediaplayer.isPlaying) {
mediaplayer.reset() // 停止播放
}
}
}
private fun initMediaPlayer() {
val assetMannager = assets
val fd = assetMannager.openFd("肉肉.mp3")
mediaplayer.setDataSource(fd.fileDescriptor, fd.startOffset, fd.length)
mediaplayer.prepare()
}
override fun onDestroy() {
super.onDestroy()
mediaplayer.stop()
mediaplayer.release()
}
}