Android基础之--Intent(应用图标不显示问题)

前言

今天遇到apk设置了LAUNCHER但不显示图标的问题,于是开始好好了解了下Intent的属性和用法,在学习过程中找到了问题原因并成功解决了问题(问题放在第3部分内容),在这里总结下。

  • Intent的调用方式

1. 显示调用

显示调用需要明确的指出被启动对象的类名;

  • Intent第1个参数为当前类;
  • 第2个参数为要跳转到的类
Intent intent = new Intent(MainActivity.this,xxxActivity.class);
startActivity(intent);

2. 隐式调用

需要Intent能匹配目标组件的IntentFilter中所设置的过滤信息.如果不匹配将无法启动目标Activity;

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:label="@string/app_name"
    android:theme="@style/Theme.Test">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

隐式调用主要是通过在Andriodmanifest.xml文件中给Activity添加过滤器,为该Activity设置属性,隐式调用时根据属性寻找匹配的Activity来启动

Intent intent = new Intent(); 
intent.setAction("android.intent.action.View"); 
startActivity(intent);

如果存在多个应用的Activity的属性均匹配,则需要选择应用启动;
如:在手机端播放音频,会弹出提示框询问你要使用 (QQ音乐、网易云音乐、本地播放器等) 哪种应用来播放。

------------------那么接下来总结下隐式Intent的主要属性和匹配规则------------------

  • 隐式Intent主要的3种属性及匹配规则

1. Action

Action属性主要用来指定组件要执行的动作;
系统内置的部分Action如下所示:

Action常量组件动作
ACTION_MAINActivityAndroid Application的入口,每个Android应用必须且只能包含一个此类型的Action声明
ACTION_VIEWActivity系统根据不同的Data类型,通过已注册的对应Application显示数据
ACTION_EDITActivity系统根据不同的Data类型,通过已注册的对应Application编辑示数据
ACTION_DIALActivity打开系统默认的拨号程序,如果Data中设置了电话号码,则自动在拨号程序中输入此号码
ACTION_CALLActivity直接呼叫Data中所带的号码。
ACTION_ANSWERActivity接听来电
ACTION_SENDActivity由用户指定发送方式进行数据发送操作。
ACTION_SENDTOActivity系统根据不同的Data类型,通过已注册的对应Application进行数据发送操作
ACTION_BOOT_COMPLETEDBroadcastAndroid系统在启动完毕后发出带有此Action的广播
ACTION_TIME_CHANGEDBroadcastAndroid系统的时间发生改变后发出带有此Action的广播
ACTION_PACKAGE_ADDEDBroadcastAndroid系统安装了新的Application之后发出带有此Action的广播
ACTION_PACKAGE_CHANGEDBroadcastAndroid系统中已存在的Application发生改变之后(如应用更新操作)发出带有此Action的广播
ACTION_PACKAGE_REMOVEDBroadcast卸载了Android系统已存在的Application之后发出带有此Action的广播
  • 匹配规则
  1. 一个intent-filter中至少得有一个Action属性;
  2. 一个intent-filter中可以有多个Action,只要Intent中的Action能够和Activity过滤规则中的任何一个Action相同即可匹配成功。
2. Category

Category属性用于指定当前动作(Action)被执行的环境;
常用的Category如下所示:

Category常量意义
CATEGORY_DEFAULTAndroid系统中默认的执行方式,按照普通Activity的执行方式执行
CATEGORY_HOME设置该组件为Home Activity,随系统启动而运行
CATEGORY_LAUNCHER设置该组件为在当前应用程序启动器中优先级最高的Activity,通常与入口ACTION_MAIN配合使用
CATEGORY_BROWSABLE设置该组件可以使用浏览器启动
  • 匹配规则
  1. 一个intent-filter中可以不声明Category属性(默认为DEFAULT),也可以声明多个Category;
  2. Activity中存在的所有Category(个数可以少于Intent中存在的Category)必须与Intent中的Category相同才能匹配成功;
  3. Category属性是一个执行Action的附加信息,只通过Category属性匹配Activity是无法匹配的,需要和Action属性一起匹配来启动Activity。
3. Data

