Android程序间跳转分析及重现
来源:互联网 发布:uefi ubuntu安装黑屏 编辑:程序博客网 时间:2024/05/16 16:17
Android应用程序之间有很多常用跳转,例如各种分享操作、选择本机图片作为头像的操作、利用第三方应用打开文件操作、发送邮件、从应用内跳转到应用市场评分操作等。
Intent中所有FLAG定义二进制值如下,可以看到ACTIVITY跟广播RECEIVER是有相同部分的:
那么这些跳转是怎么实现的呢?假如我要做一个应用实现上述的某种功能,我该怎么入手呢?要解决这些问题,我觉得不妨把这些跳转事件拦截下来分析分析。
通过Intent跳转到一个Activity可以分为两类:
显式Intent:直接指定包名和类名进行跳转,多用于在应用内部跳转或跳转到系统设置页面;
隐式Intent:通过IntentFilter 筛选出 action、category、data 类型全部符合要求的页面,假如合适页面不只一个,一般弹出窗口让用户选择。
程序间应用跳转大多采用隐式Intent,这也就是说我需要拦截和分析的也是隐式Intent跳转。
第一步:拦截Intent
在AndroidManifest.xml里面这样处理拦截页面,这里主要拦截常用跳转截:
<activity android:name="com.jersey.intentanalyser.MainActivity" android:label="@string/app_name" android:launchMode="singleTop" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <!-- 处理Intent 我们需要匹配action, category, 和对应的data所有mimeType类型 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SENDTO" /> <action android:name="android.intent.action.SEND_MULTIPLE" /> <action android:name="android.intent.action.GET_CONTENT" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.OPENABLE" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:mimeType="*/*" /> </intent-filter><pre name="code" class="html"> <!-- 处理Intent 我们需要匹配action, category, 和对应的data常用scheme类型 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SENDTO" /> <action android:name="android.intent.action.SEND_MULTIPLE" /> <action android:name="android.intent.action.GET_CONTENT" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.OPENABLE" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="" /> <data android:scheme="content" /> <data android:scheme="http" /> <data android:scheme="https" /> <data android:scheme="market" /> <data android:scheme="geo" /> <data android:scheme="file" /> </intent-filter> </activity>
第二步: 分析Intent
这里主要是对Intent内容的遍历:
/*** * 分析Intent,将结果输出至TextView * */private void handleIntent() {Intent intent = getIntent();TextView tv = (TextView) findViewById(R.id.textview);StringBuilder sb = new StringBuilder("<b>Intent:</b>");try {if (intent.getAction() != null)sb.append(getBolderTitleHtml("Action:") + intent.getAction());if (intent.getDataString() != null)sb.append(getBolderTitleHtml("DataString:")+ intent.getDataString());if (intent.getScheme() != null)sb.append(getBolderTitleHtml("Scheme:") + intent.getScheme());if (intent.getType() != null)sb.append(getBolderTitleHtml("Type:") + intent.getType());// Package和Component由于是用户选择以后添加的,不是最初的Intent内容,所以不再显示// if(intent.getPackage()!=null)sb.append("\n" + "Package:"// +intent.getPackage());// if(intent.getComponent()!=null)sb.append("\n" + "Component:"+// intent.getComponent());// 通过反射获取所有的FLAG名称,这里需要注意的是广播类型的FLAG是跟Activity有冲突的,需要屏蔽掉Class<?> intentClass = Class.forName("android.content.Intent");Field[] fileds = intentClass.getDeclaredFields();for (Field filed : fileds) {if (filed.getName().startsWith("FLAG_")&& (filed.getInt(intentClass) & intent.getFlags()) != 0&& (!filed.getName().startsWith("FLAG_RECEIVER_"))) {sb.append(getBolderTitleHtml("FLAG:") + filed.getName());}}if (intent.getCategories() != null)sb.append(getBolderTitleHtml("Categories:")+ intent.getCategories());if (intent.getData() != null)sb.append(getBolderTitleHtml("Data:") + intent.getData());if (intent.getClipData() != null)sb.append(getBolderTitleHtml("ClipData:")+ intent.getClipData());if (intent.getSourceBounds() != null)sb.append(getBolderTitleHtml("SourceBounds:")+ intent.getSourceBounds());// 遍历 BundleBundle bundle = intent.getExtras();if (bundle != null) {Set<String> set = bundle.keySet();if (set != null) {for (String ss : set) {sb.append(getBolderTitleHtml(ss + ":") + "\n"+ bundle.get(ss));}}}} catch (Exception e1) {e1.printStackTrace();}tv.setText(Html.fromHtml(sb.toString()));}/*** * 将属性名称转为html格式粗体 * * @param str */private String getBolderTitleHtml(String str) {return "<br/><b>" + str + "</b>";}
Intent中所有FLAG定义二进制值如下,可以看到ACTIVITY跟广播RECEIVER是有相同部分的:
第三步 :继续跳转
想要复原用户选择之前的Intent,只需要将Package和Component设为空就可以了:
intent.setComponent(null);intent.setPackage(null);startActivity(Intent.createChooser(intent, ""));
程序分析测试如下:
APK已上传360手机市场:
http://zhushou.360.cn/detail/index/soft_id/2777363
代码
http://download.csdn.net/detail/jerseyho/8587997
0 0
- Android程序间跳转分析及重现
- android 程序间跳转
- Android程序间的跳转问题
- Android程序间的跳转问题
- Android不同程序间的简单跳转
- Android程序OOM问题分析及解决
- 分析Android框架及Android程序的目录结构
- 程序间跳转
- 重现
- 跳转到Android的程序卸载界面
- Android 点击跳转时 ,程序显示异常
- Android实现程序之间的跳转
- Android 跳转到网页 地图 拨号程序
- android 程序完全退出,,通知跳转 逻辑
- android实现跳转到另一个app程序
- Android Activity之间跳转及跳转到其他app
- Android界面跳转的内存分析
- Android activity动画跳转案例分析
- leetcode习题代码(经常更新)
- HDU 1719--Friend【数学】
- CodeForces 523C. Name Quest 字符串
- File' Owner使用注意
- Android之ContentProvider
- Android程序间跳转分析及重现
- 关于大小端、位域的一些概念详解
- 通用线程:POSIX 线程详解
- 娃儿好玩儿
- [轉]win8.1卸載mysql
- 含表头的链表ADT(C语言版)
- 如何改变textview中的字体
- 大小端 位域
- 产品生命周期中的文档管理