进程间通信时是不是可以获取活动调用者应用程序的包名?

Posted

技术标签:

【中文标题】进程间通信时是不是可以获取活动调用者应用程序的包名?【英文标题】:Is it possible to get the package name of Activities' caller app when Interprocess Communication?进程间通信时是否可以获取活动调用者应用程序的包名? 【发布时间】:2016-03-21 06:24:28 【问题描述】:

我有一个Activity A,可以在我的应用程序中被Application1Application2 调用。

Manifest文件中AcitivityA的配置如下:

<activity
   android :name=".activity.ActivityA"
   android :exported="true"
   android :screenOrientation="portrait"/>

Application1Application2如何调用ActivityA

PackageManager packageManager = getPackageManager();
Intent intent = new Intent();
intent.setClassName(“com.abc.test", “com.abc.test.activity.ActivityA" );
List activities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (activities.size() > 0 ) 
   startActivity(intent);

为了安全,我想在ActivityA中添加一个包含Application1Application2的包名的白名单,只有ActivityA's调用者的包名在白名单中才能打开。

那么是否可以在ActivityA中获取Activities'调用者应用的包名?

已编辑:

如果没有 Intent 中的额外数据是不可能的,还有什么其他想法可以保证 Activity A 的安全吗?

【问题讨论】:

【参考方案1】:

尝试Activity 的getCallingPackage() 和getCallingActivity() 方法。

【讨论】:

直接来自文档:Note: if the calling activity is not expecting a result (that is it did not use the startActivityForResult(Intent, int) form that includes a request code), then the calling package will be null.【参考方案2】:

只要调用者没有额外提供关于自己的信息,答案是否定的。

如果您想确保只允许特定的呼叫者,请使用permissions。 见

http://developer.android.com/training/articles/security-tips.html http://developer.android.com/guide/topics/manifest/manifest-intro.html#sectperm http://developer.android.com/guide/topics/manifest/activity-element.html

如果您拥有所有调用者,那么我建议使用相同的密钥对所有这些进行签名并使用protectionLevel Signature 的权限。

另一种需要更多代码的方法是使用服务进行通信。

引用第一个链接:

使用 Binder 或 Messenger 是 Android 中 RPC 式 IPC 的首选机制。它们提供了一个定义明确的接口,可以在需要时对端点进行相互身份验证。

【讨论】:

我不拥有所有调用者,所以我不能使用 protectionLevel 签名的权限。如果我正常使用权限,其他应用可以修改其清单以使用相同的权限。 不,有点复杂。 您必须确定您的安全级别值得做多少工作。请注意,Android 上的任何应用程序都没有完美的安全性。使用权限通常就足够了。如果您必须共享高度敏感的数据,请使用服务。中间没有太多。 感谢您的回复,也许我会使用权限。【参考方案3】:

我所做的是通过意图传递调用活动。例如

public class MainActivity extends AppCompatActivity 
    private final static String THIS_ACTIVITY = "MainActivity";
.........

    Intent intent = new Intent(this, ShopAddActivity.class);
    intent.putExtra("Caller",THIS_ACTIVITY);
    startActivity(intent);

在另一个活动中(调用相同的子活动):-

public class ShopListByCursorActivity extends AppCompatActivity 

    private final static String THIS_ACTIVITY = "ShopListByCursorActivity";

.......

    Intent intent = new Intent(findViewById(R.id.aslbclv01).getContext(), ShopAddActivity.class);
    intent.putExtra("Caller", THIS_ACTIVITY + "Update");
    startActivity(intent);

然后在被调用的activity中(作为检测调用者的一个例子)

if(getIntent().getStringExtra("Caller").equals("ShopListByCursorActivityUpdate")) 

      DO STUFF HERE
        

【讨论】:

虽然不确定安全方面,所以这可能不够安全。但是,一个好处是,此方法可以满足将活动中的某个部分检测为调用者的要求。在上面的例子中。我将 Update 附加到 THIS_ACTIVITY 以表明调用者正在请求更新模式而不是添加模式。 安全性很低。我的意思是,一个未列入白名单的呼叫者只需要知道一个列入白名单的呼叫者姓名,它就可以轻松地假装是那个呼叫者。如果您想为不同的呼叫者做不同的事情,这很好。 附加值可能是某种安全码。 没有办法对这样的代码保密,除非您想在活动之间执行完整的类似 SSL 的握手。

以上是关于进程间通信时是不是可以获取活动调用者应用程序的包名?的主要内容,如果未能解决你的问题,请参考以下文章

获取接口调用者的包名

WPF怎么能跨进程通信

进程间通信 (IPC) 方法总结

Android 09 服务 使用服务进行本地进程通信

如何在android中获取Fragment的包名(不是Activity的)[重复]

POSIX 进程间同步