關於activity前臺後臺切換
[問題] Task_B取得result之後,需要把Task_A帶到前臺(active),這樣Activity_1才能響應(onActivityResult)到Activity_2返回(setResult)的結果。 現在的問題就在於,Task_B並不一定能夠退出(Activity_3其可能其他程式,如browser等),從而把Task_A帶到前臺;又或者Task_A和Task_B中又夾雜了其他的Task(你知道,長按home鍵你可以做得出來),以至於呼叫Task_B.moveTaskToBack()也不能解決問題。 [解決方案]
如果你的平臺是面向Android3.0(API level 11),那麼恭喜你,一個函式就可以搞定:
moveTaskToFront
SDK說,如果用帶FLAG_ACTIVITY_NEW_TASK標誌來啟動一個activity,並且這個activity與當前執行的另一個task(A)的affinity名字相同,那麼就這個activity就會在那個task(A)裡啟動。 Ok,到這還不行,人家沒說會把Task_A帶到前臺,接著看另一個Flag
好了,重點來了:如果Task_A中已經有了Activity_2,這時候如果以FLAG_ACTIVITY_NEW_TASK來start Activity_2,那麼這個Task_A就會被帶到前臺
如果Activity_2在Task的頂端,那麼這個Activity_2就不會被再此建立,而是走onNewIntent. 至此,結合上面3個特性,問題得以解決。結合程式碼,流程如下: 1. 在androdiManifest.xml中新增Activity_2的taskAffinity name與Task_A相同(也就是與Activity_1的taskAffinity名字相同),如android:taskAffinity = "android.task.calendar"。 2. 在Task_B啟動前,Activity_1先啟動Activity_2並要求返回結果,startActivityForResult(). 3. Task_B中的Activity_4取得所需資料後,儲存好(intent,或其他方法),然後startActivity(Activity_2),並帶上(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP)標誌。 4. Task_A被帶到前臺,並且呼叫到Activity_2::onNewIntent(). 5. Activity_2取得之前儲存的資訊(從Intent或其他地方),呼叫setResult(),然後finish(). 6. Activity_1中的onActivityResult()響應,得到返回結果。 總結下:
Android 顯示 Activity 到前臺
Java程式碼1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<uses-permission
android:name= "android.permission.REORDER_TASKS"
/>
public
class
SampleActivity extends
Activity {
private
ActivityManager.RunningAppProcessInfo getRunningAppProcessInfo(String packageName) {
ActivityManager
am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo>
processList = am.getRunningAppProcesses();
for
(ActivityManager.RunningAppProcessInfo p : processList) {
if
(p.processName.equals(packageName)) {
return
p;
}
}
return
null ;
}
private
boolean
isForeground(String packageName) {
ActivityManager.RunningAppProcessInfo
processInfo = getRunningAppProcessInfo(packageName);
if
(processInfo != null )
{
return
ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND == processInfo.importance;
}
return
false ;
}
private
boolean
moveTaskToFront() {
ActivityManager
am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(getTaskId(),
0 );
return
isForeground(getPackageName());
}
}
|
用什麼方法知道該應用是否處於前臺呢?
網上搜到的方法大多數都是使用下面的程式碼:
1 2 3 4 5 6 |
|
但是查閱Android文件後發現,google並不推薦使用這個方法:
This should never be used for core logic in an application, such as deciding between different behaviors based on the information found here. Such uses are not supported, and will likely break in the future. For example, if multiple applications can be actively running at the same time, assumptions made about the meaning of the data here for purposes of control flow will be incorrect.
而且,這個方法還要求設定android.permission.GET_TASKS
許可權。
因此,我必須尋找更加合適的方法來做這件事。最終,我找到這個方法getRunningAppProcesses(),它並不需要增加特殊的許可權。
下面是範例程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|