11

Я хочу проверить из единичного теста, может ли уведомление воспроизводить пользовательский звук из активов. Тест не предназначен для проверки чего-либо, я написал его как быстрый способ продемонстрировать функцию без загромождения основного кода приложения.Создание уведомления от InstrumentationTestCase

Так что в тестовом проекте я добавил wav-файл внутри /res/raw. Я буду использовать этот 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 и сбросить банку в папке lib тестового проекта, но это будет скрывать файл, и другим программистам может быть трудно найти его, если им нужно будет заменить его в будущем.

ответ

0

Я понял, как сделать звук работать с AndroidTestCase. WAV-файл был добавлен в исходную папку тестового проекта и не был включен в основной проект, как предполагалось.

URL-адрес для уведомления было так:

Uri path = Uri.parse("android.resource://<test project package name>/" + R.raw.air_horn); 

И строитель был получен следующим образом:

NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext()); 
2

На самом деле, я был немного озадачен вопросом. Поэтому я написал небольшой контрольно-измерительный тест.

Ради утверждения, я отметил, что тест для запуска только по 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

Надежда, это помогает.

+0

Да, это работает. Файл wav воспроизводится так, как ожидалось. Единственный недостаток заключается в том, что вам нужна деятельность из вашего основного проекта. –

+0

@MisterSmith, но вы спрашивали о ** контрольном испытании **, а не модульном тесте. Ваш ответ не отражает вопрос, который вы задаете. –

+0

Да, извините. Я предполагал, что для доступа к ресурсу в тестовом проекте мне пришлось использовать инструменты, как описано в [этом вопросе] (http://stackoverflow.com/questions/9249751/accessing-resources-in-an-android- тест-проект)). Но оказалось, что это работает из регулярного модульного теста. Спасибо, в любом случае. –

Смежные вопросы