什么是Android PendingIntent?


Answers:


891

A PendingIntent是您提供给外部应用程序(例如NotificationManagerAlarmManager主屏幕AppWidgetManager或其他第三方应用程序)的令牌,它允许外部应用程序使用您的应用程序的权限来执行预定义的代码段

如果您将外部应用程序指定为Intent,它将Intent使用自己的权限执行您的请求。但是,如果您给外部应用程序一个PendingIntent,则该应用程序将在您Intent的应用程序许可下执行您的操作。


3
除了通知外,您还在其他地方看到使用未决的意图?我想我只看到通知使用它...
android开发人员

4
@Johnny_D:这意味着它的意思,通常来说,您将要创建一个显式的Intent,其组件名称是一个绝对名称,该名称明确地引用了您自己的一个类。否则,该Intent可能会发送到另一个应用程序,这可能会导致问题,因为该Intent将在您的应用程序的许可下运行。
Lie Ryan

3
@LieRyan,这是我们在清单中指定的权限吗?例如。INTERNET权限?
2014年

2
这种“权限移交”在安全方面真的不好吗?我有一个具有多个权限的应用程序A。然后,我有了应用程序B,它使用的权限要少得多。如果应用程序A可以通过PendingIntent启动应用程序B中的某些操作(允许A的所有权限临时存在于B上),那么B不能在拥有该权限的情况下尽其所能吗?例如,A可能有权读取用户的联系人,而B则没有权限。如果A向B发送了PendingIntent,则B可以读取联系人并进行恶意操作(例如将其发送到服务器)。
Tiago 2014年

6
@Tiago:在您的情况下,如果特权应用程序A赋予应用程序B一个暂挂的意图,以便B可以在它想要读取联系人数据时将其发送。A负责询问用户要向B提供哪些联系数据,而仅向B提供该数据。Pending Intent是一种特权升级机制,就像任何特权升级机制一样,强大的功能带来了巨大的责任。用户有责任确定应用程序B对于用户选择的联系数据是否值得信任。
Lie Ryan

49

待定意向是您为某个应用程序提供的令牌,以代表您的应用程序执行操作,不管您的应用程序进程是否有效。

我认为文档足够详细: Pending Intent docs

只需考虑待定意图的用例,例如(广播意图,安排警报),文档将变得更加清晰和有意义。


我认为Intent也是一种令牌,我们将其给予其他一些应用以代表我们的应用执行操作。那么,待定意图和意图之间的唯一区别是我们的应用程序流程寿命?
CopsOnRoad

40

就我而言,上述答案和google的官方文档都没有帮助我掌握PendingIntent类的概念。

然后我发现了这段视频,即Google I / O 2013,超越了蓝点会议。在这段视频中,前Google员工Jaikumar Ganesh解释了这PendingIntent是什么,而这正是我从宏观上看到的。

以下是以上视频的转录(从15:24开始)。

那么什么是待定的意图?

这是您的应用程序过程将给定位过程的一个令牌,当感兴趣的事件发生时,定位过程将使用它来唤醒您的应用程序。因此,这基本上意味着您的应用程序不必始终在后台运行。发生感兴趣的事情时,我们将唤醒您。这样可以节省大量电池。

这段代码(包含在会话的幻灯片中)使这一解释变得更加清晰。

PendingIntent mIntent = PendingIntent.getService(...);

mLocationClient.requestLocationUpdates(locationRequest, mIntent);

public void onHandleIntent(Intent intent) {   
    String action = intent.getAction();   
    if (ACTION_LOCATION.equals(action)) {       
        Location location = intent.getParcelableExtra(...)   
    }
}

同意,这很容易理解。但这并没有告诉我们有关PendingIntent授予其他应用程序的权限的任何信息。
CopsOnRoad '18

35

为什么需要PendingIntent?我在想

  1. 为什么接收应用程序本身无法创建Intent
  2. 为什么我们不能将简单Intent用于同一目的。

例如Intent bluetoothIntent= new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

如果我发送bluetoothIntent到另一个没有权限的android.permission.BLUETOOTH_ADMIN应用程序,则该接收应用程序无法使用启用蓝牙startActivity(bluetoothIntent)

使用克服了限制PendingIntent。使用PendingIntent接收应用程序,无需android.permission.BLUETOOTH_ADMIN启用蓝牙。来源


3
您的bluetoothIntent示例确实很有价值。谢谢
Nicks

