在 Android 5.0.1_r1 中将意图从 C++ 发送到 java

Sending an intent from c++ to java in Android 5.0.1_r1

经过几次 post 之后,我发现我可以使用以下代码行发送意图(第二行用于调试):

int ret = system("am broadcast -a android.intent.action.MIKE_ACCESSED --user 0"); 

__android_log_print(ANDROID_LOG_DEBUG, "gxp18", "Shell command returned %i", ret);

不幸的是,这个returns总是(无论系统中使用的命令是什么(“...”)):

Shell 命令返回 32512

有趣的是,我可以使用以下方法通过 adb 成功发送意图:

adb shell am broadcast -a android.intent.action.MIKE_ACCESSED

注意!我没有使用 NDK。我在 post 中报告的这段代码是对 Android Framework 中的部分代码的修改。特别是,它是 Android 服务之一的一部分。我正在使用 AOSP 并修改部分源代码。

我记得,由于 Android 5.0 版本中的权限检查,您不能直接在应用程序中执行 am 命令。

这两种情况是不同的。您从 shell 执行的命令具有 shell UID 和 GID,如下所示。

uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0

您在代码中使用 system() 调用执行的命令是使用您应用的 UID 和 GID 执行的,与 shell UID 和 GID 相比,它具有更少的权限。

因此您将以失败的代码结束。您可以优化您的设计以从您的 Java 代码发送此意图。如果你坚持在你的 JNI 中做,更好的解决方案可能是在你自己的 Application 中调用静态 void 方法。这样,您就不必担心大多数时候在 JNI 中无法访问的 Context

public class MyApplication extends Application {

   private static Context context;

   @Override
   public void onCreate() {
       super.onCreate();
       context = this;
    }

    public static void sendIntent() {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("http://www.google.com"));
        context.startActivity(intent);
    }
}

1) 禁用 SELinux(设置为 Permissive 模式) 2) 修改ActivityManagerNative.java绕过userId校验

尽情享受吧:)