**RK3288 安卓N项目客户要求预置两个APK,要求用户可以卸载,恢复出厂设置时不能恢复;安卓平常的经验尝试了几种方法都不行,让自己一度开始怀疑人生了,后面经同事指导,在代码里面加载预装apk后,才搞定,感谢!前面也是无语到崩溃啊;
以下是尝试方法和修改的过程:**
1、LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/app 这两种方法在out目录可以编译生成APK,但是刷机后系统里面没有这两个apk,用adb install 进系统时会报V2签名的问题;但是APK是在官网下载的。
2、然后,规避V2签名的问题
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collect certificates from /data/app/vmdl1483607312.tmp/base.apk: META-INF/CERT.SF indicates /data/app/vmdl1483607312.tmp/base.apk is signed using APK SignatureScheme v2, but no suchsignature was found. Signature stripped?]
$(shell cp $(LOCAL_PATH)/**/.apk $(TARGET_OUT)/vendor/operator/app)
这个方式会拷贝APK到out目录,但是刷机后系统里面没有这两个APK
3、但是将APK预装不可卸载的时候,系统刷机里面有这两个APK。。。。。
4、apk是可以手动安装到机器中。。。
——————————————————————————
下面是解决办法:
后面会有一个脚本,是拷贝预置的应用到out指定目录下,注意一点的是:
在编译Android的根目录创建文件夹preinstall,把要预装的apk放在preinstall,一定要编译完成后执行脚本copy_preinstall_app.sh,然后再执行打包./mkimage和update.img
不同的项目、平台生成的out路径不一样,所以copy_preinstall_app.sh需要修改out相关路径
PRODUCT=rk3288
TARGET_OUT=out/target/product/$PRODUCT
copy_preinstall_app.sh文件可以下载https://download.csdn.net/download/m1126125223/10827985
+++ b/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -239,9 +239,11 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
+import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
@@ -1798,6 +1800,29 @@ public class PackageManagerService extends IPackageManager.Stub {
displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
}
+ //lpz add preinstall 2017.10.14
+ /*
+ public void copyFile(File sourceFile, File destFile) throws IOException {
+ FileInputStream inBuff = null;
+ FileOutputStream outBuff = null;
+ try{
+ inBuff = new FileInputStream(sourceFile);
+ outBuff = new FileOutputStream(destFile);
+ byte[] btBuff = new byte[1024];
+ int len;
+ while((len = inBuff.read(btBuff))>0){
+ outBuff.write(btBuff, 0, len);
+ }
+ }finally{
+ if(inBuff != null)
+ inBuff.close();
+ outBuff.flush();
+ if(outBuff !=null)
+ outBuff.close();
+ }
+ }*/
+ //end
+
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
@@ -2181,6 +2206,33 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ //lpz add preinstall 2017.10.14
+ try{
+ File fpreinstalled = new File("/data/pre_installed_ok");
+ File fpreDir = new File("/system/preinstall");
+ File[] fprelist = (new File("/system/preinstall")).listFiles();
+ Runtime runtime = Runtime.getRuntime();
+ if(fpreDir.exists()){
+ if(!fpreinstalled.exists()){
+ int i;
+ String fpreName = null;
+ for(i=0; i<fprelist.length; i++){
+ if(fprelist[i].isFile()){
+ fpreName = mAppInstallDir.getPath() + "/" + fprelist[i].getName();
+ //copyFile(fprelist[i], new File(fpreName));
+ FileUtils.copyFile(fprelist[i], new File(fpreName));
+ runtime.exec("chmod 0644 " + fpreName);
+ fpreName =null;
+ }
+ }
+ fpreinstalled.createNewFile();
+ }
+ }
+ }catch(IOException e)
+ {
+ e.printStackTrace();
+ }
+ //end
//look for any incomplete package installations
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
//clean up list