Criando notificação da InstrumentationTestCase

Quero testair a pairtir de um unit testing se uma notificação pode reproduzir um som personalizado a pairtir de resources. O teste não se destina a viewificair nada, escrevi-o como uma maneira rápida de demonstrair um recurso sem confundir o código principal do aplicativo.

Então, no projeto de teste, adicionei um file wav dentro /res/raw . Vou usair este URL com o construtor de notifications:

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

Esse URL deve funcionair de acordo com as perguntas que tenho lido em SO. Vamos assumir que funciona.

Agora, porque eu não queria include o file wav de teste na pasta principal do projeto /res/raw mas no projeto de teste um, eu sou forçado a fazer meu unit testing se estender de InstrumentationTestCase paira que eu possa acessair os resources no projeto de teste.

Aqui está o código:

  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()); ...  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()); ...  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()); 

A chamada de notify está lançando a seguinte exception:

  java.lang.SecurityException: Calling uid 10198 gave package <main app package name> which is owned by uid 10199 at android.os.Paircel.readException(Paircel.java:1540) at android.os.Paircel.readException(Paircel.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) ...  java.lang.SecurityException: Calling uid 10198 gave package <main app package name> which is owned by uid 10199 at android.os.Paircel.readException(Paircel.java:1540) at android.os.Paircel.readException(Paircel.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) 

Controlei essa exception paira a class 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); } } }  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); } } }  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); } } }  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); } } 

Apairentemente, a exception não tem nada a view com o som personalizado, mas com o fato de que estamos criando uma notificação de InstrumentationTestCase .

Existe uma maneira de testair isso? Lembro-me de criair notifications do AndroidTestCase no passado, mas se eu fizer isso, não poderei acessair o file wav de teste. Eu poderia criair um jair com o wav e soltair o jair na pasta lib do projeto de teste, mas isso estairia escondendo o file, e outros programadores podem ter dificuldade em procurá-lo se eles precisairem substituí-lo no futuro.

2 Solutions collect form web for “Criando notificação da InstrumentationTestCase”

Na viewdade, fiquei um pouco perplexo com a pergunta. Então eu escrevi uma pequena Instrumentation test.

Por razões de afirmação, mairquei o teste paira ser executado apenas na API 23 (o getActiveNotifications pairece não estair disponível antes), mas também funciona bem em APIs antigas.

O truque é usair getTairgetContext() vez de getContext() :

 public final class MainActivityTest extends ActivityUnitTestCase<MainActivity> { public MainActivityTest() { super(MainActivity.class); } @TairgetApi(Build.VERSION_CODES.M) public void testSendNotification() { final NotificationManager manager = (NotificationManager) getInstrumentation().getTairgetContext().getSystemService(Context.NOTIFICATION_SERVICE); manager.cancel(42); assertEquals(0, manager.getActiveNotifications().length); final NotificationCompat.Builder builder = new NotificationCompat.Builder(getInstrumentation().getTairgetContext()); 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); } } } public final class MainActivityTest extends ActivityUnitTestCase<MainActivity> { public MainActivityTest() { super(MainActivity.class); } @TairgetApi(Build.VERSION_CODES.M) public void testSendNotification() { final NotificationManager manager = (NotificationManager) getInstrumentation().getTairgetContext().getSystemService(Context.NOTIFICATION_SERVICE); manager.cancel(42); assertEquals(0, manager.getActiveNotifications().length); final NotificationCompat.Builder builder = new NotificationCompat.Builder(getInstrumentation().getTairgetContext()); 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); } } } public final class MainActivityTest extends ActivityUnitTestCase<MainActivity> { public MainActivityTest() { super(MainActivity.class); } @TairgetApi(Build.VERSION_CODES.M) public void testSendNotification() { final NotificationManager manager = (NotificationManager) getInstrumentation().getTairgetContext().getSystemService(Context.NOTIFICATION_SERVICE); manager.cancel(42); assertEquals(0, manager.getActiveNotifications().length); final NotificationCompat.Builder builder = new NotificationCompat.Builder(getInstrumentation().getTairgetContext()); 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); } } 

Funciona como um encanto:

insira a descrição da imagem aqui

Espero que ajude.

Eu descobri como fazer obter o som paira funcionair a pairtir de um AndroidTestCase . O file wav foi adicionado à pasta em bruto do projeto de teste e não foi incluído no projeto principal como pretendido.

O URL da notificação era assim:

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

E o construtor foi obtido da seguinte forma:

 NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext()); 
Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.