Android 如何获取 Intent 的发送者?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3304304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:36:25  来源:igfitidea点击:

How to get the sender of an Intent?

android

提问by zer0stimulus

Is there a way for an Activityto find out who (i.e. class name) has sent an Intent? I'm looking for a generic way for my Activityto respond to a received intent by sending one back to the sender, whoever that may be.

有没有办法Activity找出谁(即班级名称)发送了Intent?我正在寻找一种通用的方式Activity来响应收到的意图,方法是将一个意图发送回发件人,无论是谁。

采纳答案by Andy Zhang

There may be another way, but the only solution I know of is having Activity A invoke Activity B via startActivityForResult(). Then Activity B can use getCallingActivity()to retrieve Activity A's identity.

可能还有另一种方式,但我所知道的唯一解决方案是让活动 A 通过startActivityForResult(). 然后 Activity B 可以getCallingActivity()用来检索 Activity A 的身份。

回答by donfuxx

Is it an external app you receive the intent from? You could use the getReferrer()method of the activity class

它是您从中接收意图的外部应用程序吗?您可以使用getReferrer()活动类的方法

A simple example: I opened google map app to share some location with my app by using the share option of google maps. Then my app opens and this method call in the Activity:

一个简单的例子:我打开谷歌地图应用程序,通过使用谷歌地图的共享选项与我的应用程序共享一些位置。然后我的应用程序打开并在 Activity 中调用此方法:

 this.getReferrer().getHost()

will return:

将返回:

 com.google.android.apps.maps

see documentation here: https://developer.android.com/reference/android/app/Activity.html#getReferrer()

请参阅此处的文档:https: //developer.android.com/reference/android/app/Activity.html#getReferrer()

Note that this requires API 22. For older Android versions see answer from ajwillliams

请注意,这需要 API 22。对于较旧的 Android 版本,请参阅 ajwillliams 的答案

回答by Mauricio Andrada

A technique I use is to require the application sending the relevant Intent to add a PendingIntent as a Parcelable extra; the PendingIntent can be of any type (service, broadcast, etc.). The only thing my service does is call PendingIntent.getCreatorUid() and getCreatorPackage(); this information is populated when the PendingIntent is created and cannot be forged by the app so I can get the info about an Intent's sender. Only caveat is that solution only works from Jellybean and later which is my case. Hope this helps,

我使用的一种技术是要求应用程序发送相关的 Intent 以添加 PendingIntent 作为 Parcelable extra;PendingIntent 可以是任何类型(服务、广播等)。我的服务所做的唯一一件事就是调用 PendingIntent.getCreatorUid() 和 getCreatorPackage(); 此信息在创建 PendingIntent 时填充,应用无法伪造,因此我可以获得有关 Intent 发件人的信息。唯一需要注意的是,该解决方案仅适用于 Jellybean,后来就是我的情况。希望这可以帮助,

回答by ajwillliams

This isn't incredibly direct but you can get a list of the recent tasks from ActivityManager. So the caller would essentially be the task before yours and you can fetch info on that task.

这不是非常直接,但您可以从 ActivityManager 获取最近任务的列表。所以调用者本质上是你之前的任务,你可以获取有关该任务的信息。

Example usage:

用法示例:

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(10000,ActivityManager.RECENT_WITH_EXCLUDED);

The above will return a list of all the tasks from most recent (yours) to the limit specified. See docs herefor the type of info you can get from a RecentTaskInfo object.

以上将返回从最近(您的)到指定限制的所有任务的列表。请参阅此处的文档,了解您可以从 RecentTaskInfo 对象获取的信息类型。

回答by adamp

Generally you don't need to know this. If the calling activity uses startActivityForResult(Intent, int), the callee can use setResult(int, Intent)to specify an Intent to send back to the caller. The caller will receive this Intent in its onActivityResult(int, int, Intent)method.

通常你不需要知道这些。如果调用 Activity 使用startActivityForResult(Intent, int),则被调用者可以使用setResult(int, Intent)指定一个 Intent 发送回调用者。调用者将在其onActivityResult(int, int, Intent)方法中接收此 Intent 。

回答by Ali Kazi

Based on your question, since you want to send an intent backto the sender startActivityForResult is a better choice than what I am going to suggest. But I needed to start activity B when a notification is clicked by the user and execute some code in activity B only ifthe sender activity is activity A. This is how I did it quite simply.

根据您的问题,由于您想将意图发送发件人 startActivityForResult 是比我要建议的更好的选择。但是我需要在用户单击通知时启动活动 B,并且仅当发件人活动是活动 A时才在活动 B 中执行一些代码。这就是我非常简单的做法。

Inside Activity A:

内部活动A:

String senderName = this.getClass().getSimpleName();        
Intent clickIntent = new Intent(ActivityA.this, ActivityB.class);
clickIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
clickIntent.putExtra("SENDER_CLASS_NAME", senderName);

//I use PendingIntent to start Activity B but you can use what you like such as this.startActivity(clickIntent);
PendingIntent.getActivity(ActivityA.this, NOTIFICATION_ID, clickIntent, PendingIntent.FLAG_ONE_SHOT);

Inside Activity B:

内部活动B:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState == null) {
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            if(bundle.containsKey("SENDER_CLASS_NAME")){
                String senderName = bundle.getString("SENDER_CLASS_NAME");                  
                //Execute some code
                Log.d("GCM", "Notifications clicked");
                }
            }
        }
    }

回答by ZhouX

In my case, neither the accepted here and another most voted answer works perfectly.

就我而言,这里接受的答案和另一个投票最多的答案都不完美。

Activity.getCallerActivity()works only for the sender which starts your activity by startActivityForResult, meaning that if the sender is also in your app and you have full control, it works, but not every external app starts others in that way.

Activity.getCallerActivity()仅适用于通过startActivityForResult启动您的活动的发件人,这意味着如果发件人也在您的应用程序中并且您拥有完全控制权,则它可以工作,但并非每个外部应用程序都以这种方式启动其他应用程序。

Another most voted answer provides the solution for external app, but it too has issue. First I would prefer getAuthority()instead of getHost(), secondly, if the sender is a browser kind of app, like Chrome, both host and authority will give you the browsing web page's address host, such as www.google.com, instead of the app itself. So it depends on how you define 'sender', if you need to find out which web page starts you, the authority/host is good enough, but if you need to find out which app starts you, I am afraid authority/host can be trusted only when getScheme()gives you android-appinstead of http.

另一个投票最多的答案为外部应用程序提供了解决方案,但它也有问题。首先,我更喜欢getAuthority()而不是getHost(),其次,如果发件人是浏览器类型的应用程序,例如Chrome,主机和权限都会为您提供浏览网页的地址主机,例如www.google.com,而不是应用程序本身。所以要看你怎么定义'sender',如果你要查出是哪个网页启动你,权限/主机就够了,但是如果你需要查出是哪个应用启动你,恐怕权限/主机就可以了仅当getScheme()为您提供android-app而不是http时才被信任。