6

我正在爲聯繫人管理創建一個簡單的小部件,它允許用戶撥打併發送短信至所需的聯繫人。如何從鎖屏開始新的活動?

它工作正常,「正常窗口小部件」,但是當我將其添加在Android 4.2插件鎖屏,手機短信應用或撥號程序無法啓動。 事實上,他們明星,但「鎖定」幕後,所以用戶仍然必須手動解鎖屏幕才能撥打/發送短信。

我搜索網頁一些解決方案,但沒有派上用場。 我是知道FLAG_DISABLE_KEYGUARD或FLAG_SHOW_WHEN_LOCKED的,但由於短信/撥號應用程序是不是‘我的’,所以我不知道他們是否設置正確的標誌。 作爲一種解決方法,我試圖創建我的活動,設置這些標誌,然後簡單地啓動所需的一個(撥號或短信),但這沒有幫助。

有一種解鎖屏幕的方法,但這涉及到使用KeyguardManager和KeyguardLock(它工作正常),但是在使用KeyguardLock.newKeyguardLock()的結果中,我最終發現手機無法自動鎖定,當然因爲我不釋放這個鎖(它導致鎖再次出現,這不是我想要的)。

事實上,這個小部件應simmilarly工作,默認鎖屏上的短信Widget或電子郵件小部件?

所以,我的問題是,如何實現這一點,從鎖屏開始新的活動?

+0

嗨菲利普。我想知道同樣的事情。我對android非常陌生。那麼你能幫我一下嗎?如何將點擊監聽器設置爲按鈕或在小部件佈局中查看?這是否與你的AppWidgetProvider類的onReceive方法有關? – 2013-08-29 20:58:28

+0

嗨, 嗯,這不是很明顯,而且相當棘手的解釋(更不用說實施:))。我花了一段時間來解決這個問題。 總之,您需要使用'PendingIntent'和'RemoteView'類來實現它。最好的方法是查看[文檔](http://developer.android.com/guide/topics/appwidgets/index.html#implementing_collections)。 總之,當你通過'RemoteView'配置你的看法,只是通過'遠程視窗#setOnClickFillInIntent'方法注入'PendingIntent'對象進去。 – 2013-09-05 20:02:59

回答

7

嗯,我自己找到解決方案。原來我很接近:)

要啓動第三方應用程序/活動,最簡單的解決方案是創建某種代理活動,它將在窗口上設置適當的標誌,然後啓動所需的活動和完成。

示例代碼如下所示:

調用的意圖在小部件(呼叫代理):

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

在代理活動只要致電:

@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

我的兩分錢:當'pHasFocus'爲true時,您可以在'onWindowsFocusChanged(pHasFocus)'中調用'startActivity()'和'finish()'來代替使用處理函數。 – mamuso 2014-03-13 15:01:09