IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Android SDK Hidden API使用

    FranzKafka95发表于 2023-07-06 15:46:13
    love 0
    Read Time:1 Minute, 58 Second

    近期在将某个原生APP从AOSP源码环境编译转变为Android Studio下Gradle编译,其中涉及到一个API接口registerReceiverForAllUsers,在编译时报错该方法不存在。

    经查,该方法实现位于frameworks/base/core/java/android/content/Context.java文件内,代码如下:

    /**
         * Same as {@link #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)}
         * but this receiver will receive broadcasts that are sent to all users. The receiver can
         * use {@link BroadcastReceiver#getSendingUser} to determine on which user the broadcast
         * was sent.
         *
         * @param receiver The BroadcastReceiver to handle the broadcast.
         * @param filter Selects the Intent broadcasts to be received.
         * @param broadcastPermission String naming a permissions that a
         *      broadcaster must hold in order to send an Intent to you. If {@code null},
         *      no permission is required.
         * @param scheduler Handler identifying the thread that will receive
         *      the Intent. If {@code null}, the main thread of the process will be used.
         *
         * @return The first sticky intent found that matches <var>filter</var>,
         *         or {@code null} if there are none.
         *
         * @see #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
         * @see #sendBroadcast
         * @see #unregisterReceiver
         * @hide
         */
        @Nullable
        @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
        @SystemApi
        public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver,
                @NonNull IntentFilter filter, @Nullable String broadcastPermission,
                @Nullable Handler scheduler) {
            throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    可以看到虽然该方法具有public属性,但是却通过@hide标识其会作为一个Hidden api而存在;从android 9开始(API级别属于28),为了帮助提升用户体验和开发者体验,为用户降低应用发生崩溃的风险,同时为开发者降低紧急发布的风险,Android对应用的非SDK接口做了限制,使用非SDK接口,或通过反射、JNI的方式来使用非SDK接口将不被允许,关于该限制的更多信息可以参考该链接。

    如何区分SDK接口和非SDK接口呢,SDK接口是在https://developer.android.com/reference/packages中公开可查询的稳定提供的接口,而非SDK接口通常是不稳定的,所以不会对外开放,关于这些非SDK接口的信息,可以参考该链接。

    在实际开发过程中,我们可能会用到这些Hidden API,以往我们可以通过反射的方式来调用这些API,但这种方法在新的安卓系统中已经不再适用,那么还有没有办法可以绕开该限制呢。这里以两种情形教大家如何去调用Hidden API。

    情形一:AOSP源码环境下使用Android.bp配置编译环境

    在AOSP源码环境下调用Hidden API,一般我们只需要进行两个步骤即可。一是在Android.bp中配置相关权限,二是在AndroidManifest.xml中对相关权限进行声明。针对registerReceiverForAllUsers接口,我们需要配置Android.bp如下:

    android_app {
        name: "App_Name",
    
        owner: "google",
    
        srcs: ["src/**/*.java"],
    
        resource_dirs: ["res"],
    
        // registerReceiverForAllUsers() is a hidden api.need this setting
        platform_apis: true,
    
    }

    信息来源于谷歌官方链接:

    At build time, Make and Soong verify that Java modules in the product partition don't use hidden APIs by checking the platform_apis and sdk_version fields. The sdk_version of apps in the product partition must be filled with current, system_current, or numeric version of the API, and the platform_apis field must be empty

    除了Android.bp中进行配置,我们还需要进行权限相关的声明:

    <!-- for registerReceiverForAllUsers() -->
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />

    具体需要的权限,请查看该接口实现的地方所作的定义。

    情形二:Android Stuido环境下使用Gradle配置编译

    当我们把源码放到Android Studio环境下进行编译时,同样需要在 AndroidManifest.xml中对相关权限进行声明,这一点同上。不过此时我们无法在Gradle配置中配置platform_apis属性了。

    此时我们可以在AOSP环境下找到包含该SDK接口的android.jar,替换掉Android Studio下载的SDK中的${Android Sdk}/platforms/andorid-api/即可,在AOSP源码环境下有诸多android.jar,如何查看该android.jar是否包含该接口呢,这里我们使用jar命令进行查看,如下所示:

    fanzkafkafka:$ jar xf android.jar | grep -nr registerReceiverForAllUsers
    fanzkafkafka:$ Binary file android/content/ContextWrapper.class matches
    fanzkafkafka:$ Binary file android/content/Context.class matches

    如果你没有AOSP环境,我们可以通过一个GitHub项目来获取相应的Android.jar,具体可参考该项目。

    如此,我们就能正常使用Hidden API了。不过需要说明的是,Hidden API是官方明确不希望开发者使用的,可能会存在不稳定或者兼容性问题,我们应当尽可能避免使用这类API。

    Happy
    Happy
    1 100 %
    Sad
    Sad
    0 0 %
    Excited
    Excited
    0 0 %
    Sleepy
    Sleepy
    0 0 %
    Angry
    Angry
    0 0 %
    Surprise
    Surprise
    0 0 %

    The post Android SDK Hidden API使用 first appeared on FranzKafka Blog.



沪ICP备19023445号-2号
友情链接