1. Nimm jetzt an unserem 2. ADVENT-Gewinnspiel teil - Alle Informationen findest Du hier!

RecentApplicationsDialog in 4.0+ anzeigen

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von FelixL, 23.12.2011.

  1. FelixL, 23.12.2011 #1
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Servus,


    da es mich stört immer einige Sekunden auf die App-Liste beim Halten der Home-Taste zu warten bastele ich mir gerade eine App ähnlich ButtonSavior um einen einzelnen Softkey dafür zu haben. Ich will (und kann, da zu wenige) keine der Hardware-Tasten des Blade dafür opfern, will aber auch nicht durchgehend eine Leiste mit den Softkeys eingeblendet haben.
    Hab nach einem Vormittag an Test eine komplett durchsichtige Leiste am linken Bildschirmrand die eine Zeile Code (zu Testzwecken einen Toast) auslöst wenn man vom linken Bildschirmrand weit genug nach rechts wischt. Funktioniert einwandfrei (wird automatisch hinter der Tastatur angeordnet, z.B.), nur das jetzt der Befehl fehlt um den "RecentApplicationsDialog" auszulösen.
    Der wird vom PhoneWindowManager verwaltet:
    GrepCode: com.android.internal.policy.impl.PhoneWindowManager (.java) - Class - Source Code View)
    Die entsprechende Funktion showOrHideRecentAppsDialog() kann ich aber nicht aufrufen (wobei mir gerade auffällt das ich es noch nicht auf dem 4.0erSDK getestet habe....auf jeden Fall sollte die Funktion System-intern sein).
    Stattdessen wollte ich den Keycode des "AppSwitcherKeys" nutzen:
    KeyEvent | Android Developers


    Unter früheren Versionen soll das so funktioniert haben (als Beispiel mit einem Keycode für HOME:)
    su
    input keyevent 3


    Unter einer ICS-alpha funktioniert es aber nicht. Die Shell gibt
    "+Stopped (signal) input keyevent 3"
    zurück.


    Jemand eine Idee oder das 4.0er SDk schon installiert?
     
  2. Hybrider, 06.01.2012 #2
    Hybrider

    Hybrider Neuer Benutzer

    Beiträge:
    6
    Erhaltene Danke:
    0
    Registriert seit:
    22.12.2011
    Seas, ich wollt nur kurz nachfragen ob du eine lösung gefunden hast?

    Ich würde gerne (wie so viele andere) den search button in ics in den recent app button zu verwandeln. In den keylayout files hab ich den search befehl durch APP_SWITCH ersetzt und das funktioniert wunderbar.
    Da taucht aber natürlich der gingerbread app switcher auf und man hätte natürlich lieber den ICS recent apps screen.

    Unwissend wie ich bin hab ich einfach einmal probiert den befehl APP_SWITCH durch showOrHideRecentAppsDialog() zu ersetzen. Ohne erfolg..

    Mir ist klar, dass dir das wahrscheinlich alles bekannt ist. Wollte nur einfach nachfragen, wie die entwicklung deiner app voran schreitet, weil ich sie toll klingt.

    Ps: den 4.0 sdk hab ich aber außer den emulator, weiß ich nichts damit anzufangen ;) kann aber gerne sachen ausprobiern, obwohl du ihn mitlerweile sicher selbst hast
     
  3. FelixL, 06.01.2012 #3
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Vielen Dank, du hast mir den Trugschluss gezeigt das APP_SWITCH den neuen Dialog anzeigt!
    Werde nochmal den Sourcecode durchstöbern, bin bisher nicht weiter gekommen.
    Das SDK habe ich inzwischen, für den ICS-Source-Code ist meine Ubuntu-Partition zu klein. -.-
     
  4. FelixL, 07.01.2012 #4
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Jetzt bin ich endgültig verwirrt. Der "RecentApplicationsDialog" der vom PhoneWindowManager ausgelöst wird (und damit beim Halten des Home-Keys erscheinen sollte) ist der alte Dialog aus Gingerbread und davor.
    Der neue ist der hier:
    GrepCode: com.android.systemui.recent.RecentsPanelView (.java) - Class - Source Code View
    Die Softkeys nutzen nicht das alte System für die HW-Tasten sondern sind einfache Views mit onTouchListenern:
    GrepCode: com.android.systemui.statusbar.phone.PhoneStatusBar (.java) - Class - Source Code View)


    Na danke Google -.-.
    Im Moment frage ich mich vor allem warum das Halten von Home überhaupt den neuen Dialog anzeigt, da finde ich keine Verbindung.




    Edit:
    *dooh*



    Edit 2:
    Hab es über Reflection versucht, schaffe es aber nicht :/
    http://stackoverflow.com/questions/7021310/how-to-open-or-expand-status-bar-through-intent


    Edit Nummer 3:
    Im PhoneWindowManager ist übrigens auch dein Problem:

    Sprich er benutzt die alte Methode. Wenn du CM9 selbst kompilieren kannst sollte es ein leichtes sein die paar Zeilen zu ändern. Vielleicht sollte man auch einen Patch beim CM9-Team einreichen, ich empfinde das eher als Bug als gewollt.
     
    Zuletzt bearbeitet: 07.01.2012
  5. FelixL, 11.01.2012 #5
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Ich habs geschafft :)
    Man kann ohne Root oder spezielle Berechtigungen den neuen RecentAppsDialog unter Android 4.0+ anzeigen.


    Proof of Concept (Don't judge me, it's working :p)



    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />


    Code:
    package com.felixl.recentlauncher;
    
    
    import java.lang.reflect.Method;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.PixelFormat;
    import android.os.IBinder;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.ViewGroup;
    import android.view.WindowManager;
    import android.widget.Toast;
    
    public class RecentLauncherService extends Service {
        HUDView mView;
        
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
            mView = new HUDView(this);
            WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    10,
                    WindowManager.LayoutParams.FILL_PARENT,
                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
                    PixelFormat.TRANSLUCENT);
            params.gravity = Gravity.LEFT | Gravity.TOP;
            params.setTitle("Load Average");
            WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
            wm.addView(mView, params);    
                //mStatusBarService.toggleRecentApps();
            
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show();
            if(mView != null)
            {
                ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView);
                mView = null;
            }
        }
    }
    
    class HUDView extends ViewGroup {
        private Paint mLoadPaint;
        Context mcontext;
        String serviceManagerName = "android.os.ServiceManager";
        Class serviceManagerClass;
        Class serviceManagerNativeClass;
        String serviceManagerNativeName = "android.os.ServiceManagerNative";
        Object serviceManagerObject;
        Class IStatusBarClass;
        Class IStatusBarStubClass;
        Object IStatusBarStubObject;
        String IStatusBarName = "com.android.internal.statusbar.IStatusBarService";
        Method serviceMethod2;
    
        public HUDView(Context context) {
            super(context);
            mcontext = context;
            Toast.makeText(getContext(),"HUDView", Toast.LENGTH_LONG).show();
    
            mLoadPaint = new Paint();
            mLoadPaint.setAntiAlias(true);
            mLoadPaint.setTextSize(10);
            mLoadPaint.setARGB(255, 255, 0, 0);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //canvas.drawText("Hello World", 5, 15, mLoadPaint);
        }
    
        @Override
        protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (event.getRawX()>100)
                Log.e("FELIXL","TOUCHEVENT############################");
            if (event.getAction()==MotionEvent.ACTION_UP&&event.getRawX()>100){
                Log.e("FELIXL","TOUCHEVENT############################UPPPPPP");
                Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_SHORT).show();
                try{
                    if (IStatusBarStubObject==null||serviceMethod2==null){
                    serviceManagerClass = Class.forName(serviceManagerName);
                    serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
                    Method getService = serviceManagerClass.getMethod("getService", String.class);
                    IBinder retbinder = (IBinder) getService.invoke(serviceManagerClass, "statusbar");
                    IStatusBarClass = Class.forName(IStatusBarName);
                    IStatusBarStubClass = IStatusBarClass.getClasses()[0];
                    Method serviceMethod = IStatusBarStubClass.getMethod("asInterface",
                            IBinder.class);
                    IStatusBarStubObject = serviceMethod
                            .invoke(null, new Object[] { retbinder });
                    Log.e("FelixL","4");
                    serviceMethod2 = IStatusBarStubClass.getMethod("toggleRecentApps");
                    }
                    serviceMethod2.invoke(IStatusBarStubObject);
                 }
                 catch(Exception ex){
                     ex.printStackTrace();
                 }
            }
            return false;
        }
     }
    @Hybrider:
    Falls du hier noch mitliest:
    Es müsste leicht möglich sein eine App zu schreiben die wenn sie aufgerufen wird den Dialog öffnet. Apps sind afaik im Keylayout Tasten zuweisbar, und dein Problem wäre gelöst.
     
    Zuletzt bearbeitet: 11.01.2012
    Hybrider bedankt sich.
  6. Hybrider, 12.01.2012 #6
    Hybrider

    Hybrider Neuer Benutzer

    Beiträge:
    6
    Erhaltene Danke:
    0
    Registriert seit:
    22.12.2011
    Super duper toll :D

    Einer taste eine app zu zuweisen wär für mich kein problem.

    Eine app mithilfe deines codes zu schreiben, ist aber für mich zu hoch (hab ungefähr 0 erfahrung im app schreiben)

    Aber, dass es geht ist ja das wesentliche, habe in xda auch nur leute gefunden die den wunsch haben, aber noch keinerlei lösung.

    auf jeden fall vielen dank für die arbeit und die nachforschungen!!
     
  7. FelixL, 12.01.2012 #7
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Hab ja nicht gesagt das du die App schreiben musst ;)
    Hättest du lieber die App oder in CM9 integriert das der APP_SWITCH-Key den neuen Dialog öffnet und nicht den alten?
     
  8. Hybrider, 13.01.2012 #8
    Hybrider

    Hybrider Neuer Benutzer

    Beiträge:
    6
    Erhaltene Danke:
    0
    Registriert seit:
    22.12.2011
    Ich würd die app bervorzugen.
    auch wenn ich cm9 sicher flashen werd, wenns drausn ist, halt ich eine app für flexibler. weil 4.0.3 läuft bei mir so flüssig, dass mir sonst wenig einfällt was ein wechsel vom stock rechtfertigen würde.

    ich hoffe auch dass die bei cm9 schon dran gedacht haben, weil um mir ein cm9 selbst zu kompilieren fehlt mir die rechenleistung
     

Diese Seite empfehlen