update:2020.10.21

fix:安装卸载功能兼容安卓10
add:
This commit is contained in:
2020-10-21 18:49:52 +08:00
parent 08d8c0bef4
commit 446de37ef5
13 changed files with 292 additions and 38 deletions

View File

@@ -71,7 +71,8 @@
<receiver
android:name=".receiver.AppManagerReceiver"
android:enabled="true"
android:exported="true">
android:exported="true"
android:permission="com.example.broadcast.permission">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
@@ -205,7 +206,10 @@
<category android:name="com.appstore.uiui" />
</intent-filter>
</receiver> <!-- Required . Enable it you can get statistics data with channel -->
</receiver>
<receiver android:name=".receiver.InstallResultReceiver"
android:enabled="true"
android:exported="true"/> <!-- Required . Enable it you can get statistics data with channel -->
<meta-data
android:name="JPUSH_CHANNEL"
android:value="developer-default" />

View File

@@ -2,6 +2,8 @@ package com.appstore.uiui;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
@@ -12,6 +14,7 @@ import androidx.annotation.NonNull;
import com.appstore.uiui.jpush.Logger;
import com.appstore.uiui.network.OKGO;
import com.appstore.uiui.receiver.AppManagerReceiver;
import com.appstore.uiui.utils.ApkUtils;
import com.appstore.uiui.utils.LogUtils;
import com.appstore.uiui.utils.SPUtils;
@@ -99,9 +102,23 @@ public class MyApplication extends Application {
// .setFontAttrId(R.attr.fontPath)
// .build()
// );
registAppReceive();
}
private AppManagerReceiver mAppManagerReceiver;
private void registAppReceive() {
mAppManagerReceiver = new AppManagerReceiver();
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
registerReceiver(mAppManagerReceiver, filter);
}
public boolean isDebug(Context context) {
boolean isDebug = context.getApplicationInfo() != null &&
(context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
@@ -372,7 +389,7 @@ public class MyApplication extends Application {
new Thread(new Runnable() {
@Override
public void run() {
ApkUtils.installApkInSilence(app.getAppContext(), response.body().getAbsolutePath());
ApkUtils.installApp(app.getAppContext(), response.body().getAbsolutePath());
}
}).start();
LogUtils.e("onSuccess", "download file successful,now installing");

View File

@@ -198,7 +198,7 @@ public class DetailsActivity extends BaseActivity {
new Thread(new Runnable() {
@Override
public void run() {
ApkUtils.installApkInSilence(DetailsActivity.this, file.getAbsolutePath());
ApkUtils.installApp(DetailsActivity.this, file.getAbsolutePath());
}
}).start();
}

View File

@@ -416,7 +416,7 @@ public class MainActivity extends BaseActivity {
new Thread(new Runnable() {
@Override
public void run() {
ApkUtils.installApkInSilence(MainActivity.this, response.body().getAbsolutePath());
ApkUtils.installApp(MainActivity.this, response.body().getAbsolutePath());
}
}).start();
LogUtils.e("getFile", "download file successful,now installing");

View File

@@ -267,7 +267,7 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.Holder> {
new Thread(new Runnable() {
@Override
public void run() {
ApkUtils.installApkInSilence(mContext, file.getAbsolutePath());
ApkUtils.installApp(mContext, file.getAbsolutePath());
}
}).start();
}

View File

@@ -65,7 +65,7 @@ public class LocalAppAdapter extends RecyclerView.Adapter<LocalAppAdapter.LocalA
holder.btnDownLoad.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ApkUtils.uninstall(context, localApp.getPackageName());
ApkUtils.uninstallApp(context, localApp.getPackageName());
}
});
String totalLength = Formatter.formatFileSize(context, localApp.getSize());

View File

@@ -186,7 +186,7 @@ public class UpdateAppAdapter extends RecyclerView.Adapter<UpdateAppAdapter.Upda
new Thread(new Runnable() {
@Override
public void run() {
ApkUtils.installApkInSilence(context,file.getAbsolutePath() );
ApkUtils.installApp(context,file.getAbsolutePath() );
}
}).start();
}

View File

