我正在使用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
我有什么遗漏。!!提前谢谢。
答案 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.jar
和zipalign
工具,您可以在此处找到这些工具:
[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
目录中,以使其正常工作。