【发布时间】:2016-03-17 05:18:41
【问题描述】:
我想通过单元测试来测试通知是否能够从资产中播放自定义声音。 该测试并不是为了验证任何东西,我编写它是为了快速演示一项功能,而不会弄乱主应用程序代码。
所以在测试项目中,我在/res/raw里面添加了一个wav文件。我将在通知生成器中使用此 URL:
Uri path = Uri.parse("android.resource://<main app package name>/testsound.wav");
该 URL 应该根据我在 SO 中阅读的问题起作用。让我们假设它有效。
现在因为我不想将测试 wav 文件包含在主项目的 /res/raw 文件夹中,但在测试项目之一中,我不得不让我的单元测试从 InstrumentationTestCase 扩展,以便我可以访问测试项目中的资源。
代码如下:
NotificationCompat.Builder builder = new NotificationCompat.Builder(getInstrumentation().getContext());
...
builder.setSound(path, AudioManager.STREAM_NOTIFICATION);
...
NotificationManager notificationManager = (NotificationManager) getInstrumentation().getContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
notify 调用引发以下异常:
java.lang.SecurityException: Calling uid 10198 gave package <main app package name> which is owned by uid 10199
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:611)
at android.app.NotificationManager.notify(NotificationManager.java:187)
at android.app.NotificationManager.notify(NotificationManager.java:140)
...
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1873)
我已将此异常跟踪到 NotificationManagerService 类:
void checkCallerIsSystemOrSameApp(String pkg) {
int uid = Binder.getCallingUid();
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {
return;
}
try {
ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
pkg, 0, UserHandle.getCallingUserId());
if (!UserHandle.isSameApp(ai.uid, uid)) {
throw new SecurityException("Calling uid " + uid + " gave package"
+ pkg + " which is owned by uid " + ai.uid);
}
} catch (RemoteException re) {
throw new SecurityException("Unknown package " + pkg + "\n" + re);
}
}
显然,该异常与自定义声音没有任何关系,而是因为我们正在从 InstrumentationTestCase 创建通知。
有没有办法测试这个?我记得过去从AndroidTestCase 创建了通知,但如果我这样做了,我将无法访问测试 wav 文件。我可以用 wav 创建一个 jar 并将 jar 放到测试项目的 lib 文件夹中,但这会隐藏文件,如果将来需要替换它,其他程序员可能很难找到它。
【问题讨论】:
标签: java android unit-testing notifications android-instrumentation