diff --git a/app/build.gradle b/app/build.gradle
index 7219b44..b55efaa 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,7 +2,9 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
-
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-kapt'
+//apply plugin: 'realm-android'
android {
namespace 'com.navinfo.vivo'
compileSdk 32
@@ -15,6 +17,16 @@ android {
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ // 指定room.schemaLocation生成的文件路径
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
+ }
+ }
+ ndk {
+ abiFilters "armeabi", "armeabi-v7a"
+ }
}
buildTypes {
@@ -37,7 +49,7 @@ android {
dependencies {
- implementation 'androidx.core:core-ktx:1.7.0'
+ implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
@@ -48,4 +60,18 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
+
+
+ implementation 'com.tencent.wcdb:room:1.1-19' // 代替 room-runtime,同时也不需要再引用 wcdb-android
+
+ api 'androidx.sqlite:sqlite:2.2.0'
+ implementation 'androidx.room:room-runtime:2.4.3'
+ annotationProcessor 'androidx.room:room-compiler:2.4.3'
+ annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
+ kapt 'android.arch.persistence.room:compiler:1.1.1'// compiler 需要用 room 的
+ kapt 'androidx.room:room-compiler:2.4.3'
+ androidTestImplementation "android.arch.persistence.room:testing:1.1.1"
+// implementation "android.arch.lifecycle:extensions:1.1.1"
+// annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
+ implementation 'com.tencent.wcdb:wcdb-android:1.1-19'
}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/vivo/db/dao/MapLifeDataBase.java b/app/src/main/java/com/navinfo/vivo/db/dao/MapLifeDataBase.java
new file mode 100644
index 0000000..64698d8
--- /dev/null
+++ b/app/src/main/java/com/navinfo/vivo/db/dao/MapLifeDataBase.java
@@ -0,0 +1,185 @@
+package com.navinfo.vivo.db.dao;
+
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.room.Database;
+import androidx.room.Room;
+import androidx.room.RoomDatabase;
+import androidx.sqlite.db.SupportSQLiteDatabase;
+import androidx.sqlite.db.SupportSQLiteOpenHelper;
+
+import com.navinfo.vivo.db.dao.entity.Message;
+import com.tencent.wcdb.database.SQLiteCipherSpec;
+import com.tencent.wcdb.database.SQLiteDatabase;
+
+import com.tencent.wcdb.room.db.WCDBOpenHelperFactory;
+
+import android.os.AsyncTask;
+import android.util.Log;
+
+import com.tencent.wcdb.repair.BackupKit;
+import com.tencent.wcdb.repair.RecoverKit;
+import com.tencent.wcdb.room.db.WCDBDatabase;
+
+@Database(entities = {Message.class}, version = 1, exportSchema = false)
+public abstract class MapLifeDataBase extends RoomDatabase {
+ // marking the instance as volatile to ensure atomic access to the variable
+ /**
+ * 数据库单例对象
+ */
+ private static volatile MapLifeDataBase INSTANCE;
+
+ /**
+ * 要素数据库类
+ */
+ public abstract MessageDao getMessageDao();
+
+ /**
+ * 数据库秘钥
+ */
+ private final static String DB_PASSWORD = "123456";
+
+ public static MapLifeDataBase getDatabase(final Context context, final String name) {
+ if (INSTANCE == null) {
+ synchronized (MapLifeDataBase.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(), MapLifeDataBase.class, name)
+
+ // [WCDB] Specify open helper to use WCDB database implementation instead
+ // of the Android framework.
+ .openHelperFactory((SupportSQLiteOpenHelper.Factory) 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.
+ *
+ * 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 {
+
+ private final MessageDao messageDao;
+
+ PopulateDbAsync(MapLifeDataBase db) {
+ messageDao = db.getMessageDao();
+ }
+
+ @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/vivo/db/dao/MessageDao.kt b/app/src/main/java/com/navinfo/vivo/db/dao/MessageDao.kt
new file mode 100644
index 0000000..80f5cee
--- /dev/null
+++ b/app/src/main/java/com/navinfo/vivo/db/dao/MessageDao.kt
@@ -0,0 +1,19 @@
+package com.navinfo.vivo.db.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import com.navinfo.vivo.db.dao.entity.Message
+
+@Dao
+interface MessageDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun insert(vararg check: Message)
+
+ @Query("SELECT * FROM Message where id =:id")
+ fun findCheckManagerById(id: Long): Message?
+
+ @Query("SELECT * FROM Message")
+ fun findList(): List
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/vivo/db/dao/entity/Attachment.kt b/app/src/main/java/com/navinfo/vivo/db/dao/entity/Attachment.kt
new file mode 100644
index 0000000..862769b
--- /dev/null
+++ b/app/src/main/java/com/navinfo/vivo/db/dao/entity/Attachment.kt
@@ -0,0 +1,4 @@
+package com.navinfo.vivo.db.dao.entity
+
+class Attachment {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/vivo/db/dao/entity/Message.kt b/app/src/main/java/com/navinfo/vivo/db/dao/entity/Message.kt
new file mode 100644
index 0000000..d356ad3
--- /dev/null
+++ b/app/src/main/java/com/navinfo/vivo/db/dao/entity/Message.kt
@@ -0,0 +1,44 @@
+package com.navinfo.vivo.db.dao.entity
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity(tableName = "message")
+class Message(
+ @PrimaryKey(autoGenerate = true)
+ var id: Long = 0,
+ /**
+ *标题
+ */
+ var title: String,
+ /**
+ * 信息内容
+ */
+ var message: String,
+ /**
+ * 操作时间
+ */
+ var optionDate: String,
+ /**
+ * 发送时间
+ */
+ var sendDate: String,
+ /**
+ * 信息状态
+ */
+ var status: Int,
+ /**
+ * 发送者ID
+ */
+ var fromId: String,
+ /**
+ * 接收者ID
+ */
+ var toId: String,
+ /**
+ * 附件列表
+ */
+ var attachment: MutableList
+) {
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/vivo/db/dao/entity/User.kt b/app/src/main/java/com/navinfo/vivo/db/dao/entity/User.kt
new file mode 100644
index 0000000..b2329ee
--- /dev/null
+++ b/app/src/main/java/com/navinfo/vivo/db/dao/entity/User.kt
@@ -0,0 +1,13 @@
+package com.navinfo.vivo.db.dao.entity
+
+import androidx.room.PrimaryKey
+import java.net.IDN
+
+class User(
+ @PrimaryKey()
+ val id:String,
+ var name:String,
+ var nickname:String,
+
+) {
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 2536974..81412b3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,19 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+// ext.kotlin_version = '1.7.0'
+ ext.kotlin_version = '1.6.20'
+ dependencies {
+// classpath "com.android.tools.build:gradle:4.1.1"
+// classpath('androidx.multidex:multidex:2.0.1')
+// classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
+// classpath "io.realm:realm-gradle-plugin:10.10.1"
+// classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
+// id 'io.realm.kotlin' version '0.10.0' apply false
}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 3c5031e..0328c09 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -20,4 +20,10 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
\ No newline at end of file
+android.nonTransitiveRClass=true
+android.enableJetifier=true
+systemProp.http.proxyHost=127.0.0.1
+systemProp.http.proxyPort=1080
+systemProp.https.proxyHost=127.0.0.1
+systemProp.https.proxyPort=1080
+org.gradle.configureondemand=true
\ No newline at end of file