@@ -27,6 +27,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import okhttp3.internal.Util;
public class OKGO {
private static final int GET_ALL_APPINFO = 0;
@@ -89,9 +91,48 @@ public class OKGO {
}
});
}
public static synchronized void checkDevicesInfo(final Context context) {
OkGo.<String>post(Url.GET_INFO_FROMESN)
.params("sn", Utils.getSerial())
.execute(new StringCallback() {
@Override
public void onSuccess(Response<String> response) {
Log.e("onSuccess", "checkDevicesInfo");
try {
JSONObject bodyObject = JSON.parseObject(response.body());
Integer code = (bodyObject.getInteger("code"));
String msg = bodyObject.getString("msg");
String data = bodyObject.getString("data");
UserInfo userInfo = JSON.parseObject(data, UserInfo.class);
if (code == 200) {
SPUtils.put(context, "isLogined", 1);
SPUtils.put(context, "member_id", userInfo.getMember_id());
SPUtils.put(context, "sn_id", userInfo.getId());
} else if (code == -200) {
SPUtils.put(context, "isLogined", 0);
} else if (code == -250) {
SPUtils.put(context, "isLogined", 2);
//设备验证
}
} catch (Exception ex) {
Log.e("checkDevicesInfo", ex.getMessage());
}
}
@Override
public void onError(Response<String> response) {
super.onError(response);
Log.e("onError", response.getException().toString());
}
});
}
synchronized public static void getAllAppPackageName(final Handler handler) {
OkGo.<String>get(Url.GET_ALL_PACKAGENAME).execute(new StringCallback() {
OkGo.<String>post(Url.GET_ALL_PACKAGENAME)
.params("sn", Utils.getSerial())
.execute(new StringCallback() {
@Override
public void onSuccess(Response<String> response) {
String s = response.body();

View File

@@ -21,7 +21,7 @@ public class Url {
//根据包名获取更新
public final static String GET_BANNER_IMG = NETWORK_HOME_ADDRESS + "Slideshow/getImg";
//获取banner图
public final static String GET_ALL_PACKAGENAME = NETWORK_HOME_ADDRESS + "App/allPackage";
public final static String GET_ALL_PACKAGENAME = NETWORK_HOME_ADDRESS + "App/allPackageSn";
//获取所有应用包名
public final static String GET_SUBClASSFY = NETWORK_HOME_ADDRESS + "Application/getSubClassfy";
//获取应用分类

View File

@@ -0,0 +1,60 @@
package com.appstore.uiui.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInstaller;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.appstore.uiui.utils.ToastUtil;
public class InstallResultReceiver extends BroadcastReceiver {
private static final String TAG = "InstallResultReceiver";
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
//throw new UnsupportedOperationException("Not yet implemented");
if (intent != null) {
final int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);
if (status == PackageInstaller.STATUS_SUCCESS) {
// success
String PACKAGE_NAME = intent.getStringExtra("android.content.pm.extra.PACKAGE_NAME");
Log.e(TAG, "APP Install Success!");
} else {
String msg = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
}
}
// String s = intent.getAction();
// Log.e("fht", s);
// Bundle extras = intent.getExtras();
// Set<String> ks = extras.keySet();
// Iterator<String> iterator = ks.iterator();
// while (iterator.hasNext()) {
// Log.d("KEY", iterator.next());
// }
String STATUS = intent.getStringExtra(PackageInstaller.EXTRA_STATUS);
String PACKAGE_NAME = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME);
String SESSION_ID = intent.getStringExtra(PackageInstaller.EXTRA_SESSION_ID);
String STATUS_MESSAGE = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
String LEGACY_STATUS = intent.getStringExtra("android.content.pm.extra.LEGACY_STATUS");
// Log.e("fht", STATUS);
// Log.e("fht", PACKAGE_NAME);
// Log.e("fht", SESSION_ID);
// Log.e("fht", LEGACY_STATUS);
// Log.e("fht", STATUS_MESSAGE);
if (STATUS_MESSAGE != null && STATUS_MESSAGE.equals("INSTALL_SUCCEEDED")) {
ToastUtil.show(PACKAGE_NAME + "安装成功");
}
}
}

View File

@@ -119,7 +119,7 @@ public class GuardService extends Service {
case 201:
String apppackage = (String) msg.obj;
Log.e("fht", Settings.System.getString(getContentResolver(), "qch_app_forbid") + "?");
if (Settings.System.putString(getContentResolver(), "qch_app_forbid", apppackage)) {
if (Settings.System.putString(getContentResolver(), "qch_app_forbid", apppackage+ "com.info.sn,com.android.uiuios,com.appstore.uiui,com.uiuios.updatetools")) {
Log.e("fht", "app package write successful");
}
break;
@@ -138,7 +138,7 @@ public class GuardService extends Service {
new Thread(new Runnable() {
@Override
public void run() {
ApkUtils.installApkInSilence(GuardService.this, response.body().getAbsolutePath());
ApkUtils.installApp(GuardService.this, response.body().getAbsolutePath());
}
}).start();
LogUtils.e("getFile", "download file successful,now installing");
@@ -173,12 +173,12 @@ public class GuardService extends Service {
LogUtils.e("mjsheng", "downloadPath::" + downloadPath);
LogUtils.e("mjsheng", "extendField::" + packageName);
if (packageName.equalsIgnoreCase(this.getPackageName())) {
ApkUtils.install(this, new File(downloadPath));
ApkUtils.installApp(this,downloadPath);
} else {
new Thread(new Runnable() {
@Override
public void run() {
ApkUtils.installApkInSilence(GuardService.this, downloadPath);
ApkUtils.installApp(GuardService.this, downloadPath);
}
}).start();
}

View File

@@ -1,9 +1,11 @@
package com.appstore.uiui.utils;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
@@ -12,16 +14,20 @@ import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.core.content.FileProvider;
import com.appstore.uiui.BuildConfig;
import com.appstore.uiui.R;
import com.appstore.uiui.receiver.InstallResultReceiver;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -111,15 +117,17 @@ public class ApkUtils {
}
/**
* 卸载一个app
* 根据包名卸载应用
*
* @param packageName
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static void uninstall(Context context, String packageName) {
//通过程序的包名创建URI
Uri packageURI = Uri.parse("package:" + packageName);
//创建Intent意图
Intent intent = new Intent(Intent.ACTION_DELETE, packageURI);
//执行卸载程序
context.startActivity(intent);
Intent broadcastIntent = new Intent(context, InstallResultReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1,
broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
packageInstaller.uninstall(packageName, pendingIntent.getIntentSender());
}
/**
@@ -294,20 +302,136 @@ public class ApkUtils {
});
}
// public static void installApp(final String path, final String packageNames){
// File apkFile = new File(path);
// try {
// Class<?> clazz = Class.forName("android.os.ServiceManager");
// Method method_getService = clazz.getMethod("getService", String.class);
// IBinder bind = (IBinder) method_getService.invoke(null, "package");
// IPackageManager iPm = IPackageManager.Stub.asInterface(bind);
// iPm.installPackage(Uri.fromFile(apkFile),null, 2, apkFile.getName());
// Log.e("fanhuitong", "安装成功");
// } catch (Exception e) {
// e.printStackTrace();
// Log.e("fanhuitong", "安装失败");
// }
// }
public static void installApp(Context context, String filePath) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
installAppatPie(context, filePath);
} else {
installApps(filePath);
}
}
public static boolean installApps(String apkPath) {
ToastUtil.show("正在安装应用...");
Process process = null;
BufferedReader successResult = null;
BufferedReader errorResult = null;
StringBuilder successMsg = new StringBuilder();
StringBuilder errorMsg = new StringBuilder();
try {
process = new ProcessBuilder("pm", "install", "-i", BuildConfig.APPLICATION_ID, "--user", "0", apkPath).start();
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s;
while ((s = successResult.readLine()) != null) {
successMsg.append(s);
}
while ((s = errorResult.readLine()) != null) {
errorMsg.append(s);
}
} catch (Exception e) {
Log.e("installApps1", e.getMessage());
} finally {
try {
if (successResult != null) {
successResult.close();
}
if (errorResult != null) {
errorResult.close();
}
} catch (Exception e) {
Log.e("installApps2", e.getMessage());
}
if (process != null) {
process.destroy();
}
}
Log.e("result", "" + errorMsg.toString());
//如果含有“success”认为安装成功
Log.e("installApp", successMsg.toString());
// if (!successMsg.toString().equalsIgnoreCase("success")) {
// ApkUtils.install(context, new File(apkPath));
// }
return successMsg.toString().equalsIgnoreCase("success");
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static void installAppatPie(Context context, String apkFilePath) {
File file = new File(apkFilePath);
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller
.SessionParams.MODE_FULL_INSTALL);
sessionParams.setSize(file.length());
int sessionId = createSession(packageInstaller, sessionParams);
if (sessionId != -1) {
boolean copySuccess = copyApkFile(packageInstaller, sessionId, apkFilePath);
if (copySuccess) {
ToastUtil.show("正在安装应用");
install(packageInstaller, sessionId, context);
}
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private static void install(PackageInstaller packageInstaller, int sessionId, Context context) {
try {
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
Intent intent = new Intent(context, InstallResultReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
1, intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
session.commit(pendingIntent.getIntentSender());
} catch (IOException e) {
e.printStackTrace();
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private static int createSession(PackageInstaller packageInstaller, PackageInstaller.SessionParams sessionParams) {
int sessionId = -1;
try {
sessionId = packageInstaller.createSession(sessionParams);
} catch (IOException e) {
e.printStackTrace();
}
return sessionId;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private static boolean copyApkFile(PackageInstaller pi, int sessionId, String apkFilePath) {
boolean success = false;
File apkFile = new File(apkFilePath);
PackageInstaller.Session session = null;
try {
session = pi.openSession(sessionId);
OutputStream out = session.openWrite("app.apk", 0, apkFile.length());
FileInputStream input = new FileInputStream(apkFile);
int read = 0;
byte[] buffer = new byte[65536];
// while (read != -1) {
// read = input.read(buffer);
// out.write(buffer, 0, read);
// }
while (true) {
read = input.read(buffer);
if (read == -1) {
session.fsync(out);
success = true;
out.close();
input.close();
break;
}
out.write(buffer, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
Log.e("fht", "copyApkFile" + e.getMessage());
}
return success;
}
//使用系统签名
// public static void installApkInSilence(String installPath, String packageName) {
@@ -378,6 +502,14 @@ public class ApkUtils {
return successMsg.toString().equalsIgnoreCase("success");
}
public static void uninstallApp(Context context, String packageName) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ApkUtils.uninstall(context, packageName);
} else {
ApkUtils.deleteApkInSilence(packageName);
}
}
public static void deleteApkInSilence(String packageName) {
Class<?> pmService;
Class<?> activityTherad;