2016-04-26 19 views
1

Ich arbeite an einem benutzerdefinierten Android für meine Master-Arbeit, die auf CM12.1 basiert.Senden von BroadcastIntent in application.onCreate() führt zum Booten für immer

Der Anwendungsfall für die benutzerdefinierte ROM ist die Erfassung von Nutzungsdaten für beliebige Anwendungen, einschließlich z. Starten, Herunterfahren und Aufrufen von verschiedenen Systemressourcen. All dies sollte bei normaler Nutzung des Telefons passieren. Derzeit möchte ich die Application-Klasse verwenden, so dass sie eine Broadcast-Absicht in ihrer onCreate() -Methode sendet.

[...] 
class Application extends ContextWrapper implements ComponentCallbacks2 { 
[...] 
public void onCreate() { 
    // fire intent for capturing 
    Bundle bundle = new Bundle(); 
    if (mLoadedApk != null) { 
     bundle.putString("PACKAGE_NAME", mLoadedApk.getApplicationInfo().packageName); 
     bundle.putLong("CREATION_DATE", System.currentTimeMillis()); 
    } 
    Intent intent = new Intent(Intent.ACTION_START_APP) // custom action added to Intent.java 
     .putExtras(bundle); 
    getApplicationContext().sendBroadcastAsUser(intent, android.os.Process.myUserHandle()); 
} 
[...] 
} 

Auf diese Weise konnte ich die genauen Zeiten protokollieren, wenn eine App gestartet wird, aber leider mein Ansatz führt im Gerät nicht mehr booten. Nach dem Flashen des benutzerdefinierten Bildes und dem Booten bleibe ich bei der Cyanogen-Boot-Animation hängen (die animiert wird, ist sie nicht eingefroren). Ein funktionierendes Bild belässt die Animation und startet android nach ca. 2 Minuten (auch beim ersten Booten nach dem Flashen), aber mein ROM mit angepasster Application.java zeigt die Boot-Animation immer noch nach> 15 Minuten an.

Ich weiß, es wäre möglich, laufende Anwendungen mit ActivityManager regelmäßig zu überprüfen, aber da dies ungenau ist und verhindern würde, dass die CPU in Energiesparmodi geht, möchte ich diesen Ansatz verwenden.

Wenn ich sendBroadcast outcomment funktioniert alles gut. Das Problem ist also, dass der ActivityManagerNative noch nicht läuft, aber ich bin unsicher.

Da ich die Protokolle mit adb nicht erhalten kann, weiß ich nicht, an welchem ​​Punkt/warum der Start fehlschlägt.

Können Sie mir sagen, wie Sie überprüfen, ob alle Voraussetzungen für das Senden von Anforderungen erfüllt sind? Alternative Ich könnte meine Absicht nur senden, wenn der Gerätestartvorgang abgeschlossen ist, und alle geöffneten Anwendungen in meinem entsprechenden BroadcastReceiver scannen, aber ich weiß nicht, wie (oder sogar wenn möglich), ob der Startvorgang abgeschlossen ist.

Vielen Dank im Voraus.

Antwort

0

Ok, ich könnte das Problem lösen.

Glücklicherweise will Android wissen, wann das System auch gestartet wird. Die Klasse ActivityManagerService hat eine finishBooting() Funktion, die eine Flagge mCallFinishBooting setzt. Das Hinzufügen eines Getters für diese Flagge ist Teil der Lösung. Ich fügte diesen Getter auch zur Schnittstelle IActivityManager hinzu. Das verbleibende Problem ist die ActivityManagerProxy (kann in ActivityManagerNative.java gefunden werden), die die Schnittstelle implementiert, aber keine finishBooting() Methode hat.

Einige Tests ergaben, dass die ActivityManagerProxy nicht während des Bootens verwendet wird, so dass der Getter hier immer wahr zurückgibt.

Also mit dem folgenden Code kann ich Broadcasts beim Start der Anwendung für jede App senden, nachdem der Startvorgang abgeschlossen ist. Ich bin mir nicht sicher, ob der Check für null wirklich notwendig ist.

if (ActivityManagerNative.getDefault() != null && ActivityManagerNative.getDefault().isCallFinishBooting()) 
     getApplicationContext().sendBroadcastAsUser(intent, android.os.Process.myUserHandle());