如何在Activity中获取调用者 -- getReferrer()
如何在Activity中获取调用者 – getReferrer()
前言
为什么要在Activity中获取调用者?
主要是安全和定制两个方面的需求吧。
安全需求:
一般Activity如果已经对外开放了(即exported为true,或者加了Intent-filter),那么对Activity的保护就会降低,形成Activity攻击面,引入了风险。如果只对某几个app开放其Activity,则可以获取调用者的信息,并进行控制。定制需求:
如果被启动的Activity想对特定的调用者进行定制操作,则需要知道调用者是谁。
在Activity中获取调用者的方法
注:先列出所有可能的方法,后面会给出哪些方法可行。
Binder.getCallingUid()
和Binder.getCallingPid()
,然后根据uid,pid查找到包名Activity的
getCallingPackage()
和getCallingActivity()
Activity的
getReferrer()
【注意:Android 5.1(Api level 22)中才引入的】反射的方式获取Activity的
mReferrer: reflectGetReferrer()
【注:自定义函数,目的是获取到android.app.Activity
类的mReferrer
的值,也需要Api level 22(含)之后才能使用】
这里先给出结论:
方法1:不能在调用者
startActivity()
的时候获取到调用者的包名,只能用于Activity用到的Binder同步调用的地方。方法2: 在特定情况下可以使用
getCallingPackage()
和getCallingActivity()
,即如果Activity是通过startActivityForResult
启动的,则可以使用。方法3: Activity的
getReferrer()
是不可靠的,因为调用者可以自己设置referrer的值。方法4:是对方法3的改进,消除
getReferrer()
可能返回的不可靠的值,直接获取可靠的mReferrer
值(目前来看是可靠的)。
关于mReferrer的细节
Activity的getReferrer()
需要注意的是,此方法是在Android 5.1 (Api level 22)中引入的,Android 5.1之前是不能使用的。
Intent.java
public static final String EXTRA_REFERRER= "android.intent.extra.REFERRER";public static final String EXTRA_REFERRER_NAME= "android.intent.extra.REFERRER_NAME";
Activity.java
public Uri getReferrer() {Intent intent = getIntent();// 优先从Intent的Intent.EXTRA_REFERRER数据获取Uri,作为referrerUri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER);if (referrer != null) {return referrer;}// 如果之前没有获取到,则从intent的Intent.EXTRA_REFERRER_NAME数据获取,并转换成UriString referrerName = intent.getStringExtra(Intent.EXTRA_REFERRER_NAME);if (referrerName != null) {return Uri.parse(referrerName);}// 如果上面都没有获取到,则将mReferrer转换成android-app://的形式if (mReferrer != null) {return new Uri.Builder().scheme("android-app").authority(mReferrer).build();}return null;// 都没获取到的话,返回null}
反射的方式获取Activity的mReferrer
需要注意的是,此方法是基于getReferrer()(mReferrer)的,所以也必须在Android 5.1 (Api level 22)及 5.1 之后才能用。
自定义方法:
private String reflectGetReferrer() {try {Class activityClass = Class.forName("android.app.Activity");Field refererField = activityClass.getDeclaredField("mReferrer");refererField.setAccessible(true);String referrer = (String) refererField.get(MainActivity.this);return referrer;} catch (ClassNotFoundException | IllegalAccessException | NoSuchFieldException e) {e.printStackTrace();return "No referrer";}}
总结
通过反射的方式
reflectGetReferrer(
)获取到的mReferrer
,是调用者的包名,目前来看是可靠的,但是需要在Android5.1(Api level 22)以及之后才能用。getCallingPackage()
和getCallingActivity()
只有在startActivityForResult()
的时候才可以得到调用者的包名。Activity的getReferrer()
是不可靠的,因为调用者可以自己设置referrer
的值。所以不能依赖此值来判断调用者。Binder.getCallingUid()
和Binder.getCallingPid()
一般用在同步调用中,在这几个情况中并不适用。
如何在Activity中获取调用者 -- getReferrer()相关推荐
- 关于Activity的getReferrer():如何在Activity中获取调用者?
http://blog.csdn.net/u013553529/article/details/53856800 关于Activity的getReferrer()之一:如何在Activity中获取调用 ...
- java+script+当前日期_如何在JavaScript中获取当前日期?
如何在JavaScript中获取当前日期? #1楼 您可以使用扩展了 Date对象的Date.js库,从而可以使用.today()方法. #2楼 如果您想对日期格式进行更多的粒度控制,我强烈建议您查看 ...
- 如何在PHP中获取客户端IP地址[重复]
本文翻译自:How to get the client IP address in PHP [duplicate] This question already has an answer here: ...
- 如何在JavaScript中获取时间戳
如何在JavaScript中获取时间戳 +运算符 我们可以使用+运算符将日期对象直接转换为UNIX时间戳. 例如,我们可以这样写: +new Date() +日期对象之前操作者触发valueOf的方法 ...
- 【Android】12.3 在当前Activity中获取另一个Activity的返回值
分类:C#.Android.VS2015: 创建日期:2016-02-23 一.简介 在上一节的示例中,通过StartActivity(Intent)方法启动另一个Activity后,这两个Activ ...
- java如何实取随机数_java - 如何在Kotlin中获取随机数?
java - 如何在Kotlin中获取随机数? 可以在2个参数之间返回随机整数的通用方法,如ruby,可以使用rand(0..n). 有什么建议吗? 16个解决方案 208 votes 我的建议是In ...
- php mysql 到表最后_如何在PHP中获取MySQL表的最后插入ID?
如何在PHP中获取MySQL表的最后插入ID? 我有一张表,经常插入新数据. 我需要获取表格的最后一个ID. 我怎样才能做到这一点? 它类似于SELECT MAX(id) FROM table吗? g ...
- 如何在JavaScript中获取字符串数组的字符串?
本文翻译自:How do you get a string to a character array in JavaScript? How do you get a string to a chara ...
- java文件中获取创建日期_如何在Java中获取文件的上次修改日期
java文件中获取创建日期 Sometimes we need to get the file last modified date in Java, usually for listeners li ...
最新文章
- KubeSphere安装Mysql5.7
- linux删除文件后,空间未释放的一种情况,使用lsof查看
- 一个Java工程师的入门级Linux命令集
- 大学期末考试SSH试题四
- SAP UI5 应用开发教程之三十五 - 如何把本地开发的 SAP UI5 应用部署到 ABAP 服务器上
- python 反复访问迭代器iter,反复使用next
- int默认值为0,Integer默认值为null
- linux搭建python运行环境_centos运行.py centos5.5下搭建python开发运行环境 - Linux - 服务器之家...
- spark的python开发安装方式,最简单的方式来安装Python依赖关系的Spark执行器节点?...
- 自动更新统计信息的阀值——人为更新统计信息的重要性
- Centos7安装32位库用来安装32位软件程序
- 学习使用DCMTK工具
- Cameralink光端机
- Docker 容器的随机命名
- c#(WinForm)绘制两个圆的内公切线
- 计算机毕设项目 python微信公众平台机器人
- ES6最通俗易懂的超重点保姆级笔记!女朋友看了都流泪的学习秘籍!没有一句废话,全部都是满满干货!
- Ardunio测试817光电耦合交流电过零检测模块
- 结构体与动态内存(5.11)
- 细分市场或成为OA产品同质化的救星|企服三会系列报道
热门文章
- 蚌埠经贸学校98计算机一班,蚌埠的科技贸易学校
- 【已解决】Html Webpack Plugin Error;html-withimg-loader无法正常解析html内的img
- 大剧透-逐浪字库设计师展现卓越书法功底
- 跑马灯效果影响EditText的焦点
- 真·富文本编辑器的演进之路
- 中小学教师计算机应用能力提升,【四川省中小学教师信息技术应用能力提升工程2.0】_四川省中小学教师信息技术应用能力提升工程_四川省中小学教师信息技术应用能力提升工程...
- 绞车拆装实训报告_机电一体化实习报告
- 【Python 教程】list 列表遍历的 4 种方法
- 怎么python编程excel_Excel 如何在excel中运行Python代码?-ExcelVBA程序开发-ExcelHome技术论坛 -...
- 微信小程序 各类效果(视频)