Переглянути джерело

fix(app): 修复版本更新和直播状态显示问题

- 更新应用版本号至 1.0.1
- 修复获取飞行器位置时的空指针异常- 优化版本更新下载和安装流程
- 改进直播状态显示逻辑
mws 3 місяців тому
батько
коміт
f63c73d2e5

+ 1 - 1
app/build.gradle

@@ -17,7 +17,7 @@ android {
         minSdk 24
         targetSdk 35
         versionCode 1
-        versionName "1.0.0"
+        versionName "1.0.1"
         manifestPlaceholders["API_KEY"] = project.AIRCRAFT_API_KEY
         manifestPlaceholders["GMAP_API_KEY"] = project.GMAP_API_KEY
         manifestPlaceholders["AMAP_API_KEY"] = project.AMAP_API_KEY

+ 11 - 8
app/src/main/java/com/paul/drone/SteamControlActivity.java

@@ -432,14 +432,17 @@ public class SteamControlActivity extends DefaultLayoutActivity {
      * 更新直播状态显示
      */
     private void updateLiveStatus(boolean isStreaming) {
-        if (tvLiveStatus == null) return;
-        if (isStreaming) {
-            tvLiveStatus.setText("直播状态: 正在直播");
-            tvLiveStatus.setTextColor(ContextCompat.getColor(this, android.R.color.holo_green_dark));
-        } else {
-            tvLiveStatus.setText("直播状态: 未直播");
-            tvLiveStatus.setTextColor(ContextCompat.getColor(this, android.R.color.holo_red_dark));
-        }
+        runOnUiThread(() -> {
+            if (tvLiveStatus == null) return;
+            if (isStreaming) {
+                tvLiveStatus.setText("直播状态: 正在直播");
+                tvLiveStatus.setTextColor(ContextCompat.getColor(this, android.R.color.holo_green_dark));
+            } else {
+                tvLiveStatus.setText("直播状态: 未直播");
+                tvLiveStatus.setTextColor(ContextCompat.getColor(this, android.R.color.holo_red_dark));
+            }
+        });
+
     }
 
     @Override

+ 32 - 5
app/src/main/java/com/paul/drone/activity/LoginActivity.java

@@ -258,6 +258,7 @@ public class LoginActivity extends AppCompatActivity {
     
 
     private void showForceUpdateDialog(UpdateInfoResponse updateInfo) {
+
         AlertDialog.Builder builder = new AlertDialog.Builder(this);
         LayoutInflater inflater = LayoutInflater.from(this);
         View dialogView = inflater.inflate(R.layout.dialog_update, null);
@@ -533,12 +534,35 @@ public class LoginActivity extends AppCompatActivity {
             if (cursor != null && cursor.moveToFirst()) {
                 int statusIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
                 if (DownloadManager.STATUS_SUCCESSFUL == cursor.getInt(statusIndex)) {
-                    // 获取下载文件的URI
-                    int uriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
-                    String downloadedFileUriString = cursor.getString(uriIndex);
+                    // 获取下载文件的URI - 尝试多种方式获取URI
+                    Uri apkUri = null;
+
+                    // 方法1: 使用DownloadManager.getUriForDownloadedFile (推荐)
+                    apkUri = downloadManager.getUriForDownloadedFile(downloadId);
+
+                    // 方法2: 如果方法1返回null,则尝试从COLUMN_LOCAL_URI获取
+                    if (apkUri == null) {
+                        int uriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
+                        String downloadedFileUriString = cursor.getString(uriIndex);
+                        if (downloadedFileUriString != null) {
+                            apkUri = Uri.parse(downloadedFileUriString);
+                        }
+                    }
 
-                    if (downloadedFileUriString != null) {
-                        Uri apkUri = Uri.parse(downloadedFileUriString);
+                    // 方法3: 如果还是null,则尝试从COLUMN_URI获取
+                    if (apkUri == null) {
+                        int uriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_URI);
+                        String downloadedFileUriString = cursor.getString(uriIndex);
+                        if (downloadedFileUriString != null) {
+                            apkUri = Uri.parse(downloadedFileUriString);
+                        }
+                    }
+
+                    if (apkUri != null) {
+                        Log.i(TAG, "原始APK URI: " + apkUri.toString());
+                        Log.i(TAG, "URI Scheme: " + apkUri.getScheme());
+                        Log.i(TAG, "URI Authority: " + apkUri.getAuthority());
+                        Log.i(TAG, "URI Path: " + apkUri.getPath());
 
                         // Android 7.0及以上版本使用FileProvider处理file:// URI
                         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && "file".equals(apkUri.getScheme())) {
@@ -550,6 +574,7 @@ public class LoginActivity extends AppCompatActivity {
                                         "com.paul.drone.fileprovider",
                                         apkFile
                                 );
+                                Log.i(TAG, "转换后的Content URI: " + contentUri.toString());
                                 // 授予临时权限给包管理器
                                 updateUtil.installApk(contentUri);
                             } else {
@@ -557,6 +582,7 @@ public class LoginActivity extends AppCompatActivity {
                             }
                         } else {
                             // Android 7.0以下版本或已经是content:// URI,直接使用
+                            Log.i(TAG, "直接使用URI进行安装");
                             updateUtil.installApk(apkUri);
                         }
 
@@ -582,4 +608,5 @@ public class LoginActivity extends AppCompatActivity {
     }
 
 
+
 }

+ 11 - 1
app/src/main/java/com/paul/drone/util/DeviceInfoManager.java

@@ -138,12 +138,22 @@ public class DeviceInfoManager {
 
     public LocationCoordinate2D getFightLocation(){
         LocationCoordinate2D value = KeyManager.getInstance().getValue(DJIKey.create(FlightControllerKey.KeyHomeLocation));
+
+        // 先检查value是否为null
+        if (value == null) {
+            // 如果是null,创建一个新的LocationCoordinate2D实例
+            value = new LocationCoordinate2D(0.0, 0.0);
+        }
+
+        // 然后安全地设置坐标值
         value.setLatitude(28.228079);
         value.setLongitude(112.938975);
-        return value != null ? value : new LocationCoordinate2D(0.0,0.0);
+
+        return value;
     }
 
 
+
     /**
      * 获取固件版本
      * @return 固件版本字符串

+ 55 - 8
app/src/main/java/com/paul/drone/util/VersionUpdateUtil.java

@@ -203,26 +203,73 @@ public class VersionUpdateUtil {
     /**
      * 安装APK
      */
+    /**
+     * 安装APK
+     */
     public void installApk(Uri apkUri) {
         Log.i(TAG, "开始安装APK: " + apkUri);
+        Log.i(TAG, "APK URI Scheme: " + (apkUri != null ? apkUri.getScheme() : "null"));
 
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // Android 7.0及以上需要添加临时权限
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        if (apkUri == null) {
+            Log.e(TAG, "APK URI 为空,无法安装");
+            Toast.makeText(context, "安装文件路径无效", Toast.LENGTH_SHORT).show();
+            return;
         }
 
         try {
+            // 检查安装权限 (Android 8.0及以上)
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                boolean canInstall = context.getPackageManager().canRequestPackageInstalls();
+                Log.i(TAG, "安装权限检查 (Android 8.0+): " + (canInstall ? "已授予" : "未授予"));
+                if (!canInstall) {
+                    Log.w(TAG, "缺少安装权限,可能导致安装失败");
+                }
+            }
+
+            // 检查URI可读性
+            checkUriReadable(apkUri);
+
+            // 记录更多URI信息
+            Log.i(TAG, "URI Authority: " + apkUri.getAuthority());
+            Log.i(TAG, "URI Path: " + apkUri.getPath());
+            Log.i(TAG, "URI Query: " + apkUri.getQuery());
+
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+            Log.i(TAG, "启动安装Intent,Flags: " + Integer.toHexString(intent.getFlags()));
+
             context.startActivity(intent);
+            Log.i(TAG, "安装Intent已启动");
+
         } catch (Exception e) {
-            Log.e(TAG, "安装APK失败: " + e.getMessage());
+            Log.e(TAG, "安装APK失败: " + e.getMessage(), e);
+            Toast.makeText(context, "安装失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
+        } catch (Error e) {
+            // 捕获Error,防止应用崩溃
+            Log.e(TAG, "安装APK时发生严重错误: " + e.getMessage(), e);
             Toast.makeText(context, "安装失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
         }
     }
 
+    /**
+     * 检查URI是否可读
+     */
+    private void checkUriReadable(Uri uri) {
+        try {
+            // 尝试打开输入流来验证URI是否可读
+            context.getContentResolver().openInputStream(uri).close();
+            Log.i(TAG, "URI可读性检查: 成功");
+        } catch (Exception e) {
+            Log.w(TAG, "URI可读性检查失败: " + e.getMessage());
+            Log.w(TAG, "这可能是因为权限不足或文件不存在");
+        }
+    }
+
+
+
 
     /**
      * 版本更新检查监听器