瀏覽代碼

支持U盘更新

lhm 3 年之前
父節點
當前提交
e2328efff5

+ 18 - 1
app/src/main/AndroidManifest.xml

@@ -47,10 +47,17 @@
                 <category android:name="android.intent.category.HOME" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <action android:name="android.intent.action.MAIN" />
-                <action android:name="android.intent.action.PACKAGE_REPLACED"/>
+                <action android:name="android.content.pm.extra.STATUS"/>
                 <action android:name="android.intent.action.PACKAGE_ADDED" />
                 <action android:name="android.intent.action.PACKAGE_REMOVED" />
+                <action android:name="android.intent.action.PACKAGE_REPLACED" />
+                <action android:name="android.intent.action.MEDIA_CHECKING"/>
+                <action android:name="android.intent.action.MEDIA_MOUNTED"/>
+                <action android:name="android.intent.action.MEDIA_SCANNER_STARTED"/>
+                <action android:name="android.intent.action.MEDIA_SCANNER_FINISHED"/>
+                <action android:name="android.intent.action.MEDIA_EJECT"/>
                 <data android:scheme="package"/>
+                <data android:scheme="file"/>
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
@@ -71,6 +78,16 @@
                 <data android:scheme="package" />
             </intent-filter>
         </receiver>
+        <receiver android:name="com.emato.ich.update.USBUpdateReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.MEDIA_CHECKING"/>
+                <action android:name="android.intent.action.MEDIA_MOUNTED"/>
+                <action android:name="android.intent.action.MEDIA_SCANNER_STARTED"/>
+                <action android:name="android.intent.action.MEDIA_SCANNER_FINISHED"/>
+                <action android:name="android.intent.action.MEDIA_EJECT"/>
+                <data android:scheme="file"/>
+            </intent-filter>
+        </receiver>
 <!--        <receiver android:name=".update.InstallResultReceiver">-->
 <!--            <intent-filter>-->
 <!--                <action android:name="MyAction" />-->

+ 65 - 0
app/src/main/java/com/emato/ich/update/PackageManagerCompat.java

@@ -9,6 +9,9 @@ import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Build;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
+
 import com.emato.ich.utils.Log;
 
 import androidx.annotation.NonNull;
@@ -17,6 +20,7 @@ import androidx.annotation.RequiresApi;
 import com.emato.ich.MainActivity;
 import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.StringUtils;
+import com.emato.ich.utils.ToastUtils;
 import com.xuexiang.xupdate.entity.DownloadEntity;
 import com.xuexiang.xupdate.listener.OnInstallListener;
 
@@ -31,6 +35,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -66,6 +73,64 @@ public class PackageManagerCompat implements OnInstallListener {
         }
     }*/
 
+    /**
+     * android 9.0获取外置sdcard和U盘路径,并区分
+     * @param mContext  上下文
+     *  SD = "内部存储"; EXT = "SD卡"; USB = "U盘"
+     * @return apk
+     */
+    public static File getUpdateAPKFile(Context mContext){
+        String targetpath = "";
+        String keyword = "USB";
+
+        StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+
+        Class<?> storageVolumeClazz = null;
+        File file = null;
+        try {
+            storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
+
+            Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
+
+            Method getPath = storageVolumeClazz.getMethod("getPath");
+
+            Object result = getVolumeList.invoke(mStorageManager);
+
+            final int length = Array.getLength(result);
+
+            Method getUserLabel = storageVolumeClazz.getMethod("getUserLabel");
+
+            for (int i = 0; i < length; i++){
+                StorageVolume storageVolumeElement = (StorageVolume) Array.get(result, i);
+                String userLabel = (String) getUserLabel.invoke(storageVolumeElement);
+                String path = (String) getPath.invoke(storageVolumeElement);
+
+                if(!userLabel.contains("内部存储") && !storageVolumeElement.isEmulated()){
+                    targetpath = path;
+                    targetpath = targetpath +"/app-release.apk";
+                    file = new File(targetpath);
+                    if (!file.exists()) {
+                        ToastUtils.make(mContext, "U盘根目录下不存在升级所需APK!请检查APK存放目录!");
+                        return file;
+                    }
+                }
+            }
+        } catch (ClassNotFoundException e){
+            Log.e(TAG, "类找不到异常", e);
+            LoggingUtils.sendAppErrorLog("类找不到异常", e);
+        } catch (InvocationTargetException e) {
+            Log.e(TAG, "反射调用目标方法异常", e);
+            LoggingUtils.sendAppErrorLog("反射调用目标方法异常", e);
+        } catch (NoSuchMethodException e) {
+            Log.e(TAG, "反射找不到目标方法", e);
+            LoggingUtils.sendAppErrorLog("反射找不到目标方法", e);
+        } catch (IllegalAccessException e) {
+            Log.e(TAG, "没有权限", e);
+            LoggingUtils.sendAppErrorLog("没有权限", e);
+        }
+        return file;
+    }
+
     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
     public static void install(Context context, String apkFilePath, PackageManager packageManager, InstallListener listener) {
         try {

+ 69 - 0
app/src/main/java/com/emato/ich/update/USBUpdateReceiver.java

@@ -0,0 +1,69 @@
+package com.emato.ich.update;
+
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import com.emato.ich.MainActivity;
+import com.emato.ich.utils.Log;
+import com.emato.ich.utils.LoggingUtils;
+import com.emato.ich.utils.ToastUtils;
+
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+
+public class USBUpdateReceiver extends BroadcastReceiver {
+
+    private static final String TAG = USBUpdateReceiver.class.getName();
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+
+        String action = intent.getAction();
+
+        Log.i(TAG, "U盘挂载成功。3秒后开始更新!");
+        ToastUtils.make(context, "U盘挂载成功。3秒后开始更新!");
+        try {
+            TimeUnit.SECONDS.sleep(3);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        Log.i(TAG, "action:" + action);
+        if (action.equals(Intent.ACTION_MEDIA_MOUNTED)
+                || action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)
+                || action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
+
+            // 更新操作
+            Log.i(TAG, "开始通过U盘更新应用程序");
+
+            File apkFile = PackageManagerCompat.getUpdateAPKFile(context);
+
+            // 文件不存在直接退出
+            if (!apkFile.exists()) {
+                ToastUtils.make(context, "U盘根目录下不存在升级所需APK!请检查APK存放目录!");
+                return;
+            }
+
+            PackageManagerCompat.install(context, apkFile.getPath(), context.getPackageManager(), new InstallListener() {
+                @Override
+                public void onInstallException(Exception e) {
+                    // 更新异常
+                    Log.e(TAG, "安装失败! ", e);
+                }
+
+                @Override
+                public void onInstallSuccess() {
+                    // 更新成功
+                    PackageManagerCompat.restartApp(context);
+                    //
+                }
+            });
+        } else if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
+            Log.i(TAG, "U盘已移除。。。");
+            ToastUtils.make(context, "检测到U盘已移除");
+        }
+
+    }
+
+}