试图访问LauncherProvider [英] Trying to access the LauncherProvider

查看:311
本文介绍了试图访问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:

  1. 该LauncherProvider有两个权限:

  1. 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 ,其权威可能有所不同!在不同版本的Andr​​oid的权限也可能会有所不同。例如在我的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