萌新Android笔记----IntentFilter匹配篇

开个头

101要从黄铜调回黑铁了,太难了呀,都怪匹配给到的队友天天拉胯。。。(上单头铁盖伦打wn)。。Android的匹配机制也是给萌新当头一棒。但萌新突出一个莽字,不知道的东西就冲塔搞他。。首先我们萌新知道的启动activity分为两种,显式调用和隐式调用。原则上一个Intent不能即是显式调用又是隐式调用,两者真共存的话以显式调用为主。
显式调用
需要明确指定被启动对象的组件信息,包括包名和类名。例如:

		Intent intent = new Intent(Mainactivity.this,SecondActivity.class);
		startActivity(intent);

隐式调用
不需要明确指定组件信息。但需要Intent能匹配目标组件的IntentFilter中所设置的过滤信息,这些过滤信息有action,category,data,(这些属性是在AndroidMenifest里设置的)举个栗子吧:

<intent-filter>//MainActivity里的第一个intentfilter
	<action android:name="com.ryg.charpter_1.c"/>
	<action android:name="com.ryg.charpter_1.d"/>
	<category android:name="com.ryg.category.c"/>
	<category android:name="com.ryg.category.d"/>
	<category android:name="android.intent.category.DEFAULT"/>
	<data android:mimeType="text/plain"/>
</intent-filter>
<intent-filter>//MainActivity里的第二个intentfilter
	<action android:name="android.intent.action.SEND"/>
	<action android:name="com.ryg.charpter_1.d"/>
	<category android:name="com.ryg.category.c"/>
	<category android:name="android.intent.category.DEFAULT"/>
	<category android:name="com.ryg.category.d"/>
	<data android:mimeType="text/plain"/>
</intent-filter>

为了匹配过滤列表,需要同时匹配过滤列表中的action,category,data信息,否则匹配失败。值得一提的是一个过滤列表中的action,category和data可以有多个,而一个activity可以有多组过滤列表,如上。一个intent只有同时匹配一组intentfilter才能成功启动对应的activity。接下来就一一介绍下各种属性 匹配规则吧

  1. action的匹配规则
    action是一个字符串,我们可以自己写,也可以用系统预定义的action。action的匹配规则是action的字符串值必须完全一样,只要和一组intentfilter的任意一个action匹配就ok,但如果intent中没有指定action就会导致匹配失败。
    ps:action区分大小写,大小写不同会导致匹配失败。
  2. category的匹配规则
    category同样是一个字符串,同action我们可以自己写,也能用系统给的。但category的匹配规则和action有很大不同,在intent里action必须有,category可以没有也可以有2个及以上,,但如果往intent里设置了category,他或他们就必须和一个filter中的category相同。除此之外,萌新发现两个IntentFilter里都有
<category android:name="android.intent.category.DEFAULT"/>

看这DEFAULT应该就能猜出大半,我们不往intent里加category,系统加啊,加的就是上面这行。所以为了我们的activity能接收隐式调用,就必须在intent-filter中指定上面这个category。

  1. data的匹配规则
    data的匹配规则和action类似,如果过滤规则中定义了data,那么Intent中也必须得定义可匹配的data。首先来看下data的语法
<data android:scheme="string"
	  android:host="string"
	  android:post="string"
	  android:path="string"
	  android:pathPattern="string"
	  android:pathPrefix="string"
	  android:mimeType="string"/>

data由两部分组成,mimeType和URI。mimeType指媒体类型,可以表示图片,文本,视频等不同的媒体格式(说白了就是告诉你绑定了啥后缀的东西)而URI(路径)的结构就有意思了,她长这样

<scheme>://<host>:<post>/[<path>|<pathPrefix>|<pathPattern>]

举个栗子

http://www.baidu.com:80/search/info

