6

Ich erstelle ein einfaches Widget für die Kontaktverwaltung, die es dem Benutzer ermöglicht, SMS an den gewünschten Kontakt zu wählen und zu senden.Wie starte ich eine neue Aktivität vom Lockscreen?

Es funktioniert gut als "normales Widget", aber wenn ich es als Lockscreen-Widget auf Android 4.2 hinzufügen, startet SMS App oder Dial App nicht. Nun, in der Tat, sie Sterne, aber "hinter" Lockscreen, so muss der Benutzer noch manuell Bildschirm entsperren, um in der Lage zu sein, zu wählen/senden SMS.

Ich suchte im Internet nach einer Lösung, aber nichts nützte sich. Ich bin bewusst, FLAG_DISABLE_KEYGUARD oder FLAG_SHOW_WHEN_LOCKED, aber da SMS/Dial-Apps sind nicht "meins", so weiß ich nicht, ob sie richtige Flag einrichten. Als Workaround habe ich versucht, meine Aktivität zu erstellen, die diese Flagge setzt und dann einfach gewünschte (Dial oder SMS) startet, aber das hilft nicht.

Es gibt eine Möglichkeit, Bildschirm zu entsperren, aber das beinhaltet die Verwendung von KeyguardManager und KeyguardLock (die gut funktionieren), aber als Ergebnis der Verwendung von KeyguardLock.newKeyguardLock() ich am Telefon nicht in der Lage sein, die Sperre automatisch zu sperren weil ich diese Sperre nicht freigebe (es bewirkt, dass die Sperre wieder erscheint, was ich nicht will).

In der Tat sollte dieses Widget ähnlich wie Standard-SMS-Widget oder Mail-Widget auf Sperrbildschirm funktionieren?

Also, meine Frage ist, wie man das erreicht und neue Aktivität von Lockscreen starten?

+0

Hallo Filip. Ich habe mich über dasselbe gewundert. Ich bin ziemlich neu bei Android. Kannst du mir hier ein wenig helfen? Wie setzen Sie Klick-Listener auf die Schaltflächen oder die Ansicht im Widget-Layout? Hat das etwas mit der on onReceive-Methode Ihrer AppWidgetProvider-Klasse zu tun? –

+0

Hallo, Nun, das ist nicht so offensichtlich und ziemlich schwierig zu erklären (ganz zu schweigen von der Implementierung :)). Ich brauchte eine Weile, um das herauszufinden. Kurz gesagt, Sie müssen 'PendingIntent' und' RemoteView' Klassen verwenden, um dies zu erreichen. Der beste Weg ist, nach [Dokumentation] (http://developer.android.com/guide/topics/appwidgets/index.html#implementing_collections) zu schauen. Kurz gesagt, wenn Sie Ihre Ansicht über 'RemoteView' konfiguriert haben, injizieren Sie einfach' PendingIntent' Objekt über die 'RemoteView # setOnClickFillInIntent' Methode. –

Antwort

7

Nun, ich habe selbst eine Lösung gefunden. Es stellte sich heraus, dass ich in der Nähe war :)

Um 3rd Party App/Aktivität zu starten, ist einfachste Lösung, eine Art Proxy-Aktivität zu erstellen, die richtige Flags auf Fenster setzt und startet dann gewünschte Aktivität und endet.

Beispielcode ist unten dargestellt:

Aufruf Absicht in Widget (Aufruf Proxy):

@Override 
public void onReceive(Context context, Intent intent) { 
    Utilities.printLog(TAG, "onReceive"); 
    Utilities.printLog(TAG, "intent: " + intent); 
    if (intent.getAction().equals(ACTION)) { 

     final String number = intent.getStringExtra(EXTRAS); 
     Toast.makeText(context, "Selected number: " + number, 
       Toast.LENGTH_SHORT) 
       .show(); 


     /** REMOVING KEYGUARD RECEIVER **/ 
     // not really an option - lock is still holded by widget and screen 
     // cannot be locked again ;(
     // KeyguardManager keyguardManager = (KeyguardManager) context 
     // .getSystemService(Context.KEYGUARD_SERVICE); 
     // KeyguardLock lock = keyguardManager 
     // .newKeyguardLock(Context.KEYGUARD_SERVICE); 
     // lock.disableKeyguard(); 

     final Intent activity = new Intent(context, MainActivity.class); 
     activity.putExtras(intent.getExtras()); 
     activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     activity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 
     activity.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 
     context.startActivity(activity); 
    } 

    super.onReceive(context, intent); 
} 

in Proxy-Aktivität rufen Sie einfach an:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().requestFeature(Window.FEATURE_NO_TITLE); 
    // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); 

    final Intent callingIntent = getIntent(); 

    final String actionToLaunch = callingIntent.getStringExtra(ContactsStackWidgetProvider.ACTION); 
    final String number = callingIntent.getStringExtra(ContactsStackWidgetProvider.EXTRAS); 

    final Intent activity = new Intent(); 
    if (actionToLaunch.equals(Intent.ACTION_DIAL)) { 
     activity.setAction(Intent.ACTION_DIAL); 
     activity.setData(Uri.parse("tel:"+number)); 
    } else if (actionToLaunch.equals(Intent.ACTION_SENDTO)) { 
     activity.setAction(Intent.ACTION_SENDTO); 
     activity.setData(Uri.parse("sms:"+number)); 
    } else { 
     throw new IllegalArgumentException("Unrecognized action: " 
       + actionToLaunch); 
    } 

    new Handler().postDelayed(new Runnable() { 

     @Override 
     public void run() { 
      startActivity(activity); 
      finish();//it is important to finish, but after a small delay 
     } 
    }, 50L); 


} 
+0

Meine zwei Cent: Anstatt einen Handler zu verwenden, können Sie 'startActivity()' und 'finish()' in 'onWindowsFocusChanged (pHasFocus)' aufrufen, wenn 'pHasFocus' wahr ist. – mamuso