1
@Kiran-如果接收到的应用程序可以打开蓝牙(使用Pending Intent),那么为什么该应用程序未在清单中包含此权限?就像我正在制作可以拨打电话的应用程序一样,但我没有包含CALL_PHONE权限,因为我希望其他应用程序向我发送挂起此通话的意图。这是你想说的吗?
CopsOnRoad

1
@CopsOnRoad PendingIntent的接收应用程序可以是常规应用程序,它接收任何请求并代表请求者执行请求。它的角色只是中间人,因此没有所有权限。这种中间人应用程序的一个示例是通知管理器,它可以在没有拥有权限的情况下从通知中启动任何预期的应用程序。
晓丰利

21

待定意图是一种意图,它将在将来的某个时刻开始。普通意图在传递给startActivity(Intent)或时立即开始StartService(Intent)


13

其他应用程序可以使用的未来意图。
这是创建一个的示例:

Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendIntent = PendingIntent.getActivity(context, 0, intent, 0);

8
拒绝投票,因为您并未真正解释“未来”或可被其他应用程序使用的意图的特殊之处
Vic 2014年

@ WhereDatApp.com,这是Antoine de SaintExupéry所说的,由LewisGalantière翻译的;)
Choletski '16

@Choletski谢谢,我不知道翻译👍
奥德Breiner

13

出租车类比

意图

意图通常用于启动服务。例如:

Intent intent = new Intent(CurrentClass.this, ServiceClass.class);
startService(intent);

这就像您叫出租车:

Myself = CurrentClass
Taxi Driver = ServiceClass

待定意向

您将需要使用以下内容:

Intent intent = new Intent(CurrentClass.this, ServiceClass.class);
PendingIntent pi = PendingIntent.getService(parameter, parameter, intent, parameter);
getDataFromThirdParty(parameter, parameter, pi, parameter);

现在,该第三方将代表您启动服务。现实生活中的比喻是都是出租车公司的Uber或Lyft。

您向Uber / Lyft发送了乘车请求。然后,他们将继续为您致电一位司机。

因此:

Uber/Lyft ------ ThirdParty which receives PendingIntent
Myself --------- Class calling PendingIntent
Taxi Driver ---- ServiceClass

11

PendingIntent是您提供给另一个应用程序(例如,通知管理器,警报管理器或其他第三方应用程序)的令牌,它允许该另一个应用程序使用您的应用程序的权限来执行预定义的代码。要通过挂起的意图执行广播,请通过PendingIntent.getBroadcast()获得PendingIntent。要通过挂起的意图执行活动,您可以通过PendingIntent.getActivity()接收活动。


7

什么是意图?

Intent是Android中的特定命令,可让您将命令发送到Android OS以执行特定的操作。将其视为需要执行的操作。可以执行许多操作,例如发送电子邮件,将照片附加到电子邮件,甚至启动应用程序。创建意图的逻辑工作流程通常如下:创建意图b。添加意图选项->例如 我们要发送给操作系统的意图类型或与该意图关联的任何属性,例如文本字符串或与意图一起传递的内容c。运行意图

现实生活中的例子:假设我早上醒来,然后“打算”去洗手间。我首先要考虑去洗手间,但那并没有真正让我去洗手间。然后,我将不得不先告诉我的大脑起床,然后走到洗手间,然后释放,然后去洗手,然后去洗手。一旦知道要去的地方,我就发送命令开始,然后我的身体采取行动。

什么是待定意图?

继续以现实生活为例,假设我想洗个澡,但在刷完牙并吃早餐后想洗个澡。因此,我知道我至少要等30至40分钟才能洗完澡。我脑子里仍然需要准备衣服,然后走上楼梯回到浴室,然后脱衣服再淋浴。但是,只有经过30-40分钟后,这种情况才会发生。我现在有待洗的意图。等待30-40分钟。

这几乎与“待定意图”和“常规意图”之间的区别。可以在没有待定意向的情况下创建常规意向,但是要创建待定意向,您首先需要进行常规意向设置。


我真的很喜欢这个简单的示例,我对这些单词非常了解。
Josema '16

我很高兴这篇文章对您有用。Josema
Narendra Motwani

这与Shakeeb Ayaz的上述解释完全相同。谁抄袭了谁?:)
likejudo

5

