【发布时间】:2017-02-16 20:01:19
【问题描述】:
我正在尝试使用AlarmManager 来实现一些警报调度。因为当触发警报时,我想使用 WakefulBroadcastReceiver 启动 IntentService 来做一些后台工作。
我有一些与警报意图传递的参数的安全/隐私相关的问题。
-
为警报设置 PendingIntent 时,我会执行以下操作:
Intent myIntent = new Intent(context, MyReceiver.class); myIntent.putExtra("test", "testValue"); Bundle bundle = new Bundle(); bundle.putParcelable("bundleValue", bundleTestValue2); myIntent.putExtra("test3", bundle); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 323, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
我的问题是:对于警报的 pendingIntent,设置为 Extra 的值有多私密?是否有可能被其他应用程序读取,因为它们在预定后被 Android 警报管理器使用?
-
通过像这样的接收器
public class MyReceiver extends WakefulBroadcastReceiver {@Override public void onReceive(Context context, Intent intent) { startWakefulService(context, MyIntentService); }
在 android 清单上
<receiver
android:name=".receivers.MyReceiver"
android:exported="false"/>
<service
android:name=".MyIntentService"
android:exported="false"/>
还有服务
public class MyIntentService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
try {
//logic here
} catch{
} finaly{
MyReceiver.completeWakefulIntent(intent);
}
}
从我的 Activity 中调用
sendBroadcast(new Intent(context, MyReceiver.class).putExtra(...);
从警报中安排待处理意图
Intent myIntent = new Intent(context, MyReceiver.class);
myIntent.putExtra("test", "testValue");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 323,
myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
此接收器对其他应用的暴露程度如何?它可以对除我之外的其他应用程序做出反应吗?这会引发任何可能的安全问题吗?
谢谢。
后期编辑:
由于WakefullBroadcastReceiver 似乎是保证我的服务将获得部分唤醒锁的唯一方法,我怎样才能确保 100% 没有其他应用程序会知道我的接收器,并且我的接收器不会收到任何其他呼叫,除了那些来自我的活动或来自我的集合Alarm?
WakefullBroadcastReceiver 模式与 CommonsWare 的 WakefulIntentService 相比如何工作?
后期编辑: 我终于设法完成了我的实现。
如前所述,我的
WakefulBroadcastReceiver和IntentService在我的Android Manifest 中都声明为exported="false",据我了解,这意味着只有我的应用程序可以访问它们。由于receiver没有导出,是不是接收到app外的广播?-
设置闹钟时我使用这个
PendingIntent:Intent myIntent = new Intent(context, MyReceiver.class);
myIntent.putExtra("databaseId", "1"); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 323, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); 从我的 Activity 调用时,我会这样做:
sendBroadcast(new Intent(context, MyReceiver.class).putExtra("databaseId", "1"));
这就够了吗?
【问题讨论】:
-
WakefulBroadcastReceiver和WakefulIntentService使用BroadcastReceiver和IntentService的组合。关于您的顾虑,它们是相同的。 -
@CommonsWare 非常感谢您抽出宝贵的时间。关于
WakefullBroadcastReceiver的安全性,您有什么可以告诉我的吗?如何确保其intent不会被其他应用读取或其他应用通过向其发送广播与其交互? -
您已经对这个主题有一个冗长的答案。 Vasily 的开场白很好:“总的来说,我会说将敏感数据放入 Intent 是一种不安全的做法”。此外,您不需要将敏感数据放在
Intent中,Intent会路由回您自己的应用程序。使用一些对外人来说没有意义但能识别如何加载数据的标识符(例如,数据库表的主键)。 -
“但是我仍然担心其他应用程序是否能够向我的接收器广播” - 任何时候使用
PendingIntent,都不需要导出该组件,所以第三个-party 应用程序不应访问您的接收器。任何时候您使用自己的组件之一(例如,从接收方调用startService()),都不需要导出该组件。所以,你在这里不应该有问题。如果您使用明确的Intent调用sendBroadcast(),则广播只会发送到该接收者;使用隐式Intent,广播会发送到所有注册的侦听器。 -
“sendBroadcast 已声明意图”——我不清楚这意味着什么。显式的
Intent类似于new Intent(this, YourReceiver.class)。那只会转到YourReceiver。隐含的Intent类似于new Intent("your.custom.action.STRING")。这适用于任何选择收听此类广播的人。对于您的用例,不要在<receiver>上使用<intent-filter>,并为您的广播使用显式Intent。或者,不要使用sendBroadcast(),而是直接调用您的IntentService,以防警报未触发。
标签: android alarmmanager android-alarms android-broadcastreceiver