2013-10-18 58 views
2

我從通知中啓動意圖時遇到問題(準確地說有兩個問題)。通知中的意圖選擇器

我目前的情況是,我有一個apk家族,都可以使用第一個啓動的遠程服務。該服務創建一個通知,單擊時會打開啓動該服務的應用程序。這工作正常。

我想改善這一點,所以當安裝了多個應用程序的家庭,而不是隻是去啓動服務的apk選擇器意圖會出現,用戶將能夠選擇apk來回到。

我設法做到了這一點。

ArrayList<String> myApps = Lists.newArrayList(
      "com.myapp1", 
      "com.myapp2", 
      "com.myapp3", 
      "com.myapp4" 
    ); 

    List<Intent> targetedIntents = new ArrayList<Intent>(); 

    Intent baseIntent = new Intent(Intent.ACTION_MAIN, null); 
    baseIntent.addCategory("android.intent.category.LAUNCHER"); 

    final PackageManager packageManager = getApplicationContext().getPackageManager(); 
    List<ResolveInfo> list = packageManager.queryIntentActivities(baseIntent, 0); 

    for (ResolveInfo resolveInfo : list) { 
      String packageName = resolveInfo.activityInfo.packageName; 
      if (packageName != null && myApps.contains(packageName)) { 

       Intent targetedIntent = new Intent(); 
       targetedIntent.setPackage(packageName); 
       targetedIntent.setClassName(packageName, resolveInfo.activityInfo.name); 
       targetedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

       targetedIntents.add(targetedIntent); 
      } 
    } 

    Intent intent = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=whatever")), "Select app to return to"); 
    intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{})); 

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, intent.getFlags()); 
    notification.setLatestEventInfo(this, notificationTitle, notificationMessage, contentIntent); 

這個工作主要是因爲它應該。選擇器出現,選定的選項啓動所需的apk。

但我在2個問題就來了:

一,當我創建只有我感興趣的意圖意圖選擇器,選擇器是空的消息「沒有應用程序可以執行此操作」

 intent = Intent.createChooser(targetedIntents.get(0), "Select app to return to"); 
    intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{})); 

但是,如果我把existing apk there first(如谷歌播放)一切正常,我的選項與谷歌播放選項一起顯示。

 intent = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=whatever")), "Select app to return to"); 
    intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{})); 

這是我可以生活的東西,但是如果只有正確的機會在那裏,會更好。

二,當我從列表中點擊apk時,而不是從背景回來(如果apk已經在那裏運行),它會重新啓動它。我有適當的標誌設置。

Intent targetedIntent = new Intent(); 
    targetedIntent.setPackage(packageName); 
    targetedIntent.setClassName(packageName, resolveInfo.activityInfo.name); 
    targetedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

在使用選擇器之前,我只發佈了一個意圖,它通常會恢復背景apk。

intent = new Intent(this, MainActivity.class); 
    intent.setAction("android.intent.action.MAIN"); 
    intent.addCategory("android.intent.category.LAUNCHER"); 

不知道我在做什麼錯在這裏,apk重新啓動insted insted的恢復。

回答

2

對於第一個問題(選擇器問題),您收到錯誤「沒有應用程序可以執行此操作」的原因是因爲您傳遞給getChooser()Intent沒有Android可以使用的ACTION搜索可以處理Intent的應用程序。 getChooser將使用Intent中的ACTION,CATEGORY和DATA來搜索合適的應用程序。然後它將使用包名和組件名來過濾這個列表。就你而言,因爲你只提供了包和組件名稱(但沒有指定ACTION),所以Android找不到任何合適的應用程序。我不確定有沒有辦法解決這個問題,因爲你想用不同的軟件包建立一個列表。您可能只需要創建自己的選擇器對話框(無論如何,這可能是正確的選擇,因爲您已經確定了列表應包含的內容,因此使用Android選擇器沒有任何優勢)。


對於第二個問題(如果應用程序在後臺時,它會重新啓動),你需要使用下面的選項:

targetedIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

發射任務的根活動時將帶來一個指定Intent.FLAG_ACTIVITY_NEW_TASK已經存在的任務到了前臺。

注意:如果您只想將現有任務置於前臺(處於任何狀態),則只需使用Intent.FLAG_ACTIVITY_NEW_TASK並刪除其他2個標誌。

+0

第二個問題的解決方案可以正常工作。我有一個關於爲選擇器創建自己的對話框的問題(我認爲這是唯一的合理解決方案):我將如何去做,因爲選擇器是從pendingIntent啓動的? (我不能從無處發起對話) – darkhie

+0

從您的通知中,您可以啓動看起來像對話框的活動。搜索StackOverflow,你會發現一些例子。 –