一般地,當意圖可由應用程序(其活性,服務)來處理,並且用戶更喜歡的應用來處理它。 Android框架中的ActivityManagerService(Ams)
將首先查看目標活動/服務的相應應用程序是否仍然存在。如果尚未開始或被殺死,Ams將通過調用startProcessLocked
方法啓動該應用程序。
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated) {
//you can get the uid from ApplicationInfo.uid
...
startProcessLocked(app, hostingType, hostingNameStr);
...
}
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
//prepare its uid, gid, gids for starting that process
...
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, null, null);
...
}
因此,在該方法中,它開始一個新的過程。 Process.start
就是你在你的問題中提到的,它最後稱Zygote爲一個新的過程。
我認爲攔截Ams中的應用程序啓動過程是一種更好的方法。您可以獲得有關此應用程序的更多信息,它也是您的Process.start
方法的上游。
更新:
只是注意到你正在考慮限制意圖。意圖可以由多個應用程序處理,所以我們不能限制應用程序發送特定的意圖。但是我們可以修改解決過程。 Resolving
意味着Android框架需要確定哪個活動/服務可以處理這個意圖。如果有多個選擇,用戶未設置任何偏好,然後會出現如下對話框:
因此,它是可以修改的解析過程,讓Android框架丟棄的事實,你的特定的應用程序能夠處理該意圖。我認爲這也是一種完成工作的方式,但它更加複雜化,因爲Android針對活動,服務和接收方以不同方式解決意圖。對於活動,Ams將撥打以獲取要開始的活動。對於服務,這是調用PackageManagerService
中的resolveService
方法。所以你需要以不同的方式處理它們。但是,由於他們都會在其實現中獲得ResolveInfo的列表,因此您可以輕鬆篩選出您的應用程序。例如,在resolveIntent
在PackageManagerService
:
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
//filter out here!!!!
return chooseBestActivity(intent, resolvedType, flags, query, userId);
}
您可以方便地從ResolveInfo的ApplicationInfo如果你看一看ResolveInfo.java
。
對於接收者來說,它更加複雜,因爲在AndroidManifest.xml和registerReceiver(...)
中註冊的接收者是不同的。如果broadcastIntent中的intent沒有設置標誌FLAG_RECEIVER_REGISTERED_ONLY(普通情況),那麼解析結果將是一個收聽廣播的接收者列表,它可能包含兩種接收者。對於AndroidManifest.xml中的人員,Ams將撥打以獲取收聽廣播的接收者列表。對於由registerReciever(...)
動態註冊的用戶,他們由ActivityManagerService
而不是PackageManagerService
管理,因此Ams將直接撥打mReceiverResolver.queryIntent
來獲取這些接收者。該mReceiverResolver
定義爲:
final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
= new IntentResolver<BroadcastFilter, BroadcastFilter>() {
...
}
所以,你需要做的就是重寫queryIntent方法在你的應用程序來過濾接收器的東西。對於ContentProvider,該方法是PackageManagerService
中的resolveContentProvider
。同樣的方式來處理它。
防止安裝這些黑名單應用程序不是更好嗎? – SimonSays 2013-04-25 18:56:40
阻塞只能在特定的時間段內完成(比如從早上9點到下午5點)。除了這個時間間隔,用戶可以使用該應用程序。 – user1010 2013-04-25 19:56:50