如何获得意图的发送者?

时间:2010-07-21 22:10:14

标签: android

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

7 个答案:

答案 0 :(得分:30)

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

答案 1 :(得分:13)

是否是您收到意图的外部应用程序?您可以使用活动类的getReferrer()方法

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

 this.getReferrer().getHost()

将返回:

 com.google.android.apps.maps

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

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

答案 2 :(得分:8)

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

使用示例:

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

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

答案 3 :(得分:8)

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

答案 4 :(得分:6)

一般来说,你不需要知道这一点。如果调用活动使用startActivityForResult(Intent, int),则被调用方可以使用setResult(int, Intent)指定要发送回调用方的Intent。调用者将使用onActivityResult(int, int, Intent)方法接收此Intent。

答案 5 :(得分:1)

根据您的问题,由于您希望向发送方发送意图返回,因此startActivityForResult是比我建议的更好的选择。但是,当用户点击通知并且仅在发件人活动是活动A时执行活动B 中的某些代码时,我需要启动活动B.这就是我非常简单地完成它的方式。

内部活动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);

内部活动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");
                }
            }
        }
    }

答案 6 :(得分:0)

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

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

另一个投票最多的答案为外部应用程序提供了解决方案,但是它也存在问题。首先,我希望使用 getAuthority() ,而不是 getHost() ,其次,如果发送者是浏览器类型的应用程序(例如 Chrome ),主机和权限都将为您提供浏览网页的地址托管服务器(例如 www.google.com ),而不是应用程序本身。因此,这取决于您如何定义“发送者”,如果您需要确定哪个网页启动您,那么权限/主机就足够了,但是如果您需要找出哪个应用程序启动了,恐怕权限/主机可以仅当 getScheme() 给您 android-app 而不是 http < / em>