Data属性通常用于向Action属性提供操作的数据(如点击链接跳转到浏览器显示在输入框中);
Data 由2部分组成:

  • MineType :指的是媒体类型(图片imgage/jpeg、视频viedo/*);
  • URI:通用资源标识符,格式为scheme://host:port/path

URI的属性如下所示:

属性意义
SchemeURL的模式,如果URI中没有指定Scheme,那么整个URI无效(默认值为content 和 file)
HostURI的host,①如果指定了scheme和port,path等其他参数,但是host未指定,那么整个URI无效,②如果只指定了scheme没有指定host和其他参数,URI是有效的
PortURI端口,当URI指定了scheme 和 host 参数时port参数才有意义
path用来匹配完整的路径
pathPrefix用来匹配路径的开头部分
pathPattern用表达式来匹配整个路径

系统内置的部分Data属性常量如下:

Data取值意义
tel://号码数据格式,后接电话号码
mailto://邮件数据格式,后接邮件收件人地址
smsto://短息数据格式,后接短信接收号码
content://内容数据格式,后接需要读取的内容
file://文件数据格式,后接文件路径
geo://经纬数据格式,后接经纬度数据
http://超文本,后接网络资源URI
  • 匹配规则
  1. 一个intent-filter中可以不声明Data属性,也可以声明多个Data属性;
  2. 如果intent-filter中未声明URI和MIME类型,则只有不含URI和MIME类型的隐形Intent才能匹配成功;
  3. 如果intent-filter中声明URI但是未声明MIME类型(也不能从URI中分析出MIME类型),则只有URI与intent-filter中URI相同且不包含MIME类型的隐式Intent才能匹配成功;
  4. 如果intent-filter中声明MIME类型但是未声明URI,只有包含相同MIME类型但是不包含URI的隐式Intent才能匹配成功;
  5. 如果intent-filter中声明了URI和MIME类型(既可以是直接设置,也可以是从URI分析出来),只有包含相同的URI和MIME类型的隐式Intent才能匹配成功。

------------------了解完Intent基础知识之后回来解决问题------------------

  • apk不显示应用程序图标问题

通常Intent隐式调用会在Andriodmanifest.xml中的MainActivity中默认生成

  • 一个常量为MAIN的Action属性:将MainActivity设置为该程序的入口Activity;
  • 一个常量为LAUNCHER的Category属性:将MainActivity列入系统的启动器,允许用户启动,会生成应用图标;
<activity android:name=".MainActivity">
     <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
</activity>

如果没有Category属性或Category属性为默认DEFAULT时,运行出来的apk是可以成功安装到设备上的,但是不会生成应用图标,也不会自动拉起运行,效果如下;

01/06 09:27:10: Launching 'app' on HIKVISION DS-KD94x3.
Install successfully finished in 8 s 154 ms.
Could not identify launch activity: Default Activity not found
Error while Launching activity

此时如果想运行该apk只能通过adb命令来启动;

adb shell am start -n com.example.test/.MainActivity

而客户的问题是这样的:

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />

        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
        <action android:name="android.nfc.action.TAG_DISCOVERED"/>
                
        <category android:name="android.intent.category.HOME" />
        <category android:name="android.intent.category.DEFAULT" />
                
        <data android:mimeType="*/*"/>
    </intent-filter>
</activity>

中包含多个Action属性和多个Category属性,且Category属性中LAUNCHER和DEFAULT同时存在,在了解Intent之前我猜测应用图标不显示会不会是因为最后一个DEFAULT把前面的LAUNCHER值覆盖了,但是了解之后发现Category属性允许存在多个值,于是就转换思路去找解决办法;

原因:Activity中的intent-filter中设置了不同的Action和Data,会通过两种方式启动,所以不能放在一起;

解决办法就是把Data属性单拎出来写在一个中:

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />

        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
        <action android:name="android.nfc.action.TAG_DISCOVERED"/>
                
        <category android:name="android.intent.category.HOME" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter> 
     
    <intent-filter>  
        <data android:mimeType="*/*"/>
    </intent-filter>
</activity>

再次安装apk就会自动运行,并且系统中也会显示应用图标了。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题

图片

  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值