public class AutoInstallService extends Service {
private final static String TAG = "AutoInstallService" ;
private Object notiObject;
private int countInstalled = 0;
private int apkCount = 0;
private int pathFlag = 0;
IPackageManager mPm;
private PackageInstaller packageInstaller;
private Map installPackageInfo = new HashMap<>();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Log.w(TAG, "onCreate was called.");
packageInstaller = this.getPackageManager().getPackageInstaller();
notiObject = new Object();
mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
new AutoInstallTask().execute();
packageInstaller.registerSessionCallback(new PackageInstaller.SessionCallback() {
@Override
public void onCreated(int sessionId) {
}
@Override
public void onBadgingChanged(int sessionId) {
}
@Override
public void onActiveChanged(int sessionId, boolean active) {
}
@Override
public void onProgressChanged(int sessionId, float progress) {
}
@Override
public void onFinished(int sessionId, boolean success) {
Log.d(TAG, "onFinished sessionId = " + sessionId + ", success = " + success);
Message msg1 = new Message();
msg1.what = 1;
msg1.arg1 = success ? 1:0;
msg1.arg2 = apkCount;
msg1.obj = installPackageInfo.get(sessionId);
MainActivity.handler.sendMessage(msg1);
}
});
}
@Override
public void onDestroy() {
stopForeground(STOP_FOREGROUND_REMOVE);
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// In this sample, we'll use the same text for the ticker and the expanded notification
String text = "installing apks for aging test";
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0);
// Set the info for the views that show in the notification panel.
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher) // the status icon
.setWhen(System.currentTimeMillis()) // the time stamp
.setContentTitle("install aging apks") // the label
.setContentText(text) // the contents of the entry
.setContentIntent(contentIntent) // The intent to send when clicked
.setOngoing(true)
.build();
Log.w(TAG, "onStartCommand was called");
startForeground(131, notification);
return START_NOT_STICKY;
}
private class AutoInstallTask extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... p) {
Log.w(TAG, "doInBackground start auto install.");
instAllApps("/sdcard/agingapk/");
deleteApkFiles("/sdcard/agingapk/");
pathFlag = 1;
instAllApps("/sdcard/aging_3rd_apks/");
Log.w(TAG, "all Installation tasks are dispatched.");
stopSelf();
Message msg_finishInstall = new Message();
msg_finishInstall.what = 2;
MainActivity.handler.sendMessage(msg_finishInstall);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
}
@Override
protected void onPreExecute() {
Log.w(TAG, "onPreExecute called");
super.onPreExecute();
}
@Override
protected void onPostExecute(Integer result) {
Log.w(TAG, "onPreExecute called");
super.onPostExecute(result);
}
}
private void instAllApps(String apkpath) {
Vector<String> allApps = new Vector<String>();
getApkFileName(allApps, apkpath);
for (int i = 0; i < allApps.size(); i++) {
String path = allApps.get(i);
String apkinfo = path.substring(path.lastIndexOf("/")+1);
final PackageInstaller.Session session;
if (path != null) {
File apkFile = new File(path);
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
sessionParams.setSize(apkFile.length());
try {
int sessionId = packageInstaller.createSession(sessionParams);
session = packageInstaller.openSession(sessionId);
installPackageInfo.put(sessionId,apkinfo );
} catch (Exception e) {
continue;
}
try {
try (InputStream in = new FileInputStream(apkFile)) {
long sizeBytes = apkFile.length();
try (OutputStream out = session
.openWrite("PackageInstaller", 0, sizeBytes)) {
byte[] buffer = new byte[1048576];
while (true) {
int numRead = in.read(buffer);
if (numRead == -1) {
session.fsync(out);
break;
}
out.write(buffer, 0, numRead);
}
}
}
} catch (IOException | SecurityException e) {
//Log.e(LOG_TAG, "Could not write package", e);
session.close();
//return null;
continue;
} finally {
}
Intent broadcastIntent = new Intent("com.android.packageinstaller.ACTION_INSTALL_COMMIT");
broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
broadcastIntent.setPackage("com.android.packageinstaller");
broadcastIntent.putExtra("EventResultPersister.EXTRA_ID", -1);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this,
-1,
broadcastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());
session.close();
}
}
if(pathFlag == 1){
apkCount = installPackageInfo.size();
}
}
private void deleteApkFiles(String path) {
final FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".apk");
}
};
try {
for (File file : new File(path).listFiles(filter)) {
file.delete();
}
} catch (Exception e){
e.toString();
}
}
private static void getApkFileName(Vector<String> allAPks, String fileAbsolutePath) {
File file = new File(fileAbsolutePath);
File[] subFile = file.listFiles();
if (null != subFile) {
for (int i = 0; i < subFile.length; i++) {
if (!subFile[i].isDirectory()) {
String filename = subFile[i].getName();
if (filename.trim().toLowerCase().endsWith(".apk")) {
allAPks.add(subFile[i].getAbsolutePath());
}
}
}
}
}
private Class<?>[] getParamTypes(Class<?> cls, String mName) {
Class<?>[] clazz = null;
Method[] mtd = cls.getDeclaredMethods();
for (int i = 0; i < mtd.length; i++) {
if (!mtd[i].getName().equals(mName)) {
continue;
}
clazz = mtd[i].getParameterTypes();
}
return clazz;
}
private final String[] runtimePermissions = new String[]{
"android.permission.READ_CALENDAR",
"android.permission.WRITE_CALENDAR",
"android.permission.CAMERA",
"android.permission.READ_CONTACTS",
"android.permission.WRITE_CONTACTS",
"android.permission.GET_ACCOUNTS",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.RECORD_AUDIO",
"android.permission.READ_PHONE_STATE",
"android.permission.CALL_PHONE",
"android.permission.READ_CALL_LOG",
"android.permission.WRITE_CALL_LOG",
"com.android.voicemail.permission.ADD_VOICEMAIL",
"android.permission.USE_SIP",
"android.permission.PROCESS_OUTGOING_CALLS",
"android.permission.BODY_SENSORS",
"android.permission.SEND_SMS",
"android.permission.RECEIVE_SMS",
"android.permission.READ_SMS",
"android.permission.RECEIVE_WAP_PUSH",
"android.permission.RECEIVE_MMS",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"
};
private void grantRuntimepermission(String packagename) {
Log.d(TAG, "grantRuntimepermission was called : packagename=" + packagename);
final PackageManager packageManager = getPackageManager();
// 获取所有已安装程序的包信息
List<PackageInfo> pinfo = packageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS);
for (int i = 0; i < pinfo.size(); i++) {
if (pinfo.get(i).requestedPermissions != null && packagename.equals(pinfo.get(i).packageName)) {
for (String permissionString : pinfo.get(i).requestedPermissions) {
if (Arrays.asList(runtimePermissions).contains(permissionString)) {
Log.d(TAG, "requestedPermissions: " + permissionString);
try {
mPm.grantRuntimePermission(packagename, permissionString, 0);
} catch (RemoteException e) {
System.err.println(e.toString());
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
}
}
}
}
}
}
}