From 5943949cc8b1200efde646b148e36d597056b9e5 Mon Sep 17 00:00:00 2001
From: qiji4215 <qiji4215@navinfo.com>
Date: Thu, 20 Apr 2023 16:45:15 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=BD=A8=E8=BF=B9=E4=B8=9A?=
 =?UTF-8?q?=E5=8A=A1=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/build.gradle                              |  15 +-
 .../java/com/navinfo/omqs/OMQSApplication.kt  |   2 +
 .../com/navinfo/omqs/db/RoomAppDatabase.kt    |   1 +
 .../com/navinfo/omqs/db/TraceDataBase.java    | 184 ++++++++++++++++++
 .../omqs/ui/activity/map/MainActivity.kt      |   4 +
 build.gradle                                  |   3 -
 collect-library/build.gradle                  |  38 +++-
 7 files changed, 228 insertions(+), 19 deletions(-)
 create mode 100644 app/src/main/java/com/navinfo/omqs/db/TraceDataBase.java

diff --git a/app/build.gradle b/app/build.gradle
index 8f544367..dc2f04ca 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -18,10 +18,6 @@ android {
         versionName "1.0"
 
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
-
-        ndk {
-            abiFilters "armeabi", "armeabi-v7a"
-        }
     }
 
     buildTypes {
@@ -34,11 +30,6 @@ android {
         sourceCompatibility JavaVersion.VERSION_11
         targetCompatibility JavaVersion.VERSION_11
     }
-    sourceSets {
-        main {
-            jniLibs.srcDirs = ['libs']
-        }
-    }
     kotlinOptions {
         jvmTarget = '1.8'
     }
@@ -52,7 +43,10 @@ android {
 
 
 dependencies {
+
     implementation project(':collect-library')
+
+
     testImplementation 'junit:junit:4.13.2'
     androidTestImplementation 'androidx.test.ext:junit:1.1.5'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
@@ -81,6 +75,9 @@ dependencies {
     implementation 'org.apache.poi:poi:5.2.3'
     implementation 'org.apache.poi:poi-ooxml:5.2.3'
 
+    // 读取spatialite文件
+    implementation 'com.github.sevar83:android-spatialite:2.0.1'
+
 }
 //允许引用生成的代码
 kapt {
diff --git a/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt b/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt
index 0442d351..eabe4308 100644
--- a/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt
+++ b/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt
@@ -2,6 +2,8 @@ package com.navinfo.omqs
 
 import android.app.Application
 import android.util.Log
+import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase
+import com.navinfo.omqs.db.TraceDataBase
 import com.navinfo.omqs.tools.FileManager
 import com.navinfo.omqs.ui.manager.TakePhotoManager
 import com.navinfo.omqs.util.NetUtils
diff --git a/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt b/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt
index 260df186..be0365e2 100644
--- a/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt
+++ b/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt
@@ -2,6 +2,7 @@ package com.navinfo.omqs.db
 
 import androidx.room.Database
 import androidx.room.RoomDatabase
+import com.navinfo.collect.library.data.entity.NiLocation
 import com.navinfo.omqs.bean.OfflineMapCityBean
 import com.navinfo.omqs.bean.ScProblemTypeBean
 import com.navinfo.omqs.bean.ScRootCauseAnalysisBean
diff --git a/app/src/main/java/com/navinfo/omqs/db/TraceDataBase.java b/app/src/main/java/com/navinfo/omqs/db/TraceDataBase.java
new file mode 100644
index 00000000..a37f25cd
--- /dev/null
+++ b/app/src/main/java/com/navinfo/omqs/db/TraceDataBase.java
@@ -0,0 +1,184 @@
+package com.navinfo.omqs.db;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.room.Database;
+import androidx.room.Room;
+import androidx.room.RoomDatabase;
+import androidx.sqlite.db.SupportSQLiteDatabase;
+import com.navinfo.collect.library.data.dao.impl.INiLocationDao;
+import com.navinfo.collect.library.data.entity.NiLocation;
+import com.tencent.wcdb.database.SQLiteCipherSpec;
+import com.tencent.wcdb.database.SQLiteDatabase;
+import com.tencent.wcdb.repair.BackupKit;
+import com.tencent.wcdb.repair.RecoverKit;
+import com.tencent.wcdb.room.db.WCDBDatabase;
+import com.tencent.wcdb.room.db.WCDBOpenHelperFactory;
+
+@Database(entities = { NiLocation.class},version = 1, exportSchema = false)
+public abstract class TraceDataBase extends RoomDatabase {
+    // marking the instance as volatile to ensure atomic access to the variable
+    /**
+     * 数据库单例对象
+     */
+    private static volatile TraceDataBase INSTANCE;
+
+    /**
+     * 地图坐标库类
+     */
+    public abstract INiLocationDao getNiLocationDao();
+
+    /**
+     * 数据库秘钥
+     */
+    private final static String DB_PASSWORD = "123456";
+
+    public static TraceDataBase getDatabase(final Context context, final String name) {
+        if (INSTANCE == null) {
+            synchronized (TraceDataBase.class) {
+                if (INSTANCE == null) {
+                    // [WCDB] To use Room library with WCDB, pass a WCDBOpenHelper factory object
+                    // to the database builder with .openHelperFactory(...). In the factory object,
+                    // you can specify passphrase and cipher options to open or create encrypted
+                    // database, as well as optimization options like asynchronous checkpoint.
+                    SQLiteCipherSpec cipherSpec = new SQLiteCipherSpec()
+                            .setPageSize(1024)
+                            .setSQLCipherVersion(3);
+                    WCDBOpenHelperFactory factory = new WCDBOpenHelperFactory()
+                            .passphrase(DB_PASSWORD.getBytes())  // passphrase to the database, remove this line for plain-text
+                            .cipherSpec(cipherSpec)               // cipher to use, remove for default settings
+                            .writeAheadLoggingEnabled(true)       // enable WAL mode, remove if not needed
+                            .asyncCheckpointEnabled(true);        // enable asynchronous checkpoint, remove if not needed
+
+                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
+                            TraceDataBase.class, name)
+
+                            // [WCDB] Specify open helper to use WCDB database implementation instead
+                            // of the Android framework.
+                            .openHelperFactory(factory)
+
+                            // Wipes and rebuilds instead of migrating if no Migration object.
+                            // Migration is not part of this codelab.
+                            .fallbackToDestructiveMigration()
+                            .addCallback(sRoomDatabaseCallback)
+                            .build();
+                }
+            }
+        }
+        return INSTANCE;
+    }
+
+    /**
+     * Override the onOpen method to populate the database.
+     * For this sample, we clear the database every time it is created or opened.
+     * <p>
+     * If you want to populate the database only when the database is created for the 1st time,
+     * override RoomDatabase.Callback()#onCreate
+     */
+    private static Callback sRoomDatabaseCallback = new Callback() {
+
+        @Override
+        public void onOpen(@NonNull SupportSQLiteDatabase db) {
+            super.onOpen(db);
+            // If you want to keep the data through app restarts,
+            // comment out the following line.
+            new PopulateDbAsync(INSTANCE).execute();
+        }
+    };
+
+    /**
+     * Populate the database in the background.
+     * If you want to start with more words, just add them.
+     */
+    private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
+
+        private final ILayerManagerDao mLayerDao;
+
+        PopulateDbAsync(TraceDataBase db) {
+            mLayerDao = db.getLayerManagerDao();
+        }
+
+        @Override
+        protected Void doInBackground(final Void... params) {
+            // Start the app with a clean database every time.
+            // Not needed if you only populate on creation.
+            //mDao.deleteAll();
+            Log.e("qj", "doInBackground");
+            return null;
+        }
+    }
+
+    /**
+     * 数据恢复
+     */
+    protected boolean recoverData(){
+        if(INSTANCE!=null){
+            SQLiteDatabase sqlite = ((WCDBDatabase) INSTANCE.getOpenHelper().getWritableDatabase()).getInnerDatabase();
+            RecoverKit recover = new RecoverKit(
+                    sqlite,                         // 要恢复到的目标 DB
+                    sqlite.getPath() + "-backup",   // 备份文件
+                    DB_PASSWORD.getBytes()           // 加密备份文件的密钥,非 DB 密钥
+            );
+            int result = recover.run(false);    // fatal 参数传 false 表示遇到错误忽略并继续,
+            // 若传 true 遇到错误则中止并返回 FAILED
+            switch (result) {
+                case RecoverKit.RESULT_OK:
+                    /* 成功 */
+                    Log.e("qj","sRoomDatabaseCallback==RecoverKit成功");
+                    return true;
+                case RecoverKit.RESULT_CANCELED: /* 取消操作 */
+                    Log.e("qj","sRoomDatabaseCallback==RecoverKit取消操作");
+                    break;
+                case RecoverKit.RESULT_FAILED: /* 失败 */
+                    Log.e("qj","sRoomDatabaseCallback==RecoverKit失败");
+                    break;
+
+            }
+
+            recover.release();
+        }
+
+        return false;
+    }
+
+    /**
+     * 备份数据
+     */
+    protected boolean backup() {
+        Log.e("qj", "sRoomDatabaseCallback===backup==start");
+        if (INSTANCE != null) {
+            //备份文件
+            SQLiteDatabase sqlite = ((WCDBDatabase) INSTANCE.getOpenHelper().getWritableDatabase()).getInnerDatabase();
+            BackupKit backup = new BackupKit(
+                    sqlite,                         // 要备份的 DB
+                    sqlite.getPath() + "-backup",   // 备份文件
+                    "123456".getBytes(),          // 加密备份文件的密钥,非 DB 密钥
+                    0, null);
+            int result = backup.run();
+            switch (result) {
+                case BackupKit.RESULT_OK:
+                    /* 成功 */
+                    Log.e("qj", "sRoomDatabaseCallback==成功");
+                    return true;
+                case BackupKit.RESULT_CANCELED:
+                    /* 取消操作 */
+                    Log.e("qj", "sRoomDatabaseCallback==取消操作");
+                    break;
+                case BackupKit.RESULT_FAILED:
+                    /* 失败 */
+                    Log.e("qj", "sRoomDatabaseCallback==失败");
+                    break;
+            }
+
+            backup.release();
+        }
+        Log.e("qj", "sRoomDatabaseCallback===backup==end");
+        return false;
+    }
+
+    protected void release() {
+        INSTANCE = null;
+    }
+}
diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
index 1dfcd262..fd89a97a 100644
--- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
+++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt
@@ -12,7 +12,9 @@ import com.navinfo.collect.library.map.NIMapController
 import com.navinfo.omqs.Constant
 import com.navinfo.omqs.R
 import com.navinfo.omqs.databinding.ActivityMainBinding
+import com.navinfo.omqs.db.TraceDataBase
 import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager
+import com.navinfo.omqs.system.SystemConstant
 import com.navinfo.omqs.ui.activity.BaseActivity
 import dagger.hilt.android.AndroidEntryPoint
 import javax.inject.Inject
@@ -53,6 +55,8 @@ class MainActivity : BaseActivity() {
         binding.viewModel = viewModel
 //        lifecycle.addObserver(viewModel)
         lifecycleScope
+        //初始化轨迹文件
+        TraceDataBase.getDatabase(this,Constant.DATA_PATH+SystemConstant.USER_ID+"/trace.sqlite")
     }
 
     override fun onStart() {
diff --git a/build.gradle b/build.gradle
index 327b0ab8..63d6efae 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,9 +3,6 @@
 
 buildscript {
     dependencies {
-        classpath 'com.android.tools.build:gradle:4.2.2'
-        classpath('androidx.multidex:multidex:2.0.1')
-        classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
         classpath "io.realm:realm-gradle-plugin:10.11.1"
     }
 }
diff --git a/collect-library/build.gradle b/collect-library/build.gradle
index c0267699..3cca075f 100644
--- a/collect-library/build.gradle
+++ b/collect-library/build.gradle
@@ -6,25 +6,47 @@ plugins {
     id 'kotlin-kapt'
     id 'realm-android'
 }
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlin-kapt'
-apply plugin: 'realm-android'
 
+ext.roomversion = "2.1.0"
 ext.vtmVersion = "0.18.0"
 ext.realm_version = '10.10.1'
 ext.appcompatVersion = "1.3.0"
 ext.materialVersion = "1.5.0"
-ext.kotlin_version = '1.8.0'
+ext.kotlin_version = '1.7.0'
 
 android {
     compileSdk 30
 
+    defaultConfig {
+        minSdk 23
+        targetSdk 30
+        versionCode 1
+        versionName "1.0"
+
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+        consumerProguardFiles "consumer-rules.pro"
+
+        // 指定room.schemaLocation生成的文件路径
+        javaCompileOptions {
+            annotationProcessorOptions {
+                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
+            }
+        }
+        ndk {
+            abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
+        }
+    }
+
     buildTypes {
         release {
             minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         }
     }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
 
     sourceSets {
         main {
@@ -33,11 +55,13 @@ android {
     }
 }
 
-
+//configurations.all {
+//    resolutionStrategy {
+//        force 'com.intellij:annotations:13.0'
+//    }
+//}
 dependencies {
     api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
-    implementation "androidx.appcompat:appcompat:$appcompatVersion"
-    implementation "com.google.android.material:material:$materialVersion"
     api files('libs/BaiduLBS_Android.jar')
 
     //