Commit fc7bd62d by wjg

add update

parent d17da868
...@@ -73,4 +73,5 @@ dependencies { ...@@ -73,4 +73,5 @@ dependencies {
implementation 'com.umeng.umsdk:asms:1.6.3'// asms包依赖(必选) implementation 'com.umeng.umsdk:asms:1.6.3'// asms包依赖(必选)
implementation 'com.umeng.umsdk:apm:1.6.2'// U-APM产品包依赖(必选) implementation 'com.umeng.umsdk:apm:1.6.2'// U-APM产品包依赖(必选)
implementation 'io.socket:socket.io-client:1.0.0' implementation 'io.socket:socket.io-client:1.0.0'
implementation 'com.blankj:utilcode:1.28.6'
} }
\ No newline at end of file
...@@ -15,12 +15,19 @@ ...@@ -15,12 +15,19 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions" />
<application <application
android:name=".HLApplication" android:name=".HLApplication"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/hooloo_launcher" android:icon="@mipmap/hooloo_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:sharedUserId="android.uid.system"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
tools:replace="android:allowBackup,android:icon"> tools:replace="android:allowBackup,android:icon">
...@@ -34,9 +41,9 @@ ...@@ -34,9 +41,9 @@
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
<!-- <category android:name="android.intent.category.HOME" />--> <!-- <category android:name="android.intent.category.HOME" />-->
<!-- <category android:name="android.intent.category.DEFAULT" />--> <!-- <category android:name="android.intent.category.DEFAULT" />-->
<!-- <category android:name="android.intent.category.MONKEY" />--> <!-- <category android:name="android.intent.category.MONKEY" />-->
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
......
package com.ihaoin.hooloo.device.component;
import android.annotation.SuppressLint;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import androidx.annotation.NonNull;
import com.ihaoin.hooloo.device.HLApplication;
import com.ihaoin.hooloo.device.data.vo.CheckUpdateVo;
import com.ihaoin.hooloo.device.network.HttpUtil;
import com.ihaoin.hooloo.device.util.ApkUtils;
import com.ihaoin.hooloo.device.util.Utils;
import java.io.File;
@SuppressLint("HandlerLeak")
public class UpdateService extends Thread {
@Override
public void run() {
checkUpdate();
// while (true) {
// try {
// if (System.currentTimeMillis() / 1000 % 60 == 0) {
// Utils.i("check");
// }
// checkUpdate();
// Thread.sleep(1000);
// } catch (Exception e) {
// e.printStackTrace();
// Utils.i("check update error");
// }
// }
}
private void checkUpdate() {
HttpUtil.checkUpdate(checkUpdateHandler);
}
private Handler checkUpdateHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
try {
CheckUpdateVo updateVo = new CheckUpdateVo();
updateVo.setUrl("https://testapi.pecktoy.com/files/upload_test/app-debug.apk");
updateVo.setVersion("1.0.1");
updateVo.setVersionCode(3);
// Object obj = msg.obj;
// if (msg.what == 0 || obj == null) {
// Utils.i("check update error");
// return;
// }
// CheckUpdateVo updateVo = JsonUtils.readValue(obj, CheckUpdateVo.class);
// if (updateVo.getVersionCode() <= 0) {
// Utils.i("version code is 0");
// return;
// }
// if (StringUtils.isEmpty(updateVo.getUrl())) {
// Utils.i("url is null");
// return;
// }
// if (StringUtils.isEmpty(updateVo.getVersion())) {
// Utils.i("version name is null");
// return;
// }
//
// PackageInfo packageInfo = Utils.getPackageInfo();
// if (updateVo.getVersionCode() <= packageInfo.versionCode) {
// Utils.i(String.format("dont update, current: %s, update: %s", packageInfo.versionCode, updateVo.getVersionCode()));
// return;
// }
startDownload(updateVo);
} catch (Exception e) {
e.printStackTrace();
Utils.i("check update error");
}
}
};
private void startDownload(CheckUpdateVo updateVo) {
String filename = "hooloo-device_" + updateVo.getVersion() + "_" + updateVo.getVersionCode() + ".apk";
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/hooloo";
if (!new File(path).exists()) {
new File(path).mkdirs();
}
String file = path + "/" + filename;
Utils.i("start download file: " + file);
HttpUtil.download(updateVo.getUrl(), file, downloadHandler);
}
private Handler downloadHandler = new Handler() {
@Override
public void dispatchMessage(@NonNull Message msg) {
try {
Object obj = msg.obj;
if (msg.what == 0 || obj == null) {
Utils.i("download file error");
return;
}
ApkUtils.install(HLApplication.SELF, obj.toString());
} catch (Exception e) {
e.printStackTrace();
Utils.i("download file error");
}
}
};
}
package com.ihaoin.hooloo.device.data.po;
import java.io.Serializable;
public class CheckUpdate implements Serializable {
private String machineCode;
private Integer versionCode;
private String versionName;
public String getMachineCode() {
return machineCode;
}
public void setMachineCode(String machineCode) {
this.machineCode = machineCode;
}
public Integer getVersionCode() {
return versionCode;
}
public void setVersionCode(Integer versionCode) {
this.versionCode = versionCode;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
}
package com.ihaoin.hooloo.device.data.vo;
import java.io.Serializable;
public class CheckUpdateVo implements Serializable {
private String url;
private Integer versionCode;
private String version;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Integer getVersionCode() {
return versionCode;
}
public void setVersionCode(Integer versionCode) {
this.versionCode = versionCode;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
...@@ -13,4 +13,6 @@ public class HttpParams { ...@@ -13,4 +13,6 @@ public class HttpParams {
public static final String POST_CONFIRM_ORDER = AppConfig.HOST + "/application/saveData?machineCode=%s"; public static final String POST_CONFIRM_ORDER = AppConfig.HOST + "/application/saveData?machineCode=%s";
/** 保存推送ID */ /** 保存推送ID */
public static final String POST_REGISTRATION_ID = AppConfig.HOST + "/application/jgRegister?machineCode=%s&registerId=%s"; public static final String POST_REGISTRATION_ID = AppConfig.HOST + "/application/jgRegister?machineCode=%s&registerId=%s";
/** 检查更新 */
public static final String POST_CHECK_UPDATE = "https://brain.ihaoin.com/mc/upgrade";
} }
...@@ -6,10 +6,12 @@ import android.os.Message; ...@@ -6,10 +6,12 @@ import android.os.Message;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.ihaoin.hooloo.device.config.AppConfig; import com.ihaoin.hooloo.device.config.AppConfig;
import com.ihaoin.hooloo.device.data.po.CheckUpdate;
import com.ihaoin.hooloo.device.util.JsonUtils; import com.ihaoin.hooloo.device.util.JsonUtils;
import com.ihaoin.hooloo.device.util.StringUtils; import com.ihaoin.hooloo.device.util.StringUtils;
import com.ihaoin.hooloo.device.util.Utils; import com.ihaoin.hooloo.device.util.Utils;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import okhttp3.Call; import okhttp3.Call;
...@@ -19,8 +21,50 @@ import okhttp3.OkHttpClient; ...@@ -19,8 +21,50 @@ import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import okio.BufferedSink;
import okio.Okio;
import okio.Sink;
public class HttpUtil { public class HttpUtil {
public static void download(String url, String path, Handler handler) {
final long startTime = System.currentTimeMillis();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
HttpUtil.onFailure(handler, call, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Sink sink = null;
BufferedSink buffered = null;
try {
sink = Okio.sink(new File(path));
buffered = Okio.buffer(sink);
buffered.writeAll(response.body().source());
buffered.close();
buffered = null;
Utils.i("download success");
Utils.i("download totalTime=" + (System.currentTimeMillis() - startTime));
sendHandlerMessage(1, handler, call, path);
} catch (Exception e) {
e.printStackTrace();
Utils.i("download failed");
} finally {
if (buffered != null) {
buffered.close();
}
if (sink != null) {
sink.close();
}
}
}
});
}
public static void post(String url, String body, Handler handler) { public static void post(String url, String body, Handler handler) {
if (body == null) { if (body == null) {
body = ""; body = "";
...@@ -134,6 +178,14 @@ public class HttpUtil { ...@@ -134,6 +178,14 @@ public class HttpUtil {
get(url, handler); get(url, handler);
} }
public static void checkUpdate(Handler handler) {
CheckUpdate checkUpdate = new CheckUpdate();
checkUpdate.setMachineCode(AppConfig.MACHINE_CODE);
checkUpdate.setVersionCode(Utils.getPackageInfo().versionCode);
checkUpdate.setVersionName(Utils.getPackageInfo().versionName);
post(HttpParams.POST_CHECK_UPDATE, JsonUtils.toString(checkUpdate), handler);
}
// public static String getMacAddress() { // public static String getMacAddress() {
// try { // try {
// List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces()); // List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
......
package com.ihaoin.hooloo.device.util;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.TextUtils;
import androidx.annotation.RequiresPermission;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.ShellUtils;
import java.io.File;
import java.util.Locale;
public class ApkUtils {
private static final String TAG = "ApkUtils";
// private static final String SP_NAME_PACKAGE_INSTALL_RESULT = "package_install_result";
// private static volatile Method sInstallPackage;
// private static volatile Method sDeletePackage;
// private static volatile SharedPreferences sPreferences;
/**
* 静默安装
* 会依次调用Stream-->反射-->Shell
*
* @param apkFile APK文件
* @return 成功或失败
*/
@SuppressLint("PackageManagerGetSignatures")
@RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
public static synchronized boolean install(Context context, String apkFile) {
File file;
if (TextUtils.isEmpty(apkFile) || !(file = new File(apkFile)).exists())
return false;
//加上apk合法性判断
AppUtils.AppInfo apkInfo = AppUtils.getApkInfo(file);
if (apkInfo == null || TextUtils.isEmpty(apkInfo.getPackageName())) {
Utils.i(TAG, "apk info is null, the file maybe damaged: " + file.getAbsolutePath());
return false;
}
//加上本地apk版本判断
AppUtils.AppInfo appInfo = AppUtils.getAppInfo(apkInfo.getPackageName());
if (appInfo != null) {
// //已安装的版本比apk版本要高, 则不需要安装
// if (appInfo.getVersionCode() >= apkInfo.getVersionCode()) {
// Utils.i(TAG, "The latest version has been installed locally: " + file.getAbsolutePath() +
// ", app info: packageName: " + appInfo.getPackageName() + "; app name: " + appInfo.getName() +
// ", apk version code: " + apkInfo.getVersionCode() +
// ", app version code: " + appInfo.getVersionCode());
// return true;
// }
//已安装的版本比apk要低, 则需要进一步校验签名和ShellUID
PackageManager pm = context.getPackageManager();
try {
PackageInfo appPackageInfo, apkPackageInfo;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
appPackageInfo = pm.getPackageInfo(appInfo.getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES);
apkPackageInfo = pm.getPackageArchiveInfo(file.getAbsolutePath(), PackageManager.GET_SIGNING_CERTIFICATES);
} else {
appPackageInfo = pm.getPackageInfo(appInfo.getPackageName(), PackageManager.GET_SIGNATURES);
apkPackageInfo = pm.getPackageArchiveInfo(file.getAbsolutePath(), PackageManager.GET_SIGNATURES);
}
if (appPackageInfo != null && apkPackageInfo != null &&
!compareSharedUserId(appPackageInfo.sharedUserId, apkPackageInfo.sharedUserId)) {
Utils.i(TAG, "Apk sharedUserId is not match, app shellUid: " + appPackageInfo.sharedUserId + ", apk shellUid: " + apkPackageInfo.sharedUserId);
return false;
}
} catch (Throwable ignored) {
}
}
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// //由于调用PackageInstaller安装失败的情况下, 重复安装会导致内存占用无限增长的问题.
// //所以在安装之前需要判断当前包名是否有过失败记录, 如果以前有过失败记录, 则不能再使用该方法进行安装
// if (sPreferences == null) {
// sPreferences = context.getSharedPreferences(SP_NAME_PACKAGE_INSTALL_RESULT, Context.MODE_PRIVATE);
// }
// String packageName = apkInfo.getPackageName();
// boolean canInstall = sPreferences.getBoolean(packageName, true);
// if (canInstall) {
// boolean success = installByPackageInstaller(context, file, apkInfo);
// sPreferences.edit().putBoolean(packageName, success).apply();
// if (success) {
// Utils.i(TAG, "Install Success[PackageInstaller]: " + file.getAbsolutePath());
// return true;
// }
// }
// }
//
// if (installByReflect(context, file)) {
// if (sPreferences != null)
// sPreferences.edit().putBoolean(apkInfo.getPackageName(), true).apply();
// Utils.i(TAG, "Install Success[Reflect]", file.getPath());
// return true;
// }
if (installByShell(file, DeviceUtils.isDeviceRooted())) {
// if (sPreferences != null)
// sPreferences.edit().putBoolean(apkInfo.getPackageName(), true).apply();
Utils.i(TAG, "Install Success[Shell]: " + file.getPath());
return true;
}
Utils.i(TAG, "Install Failure: " + file.getAbsolutePath());
return false;
}
// /**
// * 卸载
// * PackageInstaller-->反射-->Shell
// */
// @RequiresPermission(Manifest.permission.DELETE_PACKAGES)
// public static synchronized boolean uninstall(Context context, String packageName) {
// if (TextUtils.isEmpty(packageName))
// return false;
//
// //如果未安装, 直接返回成功即可
// if (!AppUtils.isAppInstalled(packageName))
// return true;
//
// //如果是系统app, 则不支持卸载
// AppUtils.AppInfo appInfo = AppUtils.getAppInfo(packageName);
// if (appInfo != null && appInfo.isSystem()) {
// Utils.i(TAG, "Uninstall Failure[System App]: " + packageName);
// return false;
// }
//
// context = context.getApplicationContext();
// try {
//
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// if (uninstallByPackageInstaller(context, packageName)) {
// Utils.i(TAG, "Uninstall Success[PackageInstaller]: " + packageName);
// return true;
// }
// }
//
// if (uninstallByReflect(context, packageName)) {
// Utils.i(TAG, "Uninstall Success[Reflect]: " + packageName);
// return true;
// }
//
// if (uninstallByShell(packageName, DeviceUtils.isDeviceRooted())) {
// Utils.i(TAG, "Uninstall Success[Shell]: " + packageName);
// return true;
// }
//
// } catch (Throwable ignored) {
// }
//
// Utils.i(TAG, "Uninstall Failure: " + packageName);
// return false;
// }
/**
* 通过Shell命令静默安装
*
* @param file apk文件
* @param isRoot 设备是否有root权限,
* 如果没有root权限, 在Android7.0及以上设备需要声明 android:sharedUserId="android.uid.shell"
* Android 9.0 设备可能不支持shell命令安装
* @return 是否安装成功
*/
private static boolean installByShell(File file, boolean isRoot) {
String cmd = "pm install -r '" + file.getAbsolutePath() + "'";
return executeShell(cmd, isRoot) || executeShell(cmd, !isRoot);
}
// private static boolean uninstallByShell(String packageName, boolean isRoot) {
// String cmd = "pm uninstall '" + packageName + "'";
// return executeShell(cmd, isRoot) || executeShell(cmd, !isRoot);
// }
private static boolean executeShell(String cmd, boolean isRoot) {
Utils.i(TAG, "ShellCommand: " + cmd + ", isRoot: " + isRoot);
ShellUtils.CommandResult result = ShellUtils.execCmd(cmd, isRoot);
Utils.i(TAG, "ShellCommand Result: " + result.toString());
return result.successMsg != null && result.successMsg.toLowerCase(Locale.US).contains("success");
}
// /**
// * 调用反射方式安装, 通过PackageManager#installPackage方法进行安装, 该方法在7.0已经移除
// */
// private static boolean installByReflect(Context context, File file) throws InterruptedException {
// Utils.i(TAG, "InstallByReflect: "+ file.getPath());
// Method installer = getInstallPackageMethod();
// if (installer == null)
// return false;
//
// final AtomicBoolean result = new AtomicBoolean(false);
// final CountDownLatch countDownLatch = new CountDownLatch(1);
//
// IPackageInstallObserver observer = new IPackageInstallObserver.Stub() {
// @Override
// public void packageInstalled(String packageName, int returnCode) {
// try {
// result.set(returnCode == 1);
// } finally {
// countDownLatch.countDown();
// }
// }
// };
//
// try {
// installer.invoke(
// context.getPackageManager(),
// UriUtils.file2Uri(file),
// observer,
// 0x00000002,//flag=2表示如果存在则覆盖升级)
// context.getPackageName()
// );
// } catch (IllegalAccessException | InvocationTargetException ignored) {
// countDownLatch.countDown();
// }
//
// countDownLatch.await();
// return result.get();
// }
//
//
// /**
// * 调用反射方式卸载, 通过PackageManager#deletePackage, 该方法在7.0已经移除
// */
// private static boolean uninstallByReflect(Context context, String packageName) throws InterruptedException {
// Utils.i(TAG, "UninstallByReflect", packageName);
// Method deleter = getDeletePackageMethod();
// if (deleter == null)
// return false;
//
// final AtomicBoolean result = new AtomicBoolean(false);
// final CountDownLatch countDownLatch = new CountDownLatch(1);
//
// IPackageDeleteObserver observer = new IPackageDeleteObserver.Stub() {
// @Override
// public void packageDeleted(String packageName, int returnCode) {
// try {
// result.set(returnCode == 1);
// } finally {
// countDownLatch.countDown();
// }
// }
// };
//
// try {
// deleter.invoke(
// context.getPackageManager(),
// packageName, observer, 0x00000002);
// } catch (IllegalAccessException | InvocationTargetException ignored) {
// countDownLatch.countDown();
// }
//
// countDownLatch.await();
// return result.get();
// }
// /**
// * 通过流的形式进行静默安装
// */
// @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
// @RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
// private static boolean installByPackageInstaller(Context context, File file, AppUtils.AppInfo apkInfo) throws InterruptedException {
// Utils.i(TAG, "InstallByPackageInstaller: " + file.getPath());
//
// OutputStream out = null;
// InputStream in = null;
// PackageInstaller.Session session = null;
// int sessionId = -1;
// boolean success = false;
// PackageManager pm = context.getPackageManager();
// PackageInstaller installer = pm.getPackageInstaller();
// try {
//
// //初始化安装参数
// PackageInstaller.SessionParams params =
// new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
// params.setSize(file.length());
// params.setAppIcon(ImageUtils.drawable2Bitmap(apkInfo.getIcon()));
// params.setAppLabel(apkInfo.getName());
// params.setAppPackageName(apkInfo.getPackageName());
// sessionId = installer.createSession(params);
// //sessionId 会返回一个正数非零的值, 如果小于0, 表示会话开启错误
// if (sessionId > 0) {
// InstallReceiver callback = new InstallReceiver(context, true, file.getAbsolutePath());
// session = installer.openSession(sessionId);
// out = session.openWrite(file.getName(), 0, file.length());
// in = new FileInputStream(file);
// int len;
// byte[] buffer = new byte[8192];
// while ((len = in.read(buffer)) != -1) {
// out.write(buffer, 0, len);
// }
// session.fsync(out);
// in.close();
// out.close();
// session.commit(callback.getIntentSender());
// success = callback.isSuccess();
// }
// } catch (InterruptedException e) {
// throw e;
// } catch (Throwable e) {
// e.printStackTrace();
// Utils.i(TAG, e);
// } finally {
// //如果会话已经开启, 但是没有成功, 则需要将会话进行销毁
// try {
// if (sessionId > 0 && !success) {
// if (session != null)
// session.abandon();
// installer.abandonSession(sessionId);
// }
// } catch (Throwable ignored) {
// }
// CloseUtils.closeIOQuietly(in, out, session);
// }
// return success;
// }
//
// @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
// @RequiresPermission(Manifest.permission.DELETE_PACKAGES)
// private static boolean uninstallByPackageInstaller(Context context, String packageName) {
// Utils.i(TAG, "UninstallByPackageInstaller", packageName);
// try {
// InstallReceiver callback = new InstallReceiver(context, false, packageName);
// PackageInstaller installer = Utils.getApp().getPackageManager().getPackageInstaller();
// installer.uninstall(packageName, callback.getIntentSender());
// return callback.isSuccess();
// } catch (Throwable ignored) {
// }
// return false;
// }
//
// @Nullable
// private static Method getInstallPackageMethod() {
// if (sInstallPackage != null)
// return sInstallPackage;
// try {
// //noinspection JavaReflectionMemberAccess
// sInstallPackage = PackageManager.class.getMethod("installPackage",
// Uri.class, IPackageInstallObserver.class, int.class, String.class);
// return sInstallPackage;
// } catch (NoSuchMethodException ignored) {
// }
// return null;
// }
//
// @Nullable
// private static Method getDeletePackageMethod() {
// if (sDeletePackage != null)
// return sDeletePackage;
// try {
// //noinspection JavaReflectionMemberAccess
// sDeletePackage = PackageManager.class.getMethod("deletePackage",
// String.class, IPackageDeleteObserver.class, int.class);
// return sDeletePackage;
// } catch (NoSuchMethodException ignored) {
// }
// return null;
// }
//
// /**
// * 安装/卸载回调广播
// */
// @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
// private static final class InstallReceiver extends BroadcastReceiver {
// private final String ACTION = InstallReceiver.class.getName() + SystemClock.elapsedRealtimeNanos();
// private final Context mContext;
// private final String mOperate;
// private final String mParam;
// /**
// * 用于将异步转同步
// */
// private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
// private boolean mSuccess = false;
//
// private InstallReceiver(Context context, boolean isInstall, String param) {
// this.mContext = context.getApplicationContext();
// this.mOperate = isInstall ? "Install" : "Uninstall";
// this.mParam = param;
// this.mContext.registerReceiver(this, new IntentFilter(ACTION));
// }
//
//
// private boolean isSuccess() throws InterruptedException {
// try {
// //安装最长等待2分钟.
// mCountDownLatch.await(2L, TimeUnit.MINUTES);
// return mSuccess;
// } finally {
// mContext.unregisterReceiver(this);
// }
// }
//
// private IntentSender getIntentSender() {
// return PendingIntent
// .getBroadcast(mContext, ACTION.hashCode(), new Intent(ACTION).setPackage(mContext.getPackageName()),
// PendingIntent.FLAG_UPDATE_CURRENT)
// .getIntentSender();
// }
//
// @Override
// public void onReceive(Context context, Intent intent) {
// try {
// int status = -200;
// if (intent == null) {
// mSuccess = false;
// } else {
// status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE);
// mSuccess = status == PackageInstaller.STATUS_SUCCESS;
// }
// Utils.i(TAG, mParam, mOperate + " Result: " + mSuccess + "[" + status + "]");
// } finally {
// mCountDownLatch.countDown();
// }
// }
// }
private static boolean compareSharedUserId(String appUid, String apkUid) {
return TextUtils.equals(appUid, apkUid) || (appUid != null && appUid.equalsIgnoreCase(apkUid));
}
}
...@@ -3,6 +3,8 @@ package com.ihaoin.hooloo.device.util; ...@@ -3,6 +3,8 @@ package com.ihaoin.hooloo.device.util;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
...@@ -21,6 +23,7 @@ import androidx.coordinatorlayout.widget.ViewGroupUtils; ...@@ -21,6 +23,7 @@ import androidx.coordinatorlayout.widget.ViewGroupUtils;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager; import com.bumptech.glide.RequestManager;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.ihaoin.hooloo.device.HLApplication;
import com.ihaoin.hooloo.device.R; import com.ihaoin.hooloo.device.R;
import com.ihaoin.hooloo.device.component.TouchDelegateComposite; import com.ihaoin.hooloo.device.component.TouchDelegateComposite;
import com.ihaoin.hooloo.device.config.AppConfig; import com.ihaoin.hooloo.device.config.AppConfig;
...@@ -46,6 +49,16 @@ import java.util.Optional; ...@@ -46,6 +49,16 @@ import java.util.Optional;
public class Utils { public class Utils {
public static PackageInfo getPackageInfo() {
PackageInfo packageInfo = null;
try {
packageInfo = HLApplication.SELF.getPackageManager().getPackageInfo(HLApplication.SELF.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return packageInfo;
}
public static void i(String s) { public static void i(String s) {
Utils.i(AppConfig.TAG, s); Utils.i(AppConfig.TAG, s);
} }
......
...@@ -39,6 +39,7 @@ import com.ihaoin.hooloo.device.component.InteractionSocket; ...@@ -39,6 +39,7 @@ import com.ihaoin.hooloo.device.component.InteractionSocket;
import com.ihaoin.hooloo.device.component.KDSSocket; import com.ihaoin.hooloo.device.component.KDSSocket;
import com.ihaoin.hooloo.device.component.NetworkHandler; import com.ihaoin.hooloo.device.component.NetworkHandler;
import com.ihaoin.hooloo.device.component.SettingsQueue; import com.ihaoin.hooloo.device.component.SettingsQueue;
import com.ihaoin.hooloo.device.component.UpdateService;
import com.ihaoin.hooloo.device.config.AppConfig; import com.ihaoin.hooloo.device.config.AppConfig;
import com.ihaoin.hooloo.device.config.Base; import com.ihaoin.hooloo.device.config.Base;
import com.ihaoin.hooloo.device.data.MainData; import com.ihaoin.hooloo.device.data.MainData;
...@@ -114,6 +115,8 @@ public class LauncherActivity extends Activity { ...@@ -114,6 +115,8 @@ public class LauncherActivity extends Activity {
startTimeoutThread(); startTimeoutThread();
getMachineCode(); getMachineCode();
new UpdateService().start();
} }
private void initViews() { private void initViews() {
...@@ -658,7 +661,7 @@ public class LauncherActivity extends Activity { ...@@ -658,7 +661,7 @@ public class LauncherActivity extends Activity {
private void requestPermissions() { private void requestPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100); requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
} }
} }
......
-----BEGIN CERTIFICATE-----
MIID+zCCAuOgAwIBAgIJAP8GQTI8+VUSMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UE
AwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
Fw0xNDEyMjMwNjQzNDFaFw00MjA1MTAwNjQzNDFaMIGUMQswCQYDVQQGEwJVUzET
MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
A1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHQW5kcm9p
ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
hvcNAQEBBQADggENADCCAQgCggEBAKHY8Fl4XZzpJvgHoezYjhmKPvdq9DGYVc/X
9NQO5oUlYIA/Ci5rzvljz13KbNve/KxuEu9HN8SzsLg9EBhghOko8JxEg7I8W6uP
VOoRngNCMvXzjf6av77vxPqphlgq++Y4MIC+fiOxLd+gpYq0p6W7RWxEgrzLHnWi
CX0dRmWDs+ey2t4f1WKzGoRQQS0Tn21CViThrVEe+zNwANnhErUcvoQB2m4/PQot
uij7LZNccHJvUOUf5/4wIZd8JOgO3VLwzFO/HhrqUjafCvkpKTjW8oQmHLUz5m40
ljETGEjqQ6AuAwmaeFT+Bwj1DUaYg+m7AzalJ2aAtHVX0FftRUkCAQOjUDBOMB0G
A1UdDgQWBBQi+LgbyFfWSoWCbQ+NVDF4ZKTPCjAfBgNVHSMEGDAWgBQi+LgbyFfW
SoWCbQ+NVDF4ZKTPCjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBH
1kIQlSBjXRMuQdaDLytr8ZaJXIN1HApg2QA8azYQXOS/B16gwm6tBfh1dL86LL/7
w09oM9LZv8WwtQyFNjM97vvQvkaOGW/ubhrKOk3+8HTHkEx4n7H6tYGOLdpmWepD
fBSEFuLwq6yqG6wZFdd7IKO+sPlCxqUpqg40YAb4WOwzDbiuJnswDftP3wIaaJPh
li6OIjRKyd3Sgw1MtffHOy+WSwqHLkGNgH6GAgvZlvhPA/yim+rjnE9oKV5G6Pyg
QK7kJJjS/LdeqxE7M7pNRYPhcLT7qhE7MiuBuyqwAMTTBoU8u3lTdOZwNErbRT5t
SXkgVMffkfN7wBNqpSSY
-----END CERTIFICATE-----
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment