6

Tworzę prosty widget do zarządzania kontaktami, który pozwala użytkownikowi wybierać i wysyłać sms do żądanego kontaktu.Jak rozpocząć nową aktywność z ekranu blokady?

Działa dobrze jako "normalny widget", ale kiedy dodaję go jako widżet blokady ekranu w Androidzie 4.2, aplikacja sms lub aplikacja wybierania numeru nie uruchamia się. W rzeczywistości są gwiazdami, ale "za" ekranem blokady, więc użytkownik nadal musi ręcznie odblokować ekran, aby móc wybierać/wysyłać SMS-y.

Szukałem w sieci jakiegoś rozwiązania, ale nic się nie przydało. Jestem świadomy FLAG_DISABLE_KEYGUARD lub FLAG_SHOW_WHEN_LOCKED, ale ponieważ aplikacje sms/dial nie są "moje", więc nie wiem, czy skonfigurowały odpowiednią flagę. Jako obejście próbowałem utworzyć moją aktywność, która ustawi tę flagę, a następnie po prostu uruchomi wybraną (dial lub sms), ale to nie pomoże.

Istnieje sposób na odblokowanie ekranu, ale wymaga to użycia KeyguardManagera i KeyguardLock (które działają bez zarzutu), ale w wyniku użycia KeyguardLock.newKeyguardLock() w rezultacie telefon nie może automatycznie włączyć blokady, na pewno ponieważ nie zwalniam tej blokady (powoduje ona ponowne pojawienie się blokady, co nie jest tym, czego chcę).

Czy ten widget powinien działać podobnie do domyślnego widżetu SMS lub widżetu poczty na ekranie blokady?

Moje pytanie brzmi: jak to osiągnąć i rozpocząć nową aktywność od blokady ekranu?

+0

Cześć Filip. Zastanawiałem się nad tym samym. Jestem całkiem nowy dla Androida. Więc możesz mi trochę pomóc? Jak ustawić detektory kliknięcia dla przycisków lub widoku w układzie widżetów? Czy to ma coś wspólnego z metodą onReceive klasy AppWidgetProvider? –

+0

Witam, No cóż, nie jest to tak oczywiste i dość trudne do wyjaśnienia (nie wspominając już o jego wdrożeniu :)). Zajęło mi trochę czasu, aby to zrozumieć. W skrócie, aby to osiągnąć, należy użyć klas 'PendingIntent' i' RemoteView'. Najlepiej zajrzeć do [dokumentacji] (http://developer.android.com/guide/topics/appwidgets/index.html#implementing_collections). Krótko mówiąc, jeśli masz skonfigurowany widok za pomocą 'RemoteView', po prostu wprowadź do niego obiekt' PendingIntent' za pomocą metody 'RemoteView # setOnClickFillInIntent'. –

Odpowiedz

7

Sam znalazłem rozwiązanie. okazało się, że jestem blisko :)

Aby uruchomić aplikację/działanie innej firmy, najprostszym rozwiązaniem jest utworzenie pewnego rodzaju aktywności proxy, która ustawi odpowiednie flagi w oknie, a następnie uruchomi pożądaną aktywność i WYKOŃCZENIA.

przykładowy kod znajduje się poniżej:

wywołującego intencyjny w widgecie (proxy nazywając):

@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); 
} 

aktywności proxy po prostu zadzwoń:

@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

Moje dwa centy: Zamiast używania programu obsługi można wywoływać funkcje "startActivity()" i "finish()" w 'onWindowsFocusChanged (pHasFocus)', gdy "pHasFocus" jest prawdziwe. – mamuso

Powiązane problemy