首页 > 其他分享 >20240203

20240203

时间:2024-02-04 23:56:03浏览次数:33  
标签:... 20240203 fun 广播 intent override BroadcastReceiver

Android中Service机制

基础

广播的类型:标准广播(高效,无法截断)、有序广播(同步执行,可以截断,有先后顺序)

接收系统广播

动态注册监听系统广播

BroadcastReceiver的创建方法:新建一个类,让它继承自BroadcastReceiver,并重写父类的onReceive()方法。

书上的示例,监听系统时间变化的广播,显示通知。

class MainActivity : AppCompatActivity() {
	lateinit var timeChangeReceiver: TimeChangeReceiver
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)
		//过滤要监听的广播:系统时间发生变化发出的“android.intent.action.TIME_TICK”
		val intentFilter = IntentFilter()
		intentFilter.addAction("android.intent.action.TIME_TICK")
		//创建TimeChangeReceiver的实例,并调用registerReceiver注册
		timeChangeReceiver = TimeChangeReceiver()
		registerReceiver(timeChangeReceiver, intentFilter)
	}
	override fun onDestroy() {
		super.onDestroy()
		//销毁时取消注册
		unregisterReceiver(timeChangeReceiver)
	}
	inner class TimeChangeReceiver : BroadcastReceiver() {
		override fun onReceive(context: Context, intent: Intent) {
			Toast.makeText(context, "Time has changed", Toast.LENGTH_SHORT).show()
		}
	}
}
//targetApi 31测试是可以这样写的

静态注册实现开机启动

喜闻乐见的被滥用的功能,频繁啊唤醒的恶意App,即使可能离不来,笑。

AndroidStudio创建静态BroadcastReceiver,以及会自动在AndroidManifest中注册。

<receiver>标签中添加<intent-filter>声明对应action,并且声明接收开机广播的权限。

<?xml version="1.0" encoding="utf-8"?>  
<manifest
	...>  
	<!--接收开机广播毕竟是个有点敏感的权限呢-->
	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />  
	...
	<application
		...>	 
		<receiver  
			android:name=".BootCompleteReceiver"  
			android:enabled="true"  
			android:exported="true">  
			<intent-filter>
				<!--声明对应action-->
				<action android:name="android.intent.action.BOOT_COMPLETED" />  
			</intent-filter>  
		</receiver>   
		...
	</application>  
</manifest>

实体机和虚拟机盯着看了半天没看到Toast消息,不知道为什么,不过加了条log的输出,也算是看到了,真的开机自启动了呢!

自定义广播

发送标准广播

class MainActivity : AppCompatActivity() {
	...
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)
		button.setOnClickListener {
			val intent = Intent("com.example.broadcasttest.MY_BROADCAST")
			//指定这条广播是发送给哪个应用程序的,让它变成一条显式广播
			intent.setPackage(packageName)
			sendBroadcast(intent)
		}
	...
	}
	...
}

接收广播的BroadcastReceiver,和前面的写法是一样的

广播是使用Intent来发送的,因此你还可以在Intent中携带一些数据传递给相应的BroadcastReceiver

发送有序广播

有序广播的发送

sendBroadcast(intent)改变为sendOrderedBroadcast(intent, null),第二个参数是一个与权限相关的字符串。

有序广播的接收

...
<receiver
	android:name=".MyBroadcastReceiver"
	android:enabled="true"
	android:exported="true">
	<!--这里的priority为BroadcastReceiver设置了优先级,优先级高的先收到广播-->
	<intent-filter android:priority="100">
		<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
	</intent-filter>
</receiver>
...

有序广播的截断

class MyBroadcastReceiver : BroadcastReceiver() {
	override fun onReceive(context: Context, intent: Intent) {
		Toast.makeText(context, "received in MyBroadcastReceiver",
		Toast.LENGTH_SHORT).show()
		abortBroadcast()//截断这条广播
	}
}

广播的最佳实践

要在onReceive()方法中弹出一个对话框,需要动态注册的BroadcastReceiver,可以在BaseActivity中注册,所有Activity都继承自BaseActivity。

将注册和取消注册放在onResume()onPause()的生存周期,就能做到只保证栈顶的Activity才能接收这条广播。

open class BaseActivity : AppCompatActivity() {
	...
	override fun onResume() {
		super.onResume()
		val intentFilter = IntentFilter()
		intentFilter.addAction("com.example.broadcastbestpractice.FORCE_OFFLINE")
		receiver = ForceOfflineReceiver()
		//注册Receiver
		registerReceiver(receiver, intentFilter)
	}
	override fun onPause() {
		super.onPause()
		//取消注册
		unregisterReceiver(receiver)
	}
	...
}

标签:...,20240203,fun,广播,intent,override,BroadcastReceiver
From: https://www.cnblogs.com/sugar-refinery/p/18007245

相关文章

  • 北京地铁经纬度结构化数据收集20240203
    地铁图 原始数据共250个站点,或有遗漏1苹果园,39.9263251384,116.17778062822古城,39.9072014648,116.19024753573八角游乐园,39.9074319023,116.21282100684八宝山,39.9072673042,116.23582363135玉泉路,39.9073331435,116.25303268436五棵松,39.......
  • 20240203-图论随记
    最短路负环判断#include<bits/stdc++.h>usingnamespacestd;structnode{intfrom,to,v;}edge[100005];#defineoo2000000000intdis[100005];intmain(){intn,m,s,t;cin>>n>>m>>s>>t;for(inti=1;i<=m;i++){......