APK 静默安装参考(亲测)

来源:互联网 发布:xp关闭80端口 编辑:程序博客网 时间:2024/05/18 01:24

1.局限性,必须有系统签名才行(只需要将主的程序系统签名,然后就可以静默安装第三方app,第三方app不需要系统签名)

package com.example.testupdate;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;


import android.content.Context;
import android.content.Intent;


public class InstallerUtils {


public String install(String apkAbsolutePath, Context context) {
String[] args = { "pm", "install", "-r", apkAbsolutePath };
String result = "";
ProcessBuilder processBuilder = new ProcessBuilder(args);
Process process = null;
InputStream errIs = null;
InputStream inIs = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read = -1;
process = processBuilder.start();
errIs = process.getErrorStream();
while ((read = errIs.read()) != -1) {
baos.write(read);
}
baos.write('/' + 'n');
inIs = process.getInputStream();
while ((read = inIs.read()) != -1) {
baos.write(read);
}
byte[] data = baos.toByteArray();
result = new String(data);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (errIs != null) {
errIs.close();
}
if (inIs != null) {
inIs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}
// Intent intent2 = new Intent(
// "android.intent.action.PACKAGE_REPLACED_OVER");
// context.sendBroadcast(intent2);
return result;
}


}



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


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


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.testupdate.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <receiver
            android:name="com.example.testupdate.AppInstallReceiver"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />


                <data android:scheme="package" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.example.testupdate.UpdateOverReceiver"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REPLACED_OVER" />
            </intent-filter>
        </receiver>
    </application>


    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


    <!--
      <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.DELETE_PACKAGES" />
    -->


</manifest>

再activity中并在事件中调用

public void onSlience() {
Thread installThread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
String apkName = "TestUpdate.apk";
String path = Environment.getExternalStorageDirectory() + "/";
InstallerUtils installerUtils = new InstallerUtils();
installerUtils.install(path + apkName, context);
}
});
installThread.start();
}



package com.example.testupdate;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.util.Log;

//安装卸载的系统的系统广播
public class AppInstallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {


PackageManager manager = context.getPackageManager();
if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
String packageName = intent.getData().getSchemeSpecificPart();
Log.e("zdy", "安装成功" + packageName);
}
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
String packageName = intent.getData().getSchemeSpecificPart();
Log.e("zdy", "卸载成功" + packageName);
}
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
String packageName = intent.getData().getSchemeSpecificPart();
Log.e("zdy", "替换成功" + packageName);
Intent intent2 = new Intent(
"android.intent.action.PACKAGE_REPLACED_OVER");
context.sendBroadcast(intent2);//在替换成功后发送广播将自己启动
}


}
}

//安装成功启动广播

package com.example.testupdate;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;


public class UpdateOverReceiver extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent arg1) {
// TODO Auto-generated method stub
Intent intent1 = new Intent(context, MainActivity.class);
// 启动指定Server
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 注意,必须添加这个标记,否则启动会失败
context.startActivity(intent1);
}

}

系统签名:这几个文件是负责源码部分的同事那里拿来的 具体的生成方式不清楚,



然后把上面项目的apk改后缀名为.zip并打开

进入META-INT目录下把多余的文件删除,删完后就是下图所示


删除了回到第一个目录把之前的zip后缀改回apk

打开cmd cd 到系统签名文件所在的目录


然后



java -jar signapk.jar platform.x509.pem platform.pk8 old.apk 项目名称.apk 

这样系统签名完了,

把apk一个丢到sdcard 中,然后安装,运行项目在点击项目里面的安装就可以 实现在后台更新安装程序,更新完成后又启动。。。。 

系统是自己的就不感觉流氓了


0 0
原创粉丝点击