2012-01-05 66 views
3

背景
我有一個任務(即應用程序)與多個活動。將任務帶到android.intent.action.USER_PRESENT上

問題
如何把一個任務前W/O重新排序的活動堆棧這項任務?

用戶場景
當設備啓動(即在接收的廣播android.intent.action.BOOT_COMPLETED後)我的應用程序啓動時,調用此任務1,並顯示活性的(下面的代碼)。當用戶與任務1交互時,他/她在堆棧上打開活動B(活動B現在當前顯示在屏幕上)。接下來,用戶點擊home鍵並打開其他任務,將其稱爲任務2,然後鎖定屏幕。用戶解鎖屏幕,android.intent.action.USER_PRESENT意圖被我的應用程序廣播和接收(請參閱下面的清單片段)。我執行startActivity()在我的IntentReceiver類調用如預期,但而不是僅僅把任務交給它創建一個新任務的前景,稱其任務3.

變化我已經試過
如果我修改或改變Intent.FLAG_ACTIVITY_NEW_TASK到任何其他意圖然後我得到此錯誤消息:

從一個活動上下文之外調用startActivity()需要 的FLAG_ACTIVITY_NEW_TASK標誌。這真的是你想要的嗎?

...所以它看起來像我不得不使用Intent.FLAG_ACTIVITY_NEW_TASK。

如果我將主活動的lauchMode更改爲「singleTask」,則將正確的任務帶到前臺(即不創建新任務),但活動堆棧會重新排序,以使activity_A位於堆棧頂部。

在這一點上,我對如何將現有任務帶到前臺沒有重新排序活動堆棧的同時傾聽android.intent.action.USER_PRESENT意圖感到遺憾,任何幫助將不勝感激。

順便說一句,這個應用程序正在交付給公司擁有的Android設備上的一組員工,而不是普通大衆。

代碼片段
要啓動應用程序,我設置的廣播接收器在我的清單文件。

<application 
     : 
    <activity 
     android:label="@string/app_name" 
     android:launchMode="singleTop" 
     android:name=".activities.activity_A" > 
     <intent-filter > 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.HOME" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
     : 
    <receiver 
     android:enabled="true" 
     android:name=".utilities.IntentReceiver" 
     android:permission="android.permission.RECEIVE_BOOT_COMPLETED" > 
     <intent-filter > 
      <action android:name="android.intent.action.BOOT_COMPLETED" /> 
      <action android:name="android.intent.action.USER_PRESENT" /> 

      <category android:name="android.intent.category.DEFAULT" /> 
     </intent-filter> 
    </receiver> 

在我的IntentReceiver類中,我開始了我的主要活動......

public class IntentReceiver extends BroadcastReceiver { 

@Override 

    public void onReceive(Context context, Intent intent) { 
     Intent i = new Intent(context, activity_A.class); 
     i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(i); 
    } 
} 

回答

5

這裏有一個稍微hackish的實現,爲我的作品:

  • 創建一個簡單的BringToFront活動,僅僅finish()的是其onCreate()

    public class BringToFront extends Activity { 
    
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         finish(); 
        } 
    
    } 
    
  • 在你的廣播接收器,開始上面的BringToFront活動,而不是您的activity_A,如果操作是USER_PRESENT:

    @Override 
    public void onReceive(Context context, Intent intent) { 
        Class<? extends Activity> activityClass = activity_A.class; 
    
        if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) { 
         activityClass = BringToFront.class; 
        } 
    
        Intent i = new Intent(context, activityClass); 
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
        context.startActivity(i); 
    } 
    

這工作,因爲BringToFront活動具有相同的taskAffinity爲您activity_A並啓動它將使系統把現有任務的前景。然後BringToFront活動立即退出,將您任務中的最後一個活動(您的方案中的activity_B)帶到最前面。

值得注意的是,在API級別11(Honeycomb)上,moveTaskToFront()方法被添加到系統的ActivityManager服務中,這可能是實現您想要的更好的方法。

+0

這個作品幾乎除以下情形:(1)該應用程序正在運行; (2)用戶退出應用程序(主要活動調用完成()); (3)用戶鎖屏; (4)用戶解鎖屏幕。 在這種情況下,應用程序收到Intent.ACTION_USER_PRESENT(請參閱logcat中的Log.i語句),以便按預期方式啓動並退出BringToFront.class活動,但由於此應用程序之前已退出,因此該應用程序中不存在其他任何活動堆棧,並且用戶返回到主屏幕(或之前顯示的任何應用程序)。 我如何知道應用程序是否正在運行,以便我可以啓動activity_A.class? – celoftis 2012-01-09 15:55:29

+0

你節省了我的時間喬。在過去兩天裏一直在尋找這個。一個很好的解決方法。 – Prachur 2013-08-15 14:45:32

+0

@Joe蜂窩前的任何事情? – Pierre 2014-01-07 21:05:35

0

好吧,我可以通過在我的主要活動(activity_A)中添加一個靜態全局變量來實現這個功能。在onCreate中,我設置了isRunning = true,並且onDestory = false。然後在我的IntentReceiver I類檢查,將isRunning來確定要啓動的活動:

  : 
    if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) { 
     if (GlobalVariables.isRunning) { 
      activityClass = BringToFront.class; 
     } else { 
      activityClass = activity_A.class; 
     } 
    } else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { 
     activityClass = activity_A.class; 
    } 
      : 
相關問題