我希望能够从单元测试中测试通知是否能够播放来自资产的自定义声音。
该测试并不旨在验证任何内容,我编写它只是为了快速展示一个功能而不会使主应用程序代码混乱。
因此,在测试项目中,我在/res/raw
中添加了一个wav文件。 我将使用此URL与通知构建器:
Uri path = Uri.parse("android.resource://<main app package name>/testsound.wav");
根据我在SO上读到的问题,那个URL应该是有效的。假设它有效。
现在由于我不想将测试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,并将其放入测试项目的lib文件夹中,但这将隐藏该文件,其他程序员在未来需要替换该文件时可能会很难找到它。