gpt4 book ai didi

java - 从 InstrumentationTestCase 创建通知

转载 作者:搜寻专家 更新时间:2023-10-30 21:34:23 26 4
gpt4 key购买 nike

我想通过单元测试来测试通知是否能够播放 Assets 中的自定义声音。该测试并不意味着要验证任何内容,我将其编写为一种快速演示功能的方法,同时又不会弄乱主应用程序代码。

所以在测试项目中,我在/res/raw里面添加了一个wav文件。我将在通知生成器中使用此 URL:

Uri path = Uri.parse("android.resource://<main app package name>/testsound.wav");

根据我在 SO 中阅读的问题,该 URL 应该有效。让我们假设它有效。

现在因为我不想在主项目的 /res/raw 文件夹中包含测试 wav 文件,但是在测试项目一中,我不得不让我的单元测试从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 文件夹中,但这会隐藏文件,如果其他程序员将来需要替换它,他们可能很难找到它。

最佳答案

其实,我一直对这个问题有点疑惑。所以我写了一个小的 Instrumentation 测试。

为了断言,我将测试标记为仅在 API 23 上运行(getActiveNotifications 之前似乎不可用),但它在旧 API 上也能正常工作。

诀窍是使用 getTargetContext() 而不是 getContext():

public final class MainActivityTest extends ActivityUnitTestCase<MainActivity> {

public MainActivityTest() {
super(MainActivity.class);
}

@TargetApi(Build.VERSION_CODES.M)
public void testSendNotification() {
final NotificationManager manager = (NotificationManager) getInstrumentation().getTargetContext().getSystemService(Context.NOTIFICATION_SERVICE);

manager.cancel(42);
assertEquals(0, manager.getActiveNotifications().length);

final NotificationCompat.Builder builder = new NotificationCompat.Builder(getInstrumentation().getTargetContext());
builder.setContentTitle("Notification test")
.setAutoCancel(true)
.setContentText("Hello, Mister Smith")
.setSmallIcon(R.drawable.ic_launcher_notification);

manager.notify(42, builder.build());

assertEquals(1, manager.getActiveNotifications().length);
}
}

它就像一个魅力:

enter image description here

希望对您有所帮助。

关于java - 从 InstrumentationTestCase 创建通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34221081/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com