????????目录
一、背景
二、新建AlarmService类,继承Service
三、新建AlarmReceiver,继承BroadcastReceiver
四、MainActivity
五、布局
六、补充
一、背景
AndroidStudio版本2021.2.1,sdk版本29以上
最近写软件碰到一个问题——消息推送,还是那种不需要挂在后台就能实现推送效果的功能。
直接看代码吧。
二、新建AlarmService类,继承Service
这个服务用来启动AlarmManage,当然可以根据自己喜欢放在activity里,效果一样。
class AlarmService : Service() {
override fun onBind(p0: Intent?): IBinder? {
return null
}
@SuppressLint("UnspecifiedImmutableFlag")
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val manager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
//设置这个intent,是为了能够准确通知到广播
val i = Intent("toAlarmReceiver")
Log.i("test1", "onStartCommand: $packageName, $packageName.receiver.AlarmReceiver")
i.component = ComponentName(packageName, "$packageName.receiver.AlarmReceiver")
val pendingIntent =
PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT)
//这个Int类型的time是前台activity传过来的
val time = intent.getIntExtra("time", 0)
manager.setAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + time * 1000L,
pendingIntent
)
return super.onStartCommand(intent, flags, startId)
}
}
关于AlarmManager.RTC_WAKEUP,可以看文章结尾,我的参考文章。
三、新建AlarmReceiver,继承BroadcastReceiver
使用广播能够实现在关闭app后台的时候,接收讯息实行操作。
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
//设置通知的一些必要信息,都是字面意思
val notify = NotificationCompat.Builder(context, "xxm")
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle("标题")
.setContentText("看通知,看通知哦!").build()
val manager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.notify(1, notify)
}
}
关于notification和BroadcastReceiver,在activity里还有操作。
四、MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
@SuppressLint("ShortAlarm")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//注册NotificationChannel,Android8之后需要,可根据自己选择
val channel = NotificationChannel("xxm", "通知", NotificationManager.IMPORTANCE_HIGH)
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
//动态注册BroadcastReceiver
val receiver = AlarmReceiver()
val filter = IntentFilter()
filter.addAction("toAlarmReceiver")
registerReceiver(receiver, filter)
//点击函数
click()
}
private fun click() {
binding.btn.setOnClickListener {
val input = binding.edt.text.toString().trim()
if (input.isNotEmpty()) {
val intent = Intent(this, AlarmService::class.java)
intent.putExtra("time", input.toInt())
startService(intent)
}
}
}
}
这里说一下NotificationChannel,这是Android官方要求,如果直接使用NotificationCompat.Builder(context)来构造通知,而不带channel的参数,会被系统提示该方法已被弃用。
还有就是广播,不只要在Manifest清单中注册,还要动态注册,具体可自行百度。
五、布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginEnd="14dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.319">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="延迟推送时间:"
android:textSize="18sp" />
<EditText
android:id="@+id/edt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="number"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="秒"
android:textSize="18sp" />
</LinearLayout>
<Button
android:id="@+id/btn"
android:layout_width="140dp"
android:layout_height="wrap_content"
android:text="开始"
android:textSize="18sp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
这个很简单,就不多说了。
六、补充
在真机测试的时候,要记得开启通知权限,打开自启动。我用的miui,打开自启动,省电策略无限制,通知设为重要,并且允许悬浮通知。
最后问一下,输入小于5秒时,Alarm会默认延迟5秒,这个还请各位大神指点一二。
附上demo地址,需要自行下载
欢迎批评指点。
参考:Android 接收不到广播的原因解决? ? ?Android之AlarmManger
??????????
|