Scheme ☞ URI的模式,比如http,file,content,如果不指定scheme,那么URI其他参数都无效,最终URI无效。
Host ☞ URI的主机名,比如www.baidu.com,host未指定也会导致URI无效。
Port ☞ 这是URI的端口号,比如上头的80
PathPathPatternpathPrefix ☞ 这Ⅲ代表了路径信息,path表示完整的路径,pathPattern也表示完整路径,但他可以包含“”,“”表示0个或多个字符(比如“image/*”意思就是指定了媒体类型为所有的图片),pathPrefix表示路径的前缀信息。
data的匹配分两者情况

  1. 只给了mimeType没给URI

例如:

<intent-filter>
	<data android:mimeType="image/*" />
	.......
</intent-filter>

那么Intent里的mimeType必须是"image/*"才能匹配。此外,这种情况下虽然没指定URI,但有默认值,URI默认值为content和file,所以我们即使不想通过URI指定也得在intent设置的时候把intent中的URI部分的scheme设置为content或file才能成功匹配。我们可以这么写
intent.setDataAndType(Uri.parse("file://abc"),"image/png")
有必要提一句,如果要为Intent指定完整的data,不能先用setData再用setType,因为他们彼此会清除对方的值,要用setDataAndType。

  1. 既有mimeType又有URI
    例如
<intent-filter>
	<data android:mimeType="video/mpeg" android:scheme="http"/>
	<data android:mimeType="audio/mpeg" android:scheme="http"/>
</intent-filter>

这种情况下每个data都指定了完整的属性值,既有URI又有mimeType。所以我们可以这么写

intent.setDataAndType(Uri.parse("http://abc"),"video/mpeg")

出了以上特点,data还有一点和action不一样

<intent-filter>
	<data android:scheme="file" android:host="www.baidu.com"/>
</intent-filter>

<intent-filter>
	<data android:scheme="file" />
	<data android:host="www.baidu.com" />
</intent-filter>

这两种写法,作用是一样的。
还有就是千万别忘了我们如果没设置scheme的话,他是有默认值的。默认值是file和content,这点很重要。setDataAndType的时候不能忘了这点。

总结:萌新常用的是隐式匹配方式,但实际上是显式匹配更准确,好用。但实际上intentfilter有什么用呢?简单来讲filter是处理活动的必须步骤,比如你发送一个intent希望这个activity打开一个网页,就要用到intentfilter,action表示了这个activity接收到intent后要干啥,category像安检,你得给出身份证明才能通过,而data更像是甲方,他想要啥你就得给啥,严格的甲方连具体的URI需求都给出来,宽松的送钱的甲方只说了mimeType格式,只要满足这个格式就能过关。如果想取出data里的东西我们可以用getData,想取出type就用getType。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!对于 Android Wi-Fi 直连传输数据的实践,可以使用 Android 的 Wi-Fi P2P(Wi-Fi Direct)功能来实现。下面是一个简单的示例代码,演示了如何在两台设备之间进行 Wi-Fi 直连传输数据: 首先,在 AndroidManifest.xml 文件中添加以下权限: ```xml <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> ``` 然后,在你的 Activity 中添加以下代码: ```java private WifiP2pManager mManager; private WifiP2pManager.Channel mChannel; private BroadcastReceiver mReceiver; private IntentFilter mIntentFilter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化 Wi-Fi P2P 相关对象 mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mManager.initialize(this, getMainLooper(), null); // 注册广播接收器,用于接收 Wi-Fi P2P 相关的系统广播 mReceiver = new WiFiDirectBroadcastReceiver(); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); } @Override protected void onResume() { super.onResume(); registerReceiver(mReceiver, mIntentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mReceiver); } // 开始 Wi-Fi P2P 搜索设备 public void discoverPeers(View view) { mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // 搜索成功 } @Override public void onFailure(int reasonCode) { // 搜索失败 } }); } // 连接到指定设备 public void connectToDevice(WifiP2pDevice device) { WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.deviceAddress; mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { // 连接成功 } @Override public void onFailure(int reason) { // 连接失败 } }); } // 发送数据 public void sendData(byte[] data) { // 通过 Socket 发送数据 // 这里省略具体实现代码 } // 接收数据 public void receiveData(byte[] data) { // 通过 Socket 接收数据 // 这里省略具体实现代码 } // 广播接收器,用于接收 Wi-Fi P2P 相关的系统广播 private class WiFiDirectBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { // Wi-Fi P2P 状态变化 } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // 可用的对等设备列表发生变化 } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { // Wi-Fi P2P 连接状态发生变化 } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { // 本设备的信息发生变化 } } } ``` 以上是一个简单的 Android Wi-Fi 直连传输数据的实践示例,其中涉及到了 Wi-Fi P2P 的搜索设备、连接设备以及发送和接收数据的过程。需要注意的是,具体的发送和接收数据的实现需要借助 Socket 或其他网络通信方式来完成,这里只是一个简单的示例。 希望对您有所帮助!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值