安装在system / priv-app中的应用程序无法在不重启(root)的情况下启动

时间:2014-10-17 14:03:51

标签: android android-intent android-service rooted-device

我正在使用root设备。我创建了一个作为系统应用程序运行的应用程序。我已经将apk文件复制到sd卡,然后从adb shell挂载/ system目录作为su user复制到/ system / priv-app。清单文件如下所示

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="abc.def.settings"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.STATUS_BAR" />
    <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >

        <service
            android:name="abc.def.settings.service.SystemSettingsService" >
        </service>

        <receiver android:name="abc.def.settings.boot.DeviceBootReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="abc.def.settings.start_after_reinstall"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

将apk复制到/ system / priv-app后,我将权限从shell更改为777。应用程序启动设备启动非常好。但是我无法在重新启动之前启动该服务。我的一个限制是不应重新启动设备来启动此服务。

我尝试了以下但没有一个有效。

adb shell am startservice -n abc.def.settings/.SystemSettingsService
adb shell am startservice -n abc.def.settings/.service.SystemSettingsService
adb shell am startservice -a abc.def.settings.start_after_reinstall
adb shell am broadcast -a abc.def.settings.start_after_reinstall
adb shell am broadcast -a abc.def.settings.start_after_reinstall -f 32

我有什么遗漏。!!提前谢谢。

1 个答案:

答案 0 :(得分:4)

我知道这是一个老问题,但我想在这里发布一个答案,以便其他人可能希望自定义ROM或在使用内部或受限API的现有设备上安装自己的应用程序。我不得不寻找相当长的时间来获取我在这里提供的信息,因为信息可能很难找到。

要使priv-app APK正常运行,甚至完全根据权限运行,需要使用已用于ROM中的关键系统应用程序的系统密钥和框架JAR文件进行签名(通常在/system/framework)。

在某些情况下(例如基于MediaTek CPU的中文ROM等),正在使用的APK签名密钥是标准的Android AOSP(Android开源项目)签名密钥,可以在Android源代码分发中找到。作为AOSP发行版的一部分提供了4个默认密钥,每个密钥作为私有/公共对提供。他们的名字是:

media.pk8
media.x509.pem
platform.pk8
platform.x509.pem
shared.pk8
shared.x509.pem
testkey.pk8
testkey.x509.pem

如果您想将APK添加到使用过这些签名密钥的ROM中,那么您很幸运!我已经包含了一个脚本和一些指向下面所需文件的链接,以便完成整个过程。

但是,如果您尝试从三星等主要制造商自定义ROM,您可能会发现需要使用新密钥重新签名所有系统APK文件,以使您的应用在/system/priv-app目录。

你还需要为你的ROM修改框架APK,这样它们也会被你的新密钥签名,并且你可以想象这个过程充满了危险,因为如果你错过了什么东西会导致ROM无法使用重要。此过程超出了答案的范围,但您可以在XDA开发人员上找到适合不同制造商的一些好资源。我已将它链接起来,但目前我的声誉太低,我不能分享两个以上的链接。

如果您的应用使用的任何内部API仅适用于已签名的特权系统应用,则必须执行此步骤才能调用这些API。这些API包括使用反射访问的API,以及对这些API的直接调用。

我在您的清单中看到您在APK中至少使用了两个受限制的权限。那些是:

<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />

<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

如果没有签名,这些权限几乎无用,尤其是WRITE_SECURE_SETTINGS权限。

我写了一个小的shell脚本,在需要的时候签署我的priv-app APK,这里是源代码。执行签名过程后,您还需要zip-align您的APK。它适用于OS X / macOS和Linux:

#!/bin/bash
echo Signing with Android Platform key...
java -jar signapk.jar -w platform.x509.pem platform.pk8 <app-name-for-signing>.apk <app-signed-output>.apk
echo Zip-Aligning...
./zipalign -f 4 <app-signed-output>.apk <final-app-name-signed-zipaligned>.apk
echo Done!
echo

您需要获得适用于您平台的signapk.jarzipalign工具,您可以在此处找到这些工具:

[CROSS-PLATFORM] APK Sign/Zipalign/Install

您还需要获取AOSP标准密钥,这些密钥可在许多位置使用,包括https://github.com/android/platform_build/tree/master/target/product/security

如果您想知道ROM中的priv-app APK文件使用了哪个签名密钥,您可以使用标准Java工具执行两步过程,因此请确保您拥有Java SDK(任何味道)安装,然后按照这个答案中的步骤:

How do I find out which keystore was used to sign an app?

如果您发现ROM正在使用AOSP密钥,那么您只需使用相同的密钥签署自己的APK文件并将其放在priv-app目录中,以使其正常工作。