PendingIntent基本上是包装另一个Intent对象的对象。然后,可以将其传递给外部应用程序,在该外部应用程序中,您授予该应用程序执行操作的权限,即,执行该意图,就好像它是从您自己的应用程序的流程(相同的权限和身份)中执行的。出于安全原因,您应该始终将显式意图传递给PendingIntent,而不是隐式。

 PendingIntent aPendingIntent = PendingIntent.getService(Context, 0, aIntent,
                    PendingIntent.FLAG_CANCEL_CURRENT);

4

用一种简单的语言,
1.要执行的意图和目标动作的描述。首先,您必须创建一个Intent,然后必须将要执行的特定Java类传递给Intent。
2.您可以通过PendingIntent.getActivity,PendingIntent.getActivities(Context,int,Intent [],int),PendingIntent.getBroadcast(Context,int,Intent,int)和PendingIntent调用那些作为类动作类的java类。 getService(Context,int,Intent,int); 在这里,您可以看到来自步骤1的Intent
3的。您应该记住...通过将PendingIntent赋予另一个应用程序,您可以授予它执行指定操作的权限。

这是我长时间阅读后所学到的。


3

PendingIntent使用您赋予外部应用程序的令牌包装通用Intent,以在您的许可下执行。例如:

如果您未发出PendingIntent发送广播的消息,则音乐应用程序的通知将无法播放/暂停音乐,因为您的音乐应用程序具有READ_EXTERNAL_STORAGE通知应用程序未获得的许可。通知是一项系统服务(因此它是外部应用程序)。


很好的例子!
likejudo

2

顾名思义.. PendingIntent

您可以挂(一段时间后再做)。它是另一个目的。.它是将您的任务交给其他应用以代表您执行的一种方式。


1
你能举一个现实的例子吗?
CopsOnRoad

0

一个待定意图指定要采取的动作在未来。它使您可以将将来的Intent传递给另一个应用程序,并允许该应用程序执行该Intent,就像它具有与您的应用程序相同的权限一样,而在最终调用该Intent时您的应用程序是否仍然存在。

这是您提供给外部应用程序的令牌,该令牌允许外部应用程序使用应用程序的权限来执行预定义的代码段。

如果您为外部应用程序提供了一个Intent,并且该应用程序发送/广播了您提供的Intent,则他们将使用自己的权限执行该Intent。但是,如果您改为使用您自己的权限为外部应用程序创建一个待定意图,则该应用程序将使用您的应用程序的许可权执行所包含的意图。

要通过挂起的意图执行广播,请通过PendingIntent.getBroadcast()获得PendingIntent。要通过挂起的意图执行活动,您可以通过PendingIntent.getActivity()接收活动。

这是您要执行的Intent操作,但稍后要执行。认为这是将意图放在冰上。之所以需要它,是因为必须在应用程序中的有效上下文中创建并启动一个Intent,但是在某些情况下,由于您在技术上不在应用程序上下文中,因此您在运行该操作时不可用。两个常见的示例是从Notification或BroadcastReceiver启动Activity。

通过创建要用于启动(例如,活动)的PendingIntent(从另一个活动或服务内部),您可以将该对象传递给外部对象,以使其启动应用程序的一部分代表你。

PendingIntent提供了一种使应用程序工作的方法,即使它们退出了进程也是如此。重要的是要注意,即使在终止创建PendingIntent的应用程序之后,该Intent仍然可以运行。要执行的意图和目标动作的描述。此类的实例是使用getActivity(Context,int,Intent,int),getBroadcast(Context,int,Intent,int),getService(Context,int,Intent,int)创建的;返回的对象可以移交给其他应用程序,以便它们以后可以执行您代表您描述的操作。

通过将PendingIntent赋予另一个应用程序,您将授予它执行指定的操作的权限,就好像另一个应用程序是您自己一样(具有相同的权限和身份)。因此,您应该谨慎地构建PendingIntent:例如,通常,您提供的基本Intent会将组件名称显式设置为您自己的组件之一,以确保最终将其发送到那里。

PendingIntent本身只是对系统维护的令牌的引用,该令牌描述了用于检索令牌的原始数据。这意味着,即使其拥有的应用程序的进程被杀死,PendingIntent本身也将在已赋予它的其他进程中保持可用。如果创建的应用程序以后重新检索相同类型的PendingIntent(相同的操作,相同的Intent操作,数据,类别和组件以及相同的标志),它将收到一个表示相同令牌的PendingIntent(如果该令牌仍然有效),并且可以因此调用cancel()将其删除。


0

待定意图是一种意图,它向其他应用程序提供所有许可以执行特定工作。当主要活动被销毁时,Android OS将从中收回许可。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.