diff --git a/app/build.gradle b/app/build.gradle index 80c9c4f..c156633 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { applicationId "com.appstore.uiui" minSdkVersion 23 targetSdkVersion 29 - versionCode 22 - versionName "1.2.2" + versionCode 24 + versionName "1.2.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" //极光 ndk { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f364df4..1d35425 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,7 +71,8 @@ + android:exported="true" + android:permission="com.example.broadcast.permission"> @@ -205,7 +206,10 @@ - + + diff --git a/app/src/main/java/com/appstore/uiui/MyApplication.java b/app/src/main/java/com/appstore/uiui/MyApplication.java index 80ae6be..33fe0cb 100644 --- a/app/src/main/java/com/appstore/uiui/MyApplication.java +++ b/app/src/main/java/com/appstore/uiui/MyApplication.java @@ -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"); diff --git a/app/src/main/java/com/appstore/uiui/activity/DetailsActivity.java b/app/src/main/java/com/appstore/uiui/activity/DetailsActivity.java index d541251..6376cbf 100644 --- a/app/src/main/java/com/appstore/uiui/activity/DetailsActivity.java +++ b/app/src/main/java/com/appstore/uiui/activity/DetailsActivity.java @@ -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(); } diff --git a/app/src/main/java/com/appstore/uiui/activity/MainActivity.java b/app/src/main/java/com/appstore/uiui/activity/MainActivity.java index b90f9d5..b3c90d4 100644 --- a/app/src/main/java/com/appstore/uiui/activity/MainActivity.java +++ b/app/src/main/java/com/appstore/uiui/activity/MainActivity.java @@ -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"); diff --git a/app/src/main/java/com/appstore/uiui/adapter/AppAdapter.java b/app/src/main/java/com/appstore/uiui/adapter/AppAdapter.java index c9ebc7b..90e1b05 100644 --- a/app/src/main/java/com/appstore/uiui/adapter/AppAdapter.java +++ b/app/src/main/java/com/appstore/uiui/adapter/AppAdapter.java @@ -267,7 +267,7 @@ public class AppAdapter extends RecyclerView.Adapter { new Thread(new Runnable() { @Override public void run() { - ApkUtils.installApkInSilence(mContext, file.getAbsolutePath()); + ApkUtils.installApp(mContext, file.getAbsolutePath()); } }).start(); } diff --git a/app/src/main/java/com/appstore/uiui/adapter/LocalAppAdapter.java b/app/src/main/java/com/appstore/uiui/adapter/LocalAppAdapter.java index 5dd3034..1d7d717 100644 --- a/app/src/main/java/com/appstore/uiui/adapter/LocalAppAdapter.java +++ b/app/src/main/java/com/appstore/uiui/adapter/LocalAppAdapter.java @@ -65,7 +65,7 @@ public class LocalAppAdapter extends RecyclerView.Adapterpost(Url.GET_INFO_FROMESN) + .params("sn", Utils.getSerial()) + .execute(new StringCallback() { + @Override + public void onSuccess(Response 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 response) { + super.onError(response); + Log.e("onError", response.getException().toString()); + + } + }); + } synchronized public static void getAllAppPackageName(final Handler handler) { - OkGo.get(Url.GET_ALL_PACKAGENAME).execute(new StringCallback() { + OkGo.post(Url.GET_ALL_PACKAGENAME) + .params("sn", Utils.getSerial()) + .execute(new StringCallback() { @Override public void onSuccess(Response response) { String s = response.body(); diff --git a/app/src/main/java/com/appstore/uiui/network/URLs/Url.java b/app/src/main/java/com/appstore/uiui/network/URLs/Url.java index 3b138c2..1584c85 100644 --- a/app/src/main/java/com/appstore/uiui/network/URLs/Url.java +++ b/app/src/main/java/com/appstore/uiui/network/URLs/Url.java @@ -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"; //获取应用分类 diff --git a/app/src/main/java/com/appstore/uiui/receiver/InstallResultReceiver.java b/app/src/main/java/com/appstore/uiui/receiver/InstallResultReceiver.java new file mode 100644 index 0000000..7422a8c --- /dev/null +++ b/app/src/main/java/com/appstore/uiui/receiver/InstallResultReceiver.java @@ -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 ks = extras.keySet(); +// Iterator 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 + "安装成功"); + } + } +} diff --git a/app/src/main/java/com/appstore/uiui/service/GuardService.java b/app/src/main/java/com/appstore/uiui/service/GuardService.java index f471fcc..fabd765 100644 --- a/app/src/main/java/com/appstore/uiui/service/GuardService.java +++ b/app/src/main/java/com/appstore/uiui/service/GuardService.java @@ -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(); } diff --git a/app/src/main/java/com/appstore/uiui/utils/ApkUtils.java b/app/src/main/java/com/appstore/uiui/utils/ApkUtils.java index 3ae72f7..ad66c43 100644 --- a/app/src/main/java/com/appstore/uiui/utils/ApkUtils.java +++ b/app/src/main/java/com/appstore/uiui/utils/ApkUtils.java @@ -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;