试图访问LauncherProvider [英] Trying to access the LauncherProvider
问题描述
我试图访问 LauncherProvider
。你可以找到它的源$ C $ C <一个href="https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/LauncherProvider.java"相对=nofollow> 此处
I am trying to access the LauncherProvider
. You can find its source code here
我试图查询这个的ContentProvider
是这样的:
I tried to query this ContentProvider
like this:
Uri uri = new Uri.Builder().scheme("content").authority("com.android.launcher.settings").appendPath("favorites").build();
String[] projection = new String[]{
"_id", "title", "intent", "container", "screen", "cellX", "cellY",
"spanX", "spanY", "itemType", "appWidgetId", "isShortcut", "iconType",
"iconPackage", "iconResource", "icon", "uri", "displayMode"
};
String selection = null;
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Cursor query = getActivity().getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
if (query != null) {
while (query.moveToNext()) {
Log.d(TAG, query.getString(2));
}
}
if (query != null) {
query.close();
}
然而光标
我得到的是永远空
!这是我得到的logcat的错误:
However the Cursor
I get is always null
! This is the error I get in the logcat:
07-31 15:55:14.703 24773-24773/x.y.z.testE/ActivityThread﹕ Failed to find provider info for com.android.launcher.settings
谁能告诉我什么,我做错了什么?
Can anybody tell me what I'm doing wrong?
推荐答案
您试图访问 LauncherProvider
,但可能不是你想要的那样容易。存在两个主要问题:
Explanation of your problems
You are trying to access the LauncherProvider
, but that may not be as easy you want. There are two main problems:
-
该LauncherProvider有两个权限:
The LauncherProvider has two permissions:
-
com.android.launcher.permission.READ_SETTINGS
从中读取数据。 -
com.android.launcher.permission.WRITE_SETTINGS
来写入。
com.android.launcher.permission.READ_SETTINGS
to read from it.com.android.launcher.permission.WRITE_SETTINGS
to write to it.
不同的原始设备制造商编写他们自己的版本的 LauncherProvider
,其权威可能有所不同!在不同版本的Android的权限也可能会有所不同。例如在我的Nexus 5的正确的提供者的权威是 com.android.launcher3.settings
。
Different OEMs write their own version of the LauncherProvider
and its authority might be different! On different versions of Android the authority might also be different. For example on my Nexus 5 the authority of the correct provider is com.android.launcher3.settings
.
声明的权限当然不是问题,但要找到正确的的ContentProvider
可以证明是困难的,好在有一个解决方案!
Declaring the permissions is of course not a problem, but finding the correct ContentProvider
can prove difficult, fortunately there is a solution!
您首先要声明的所有所需的权限在清单中是这样的:
You first have to declare all the required permissions in the manifest like this:
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />
在这之后,我们需要找到正确的供应商!为此,您可以通过所有的 ContentProviders每个应用程序的
读取所有安装的应用程序的 PackageInfo
和循环。该的ContentProvider
具有 READ_SETTINGS
和 WRITE_SETTINGS
的读取和写入权限是我们要找的人。但是,我们需要一个更复杂的逻辑来找到合适的人,因为权限往往是基于包的名称。
And after that we need to find the correct provider! You can do that by reading the PackageInfo
of all the installed apps and looping through all the ContentProviders
of each app. The ContentProvider
which has READ_SETTINGS
and WRITE_SETTINGS
as read and write permission is the one we are looking for. But we need a more complex logic to find the right one since the permissions are often based on the package name.
public static String findLauncherProviderAuthority(Context context) {
// Gets PackageInfo about all installed apps
final List<PackageInfo> packs = context.getPackageManager().getInstalledPackages(PackageManager.GET_PROVIDERS);
if (packs == null) {
return null;
}
for (PackageInfo pack : packs) {
// This gets the ProviderInfo of every ContentProvider in that app
final ProviderInfo[] providers = pack.providers;
if (providers == null) {
continue;
}
// This loops through the ContentProviders
for (ProviderInfo provider : providers) {
// And finally we look for the one with the correct permissions
// We use `startsWith()` and `endsWith()` since only the middle
// part might change
final String readPermission = provider.readPermission;
final String writePermission = provider.writePermission;
if(readPermission != null && writePermission != null) {
final boolean readPermissionMatches = readPermission.startsWith("com.android.") && readPermission.endsWith(".permission.READ_SETTINGS");
final boolean writePermissionMatches = writePermission.startsWith("com.android.") && writePermission.endsWith(".permission.WRITE_SETTINGS");
if(readPermissionMatches && writePermissionMatches) {
// And if we found the right one we return the authority
return provider.authority;
}
}
}
}
return null;
}
所以这应该很可靠地返回正确的的ContentProvider
!你可能想,如果你碰到某些设备上的问题,调整它多一点,但在所有设备上我可以测试它(这是一个很大的设备),它完美地工作。你可以用上面的方法是这样的:
So this should very reliably return the correct ContentProvider
! You may want to tweak it a little more if you run into problems on some devices, but on all devices I could test it (and that's a lot of devices) it is working perfectly. You can use the method above like this:
final String authority = findLauncherProviderAuthority(getActivity());
final Uri uri = new Uri.Builder().scheme(CONTENT).authority(authority).appendPath(PATH).build();
...
我希望我可以帮你,如果你有任何问题,请随时问!
I hope I could help you and if you have any further questions please feel free to ask!
这篇关于试图访问LauncherProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!