Voglio testare da un'unità di test se una notifica è in grado di riprodurre un suono personalizzato dalle risorse. Il test non ha lo scopo di verificare nulla, l'ho scritto come un modo rapido per dimostrare una funzionalità senza ingombrare il codice dell'app principale.Creazione di notifiche da InstrumentationTestCase
Quindi nel progetto di test, ho aggiunto un file wav all'interno di /res/raw
. Userò questo URL con il costruttore di notifica:
Uri path = Uri.parse("android.resource://<main app package name>/testsound.wav");
Questo URL dovrebbe funzionare in base alle domande che ho letto in SO. Supponiamo che funzioni.
Ora perché non ho voglia di includere il file di test wav nella cartella del progetto principale /res/raw
ma nel progetto di test, io sono costretto a fare il mio test di unità si estendono dalla InstrumentationTestCase
modo che io possa accedere alle risorse in il progetto di test.
Ecco il codice:
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());
La chiamata notify
sta gettando la seguente eccezione:
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)
ho rintracciato questa eccezione fino alla classe di 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);
}
}
Apparentemente l'eccezione non ha nulla a che fare con l'abitudine suono, ma con il fatto che stiamo creando una notifica da un InstrumentationTestCase
.
C'è un modo per testarlo? Ricordo di aver creato notifiche da AndroidTestCase
in passato, ma se lo faccio, non sarò in grado di accedere al file di test wav. Potrei creare un jar con il wav e rilasciare il jar nella cartella lib del progetto di test, ma questo potrebbe nascondere il file, e altri programmatori potrebbero avere difficoltà a cercarlo se hanno bisogno di sostituirlo in futuro.
Sì, questo funziona. Il file wav viene riprodotto come previsto. L'unico inconveniente è che hai bisogno di un'attività dal tuo progetto principale. –
@MisterSmith ma hai chiesto informazioni su ** Instrumentation test **, non su unit test. La tua risposta non riflette la domanda che chiedi. –
Sì, mi dispiace per quello. Supponevo che per accedere a una risorsa nel progetto di test dovessi usare la strumentazione, come descritto in [questa domanda] (http://stackoverflow.com/questions/9249751/accessing-resources-in-an-android- test-project)). Ma si è scoperto che funziona con un normale test unitario. Grazie comunque. –