通知
notification可以对消息进行区分,也就是Android 8.0 系统引入的通知渠道,渠道一旦划分,则无法修改,因此开发者需要仔细考虑。
以Twitter为例,在设置中的消息分类非常之细:
创建渠道组别
发送的通知,首先需要定义它的组名,也就是要先“给组命名”
如下:
@SuppressLint("NewApi")
fun createManager()
{
// 首先需要NotificationManager对通知进行管理
manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// 这里创建的其实是渠道组别,而不是创建通知
val channel = NotificationChannel(
"channelId", // 渠道ID, 给与通知所属类别,也就是“组名”
"channelName", // 给用户的解释组名
NotificationManager.IMPORTANCE_HIGH
)
manager.createNotificationChannel(channel)
}
该方法只会执行一次,只要判断需要产生的渠道存在,就不会重复创建。
创建的解释组名为“channelName”可在应用查看:
基本发送通知
private fun createNotification()
{
val notification = NotificationCompat.Builder(
this,
"channelId" // 发送渠道的ID,如果渠道id不存在,则无法显示
).run {
setContentTitle("标题")
setContentText("正文")
// 注意,只能使用纯alpha图片进行设置,否则不同机型差异较大
setSmallIcon(R.drawable.ic_launcher_background)
setLargeIcon(
BitmapFactory.decodeResource(resources, androidx.navigation.ui.ktx.R.drawable.abc_btn_switch_to_on_mtrl_00001)
)
build()
}
manager.notify(
1, // id,要保证每个通知指定的id都是不同的
notification
)
}
解释说明:
通知的点击事件
PendingIntent
PendingIntent与Intent类似,都可以指明某个“意图”,前者倾向于某个合适时候执行,后者一般是立即执行,具体用法这里也不做介绍。
点击通知跳转主要改成以下方法,跳转到TestActivity
@RequiresApi(Build.VERSION_CODES.S)
private fun createNotification()
{
val notification = NotificationCompat.Builder(
this,
"channelId" // 发送渠道的ID
).run {
setContentTitle("标题")
setContentText("正文")
setSmallIcon(R.drawable.ic_launcher_background)
setLargeIcon(
BitmapFactory.decodeResource(resources, androidx.navigation.ui.ktx.R.drawable.abc_btn_switch_to_on_mtrl_00001)
)
setContentIntent(
PendingIntent.getActivity(
this@MainActivity,
0,
Intent(this@MainActivity, TestActivity::class.java),
PendingIntent.FLAG_MUTABLE
)
)
build()
}
manager.notify(
1, // id,要保证每个通知指定的id都是不同的
notification
)
}
这里图标并没有消失,有两种方法:
- 狭义的消失,只要在上文notification变量build()之前调用
setAutoCannel(true)
即可 - 广义的消失,需要提供id,也就是通知所提交的manager.notify的第一个参数,而执行的时间可以自定义,一般并不配合点击事件决定(因为不一定所有点击事件都会打开新的Activity,在之中初始运行消除通知的代码)。
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.cancel(
1 //需要消除的通知的id
)
使用富文本通知
我们知道,单纯使用setContentText
对于过长文本无法全部显示,这时候就需要使用setStyle()
方法
长文本例子
@RequiresApi(Build.VERSION_CODES.S)
private fun createNotification()
{
val notification = NotificationCompat.Builder(
this,
"channelId" // 发送渠道的ID
).run {
setContentTitle("标题")
setStyle(
NotificationCompat.BigTextStyle() // 这个对象用于封装长文本信息
.bigText("If the platform does not provide large-format notifications, this method has no effect. The\n" +
"user will always see the normal notification view.\n" +
"This class is a \"rebuilder\": It attaches to a Builder object and modifies its behavior, like so:")
)
setSmallIcon(R.drawable.ic_launcher_background)
setLargeIcon(BitmapFactory.decodeResource(resources, androidx.navigation.ui.ktx.R.drawable.abc_btn_switch_to_on_mtrl_00001))
build()
}
manager.notify(1, notification)
}
图片例子
@RequiresApi(Build.VERSION_CODES.S)
private fun createNotification()
{
val notification = NotificationCompat.Builder(
this,
"channelId" // 发送渠道的ID
).run {
setContentTitle("标题")
setStyle(
NotificationCompat.BigPictureStyle().bigPicture(
BitmapFactory.decodeResource(resources, R.drawable.picture)
)
)
setSmallIcon(R.drawable.ic_launcher_background)
// setLargeIcon(BitmapFactory.decodeResource(resources, androidx.navigation.ui.ktx.R.drawable.abc_btn_switch_to_on_mtrl_00001))
build()
}
manager.notify(1, notification)
}
通知等级
通知渠道的等级越高,发出的通知越容易被注意(但在高版本中,这可能不适用,需要用户手动打开),并且不会像低等级一样被列入不重要通知或直接隐藏起来堆到末尾,而是排在首要位置上。
开发者只能在创建渠道(组名)的时候为其指定重要性,之后只能用户进行修改,无法再通过变更代码来更改。
调用相机摄像
使用摄像头拍照
https://www.jianshu.com/p/29b349ff7f1a
读取本地照片
读取本地照片,重在打开文件选择器:
private fun openFileChoice()
{
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"
// 已弃用
// startActivityForResult(intent, 2)
}