diff --git a/app/build.gradle b/app/build.gradle
index 93a2907..4c41460 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -136,9 +136,13 @@ dependencies {
// 日志工具 https://github.com/elvishew/xLog/blob/master/README_ZH.md
implementation 'com.elvishew:xlog:1.10.1'
//加载图片的依赖包
- implementation ("com.github.bumptech.glide:glide:4.11.0") {
+ implementation("com.github.bumptech.glide:glide:4.11.0") {
exclude group: "com.android.support"
}
+ // 多媒体播放库 https://github.com/JagarYousef/ChatVoicePlayer
+ implementation 'com.github.JagarYousef:ChatVoicePlayer:1.1.0'
+ // 图片查看器 https://github.com/XiaoGe-1996/ImageViewer
+ implementation 'com.github.XiaoGe-1996:ImageViewer:v1.0.0'
}
kapt {
diff --git a/app/src/main/java/com/navinfo/volvo/database/AppDatabase.kt b/app/src/main/java/com/navinfo/volvo/database/AppDatabase.kt
index 0f288af..4b5f880 100644
--- a/app/src/main/java/com/navinfo/volvo/database/AppDatabase.kt
+++ b/app/src/main/java/com/navinfo/volvo/database/AppDatabase.kt
@@ -2,19 +2,19 @@ package com.navinfo.volvo.database
import androidx.room.Database
import androidx.room.RoomDatabase
-import com.navinfo.volvo.database.dao.MessageDao
+import com.navinfo.volvo.database.dao.GreetingMessageDao
import com.navinfo.volvo.database.dao.UserDao
-import com.navinfo.volvo.model.Attachment
-import com.navinfo.volvo.model.Message
-import com.navinfo.volvo.model.User
+import com.navinfo.volvo.database.entity.Attachment
+import com.navinfo.volvo.database.entity.GreetingMessage
+import com.navinfo.volvo.database.entity.User
@Database(
- entities = [Message::class, Attachment::class, User::class],
+ entities = [GreetingMessage::class, Attachment::class, User::class],
version = 1,
exportSchema = false
)
abstract class AppDatabase : RoomDatabase() {
- abstract fun getMessageDao(): MessageDao
+ abstract fun getMessageDao(): GreetingMessageDao
abstract fun getUserDao(): UserDao
}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/volvo/database/MapLifeDataBase.java b/app/src/main/java/com/navinfo/volvo/database/MapLifeDataBase.java
index 857125f..f1ebae1 100644
--- a/app/src/main/java/com/navinfo/volvo/database/MapLifeDataBase.java
+++ b/app/src/main/java/com/navinfo/volvo/database/MapLifeDataBase.java
@@ -1,191 +1,191 @@
-package com.navinfo.volvo.database;
-
-
-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.volvo.database.dao.MessageDao;
-import com.navinfo.volvo.database.dao.UserDao;
-import com.navinfo.volvo.model.Message;
-import com.navinfo.volvo.model.Attachment;
-import com.navinfo.volvo.model.User;
-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, Attachment.class, User.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();
-
- public abstract UserDao getUserDao();
-
- /**
- * 数据库秘钥
- */
- 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;
- }
-}
+//package com.navinfo.volvo.database;
+//
+//
+//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.volvo.database.dao.MessageDao;
+//import com.navinfo.volvo.database.dao.UserDao;
+//import com.navinfo.volvo.database.entity.Message;
+//import com.navinfo.volvo.database.entity.Attachment;
+//import com.navinfo.volvo.database.entity.User;
+//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, Attachment.class, User.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();
+//
+// public abstract UserDao getUserDao();
+//
+// /**
+// * 数据库秘钥
+// */
+// 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/volvo/database/dao/GreetingMessageDao.kt b/app/src/main/java/com/navinfo/volvo/database/dao/GreetingMessageDao.kt
new file mode 100644
index 0000000..479d490
--- /dev/null
+++ b/app/src/main/java/com/navinfo/volvo/database/dao/GreetingMessageDao.kt
@@ -0,0 +1,19 @@
+package com.navinfo.volvo.database.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import com.navinfo.volvo.database.entity.GreetingMessage
+
+@Dao
+interface GreetingMessageDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun insert(vararg check: GreetingMessage)
+
+ @Query("SELECT * FROM GreetingMessage where id =:id")
+ fun findCheckManagerById(id: Long): GreetingMessage?
+
+ @Query("SELECT * FROM GreetingMessage")
+ fun findList(): List
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/volvo/database/dao/MessageDao.kt b/app/src/main/java/com/navinfo/volvo/database/dao/MessageDao.kt
deleted file mode 100644
index fa60d36..0000000
--- a/app/src/main/java/com/navinfo/volvo/database/dao/MessageDao.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.navinfo.volvo.database.dao
-
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.OnConflictStrategy
-import androidx.room.Query
-import com.navinfo.volvo.model.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/volvo/database/dao/UserDao.kt b/app/src/main/java/com/navinfo/volvo/database/dao/UserDao.kt
index fdbd156..4057662 100644
--- a/app/src/main/java/com/navinfo/volvo/database/dao/UserDao.kt
+++ b/app/src/main/java/com/navinfo/volvo/database/dao/UserDao.kt
@@ -3,7 +3,7 @@ package com.navinfo.volvo.database.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
-import com.navinfo.volvo.model.User
+import com.navinfo.volvo.database.entity.User
@Dao
interface UserDao {
diff --git a/app/src/main/java/com/navinfo/volvo/model/Attachment.kt b/app/src/main/java/com/navinfo/volvo/database/entity/Attachment.kt
similarity index 95%
rename from app/src/main/java/com/navinfo/volvo/model/Attachment.kt
rename to app/src/main/java/com/navinfo/volvo/database/entity/Attachment.kt
index fefa2b3..4e226d4 100644
--- a/app/src/main/java/com/navinfo/volvo/model/Attachment.kt
+++ b/app/src/main/java/com/navinfo/volvo/database/entity/Attachment.kt
@@ -1,4 +1,4 @@
-package com.navinfo.volvo.model
+package com.navinfo.volvo.database.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
@@ -8,7 +8,7 @@ import com.navinfo.volvo.tools.GsonUtil
@Entity(tableName = "Attachment")
data class Attachment(
- @PrimaryKey()
+ @PrimaryKey
var id: String,
var pathUrl: String,
var attachmentType: AttachmentType
diff --git a/app/src/main/java/com/navinfo/volvo/database/entity/GreetingMessage.kt b/app/src/main/java/com/navinfo/volvo/database/entity/GreetingMessage.kt
new file mode 100644
index 0000000..325af6b
--- /dev/null
+++ b/app/src/main/java/com/navinfo/volvo/database/entity/GreetingMessage.kt
@@ -0,0 +1,44 @@
+package com.navinfo.volvo.database.entity
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import androidx.room.TypeConverters
+import org.jetbrains.annotations.NotNull
+
+@Entity(tableName = "GreetingMessage")
+@TypeConverters(AttachmentConverters::class)
+data class GreetingMessage @JvmOverloads constructor(
+ @PrimaryKey(autoGenerate = true)
+ var uuid:Long = 0,
+ var id: Long = 0,
+ var searchValue: String? = "",
+ var createBy: String? = "",
+ var createTime: String? = "",
+ var updateBy: String? = "",
+ var updateTime: String? = "",
+ var remark: String? = "",
+ var name: String? = "",
+ var imageUrl: String? = "",
+ var mediaUrl: String? = "",
+ var who: String? = "",
+ var toWho: String? = "",
+ var sendDate: String? = "",
+ var status: String? = "",
+ var isSkip: String? = "",
+ var skipUrl: String? = "",
+ var startTime: String? = "",
+ var endTime: String? = "",
+ var sendVehicle: String? = "",
+ var sendSex: String? = "",
+ var sendAge: String? = "",
+ var sendNum: String? = "",
+ var sendVins: String? = "",
+ var sendType: String? = "",
+ var del: String? = "",
+ var version: String? = "",
+// /**
+// * 附件列表
+// */
+// var attachment: MutableList = mutableListOf()
+) {
+}
diff --git a/app/src/main/java/com/navinfo/volvo/model/User.kt b/app/src/main/java/com/navinfo/volvo/database/entity/User.kt
similarity index 93%
rename from app/src/main/java/com/navinfo/volvo/model/User.kt
rename to app/src/main/java/com/navinfo/volvo/database/entity/User.kt
index 80a6c7a..1816bd4 100644
--- a/app/src/main/java/com/navinfo/volvo/model/User.kt
+++ b/app/src/main/java/com/navinfo/volvo/database/entity/User.kt
@@ -1,4 +1,4 @@
-package com.navinfo.volvo.model
+package com.navinfo.volvo.database.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
@@ -7,8 +7,6 @@ import androidx.room.TypeConverters
import com.google.gson.reflect.TypeToken
import com.navinfo.volvo.tools.GsonUtil
import org.jetbrains.annotations.NotNull
-import java.time.LocalDateTime
-import java.time.LocalTime
import javax.inject.Inject
@Entity(tableName = "User")
diff --git a/app/src/main/java/com/navinfo/volvo/di/module/DatabaseModule.kt b/app/src/main/java/com/navinfo/volvo/di/module/DatabaseModule.kt
index bd2582e..2a302b3 100644
--- a/app/src/main/java/com/navinfo/volvo/di/module/DatabaseModule.kt
+++ b/app/src/main/java/com/navinfo/volvo/di/module/DatabaseModule.kt
@@ -3,7 +3,7 @@ package com.navinfo.volvo.di.module
import android.content.Context
import androidx.room.Room
import com.navinfo.volvo.database.AppDatabase
-import com.navinfo.volvo.database.dao.MessageDao
+import com.navinfo.volvo.database.dao.GreetingMessageDao
import com.navinfo.volvo.database.dao.UserDao
import com.tencent.wcdb.database.SQLiteCipherSpec
import com.tencent.wcdb.room.db.WCDBOpenHelperFactory
@@ -45,7 +45,7 @@ class DatabaseModule {
@Singleton
@Provides
- fun provideMessageDao(database: AppDatabase): MessageDao {
+ fun provideMessageDao(database: AppDatabase): GreetingMessageDao {
return database.getMessageDao()
}
diff --git a/app/src/main/java/com/navinfo/volvo/http/DownloadManager.kt b/app/src/main/java/com/navinfo/volvo/http/DownloadManager.kt
new file mode 100644
index 0000000..666b263
--- /dev/null
+++ b/app/src/main/java/com/navinfo/volvo/http/DownloadManager.kt
@@ -0,0 +1,86 @@
+package com.navinfo.volvo.http
+
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOn
+import okhttp3.ResponseBody
+import retrofit2.Retrofit
+import java.io.File
+import java.io.IOException
+
+object DownloadManager {
+ suspend fun download(url: String, file: File): Flow {
+ return flow {
+ val retrofit = Retrofit.Builder()
+ .baseUrl(UrlUtils.getBaseUrl(url))
+ .build()
+ val response = retrofit.create(NavinfoVolvoService::class.java).downloadFile(url).execute()
+ if (response.isSuccessful) {
+ saveToFile(response.body()!!, file) {
+ emit(DownloadState.InProgress(it))
+ }
+ emit(DownloadState.Success(file))
+ } else {
+ emit(DownloadState.Error(IOException(response.toString())))
+ }
+ }.catch {
+ emit(DownloadState.Error(it))
+ }.flowOn(Dispatchers.IO)
+ }
+
+ private inline fun saveToFile(responseBody: ResponseBody, file: File, progressListener: (Int) -> Unit) {
+ val total = responseBody.contentLength()
+ var bytesCopied = 0
+ var emittedProgress = 0
+ file.outputStream().use { output ->
+ val input = responseBody.byteStream()
+ val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
+ var bytes = input.read(buffer)
+ while (bytes >= 0) {
+ output.write(buffer, 0, bytes)
+ bytesCopied += bytes
+ bytes = input.read(buffer)
+ val progress = (bytesCopied * 100 / total).toInt()
+ if (progress - emittedProgress > 0) {
+ progressListener(progress)
+ emittedProgress = progress
+ }
+ }
+ }
+ }
+}
+
+sealed class DownloadState {
+ data class InProgress(val progress: Int) : DownloadState()
+ data class Success(val file: File) : DownloadState()
+ data class Error(val throwable: Throwable) : DownloadState()
+}
+
+interface DownloadCallback {
+ fun progress(progress: Int)
+ fun error(throwable: Throwable)
+ fun success(file: File)
+}
+
+object UrlUtils {
+
+ /**
+ * 从url分割出BaseUrl
+ */
+ fun getBaseUrl(url: String): String {
+ var mutableUrl = url
+ var head = ""
+ var index = mutableUrl.indexOf("://")
+ if (index != -1) {
+ head = mutableUrl.substring(0, index + 3)
+ mutableUrl = mutableUrl.substring(index + 3)
+ }
+ index = mutableUrl.indexOf("/")
+ if (index != -1) {
+ mutableUrl = mutableUrl.substring(0, index + 1)
+ }
+ return head + mutableUrl
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/volvo/http/NavinfoVolvoService.kt b/app/src/main/java/com/navinfo/volvo/http/NavinfoVolvoService.kt
index 019e473..206d55a 100644
--- a/app/src/main/java/com/navinfo/volvo/http/NavinfoVolvoService.kt
+++ b/app/src/main/java/com/navinfo/volvo/http/NavinfoVolvoService.kt
@@ -2,11 +2,9 @@ package com.navinfo.volvo.http
import okhttp3.MultipartBody
import okhttp3.RequestBody
+import okhttp3.ResponseBody
import retrofit2.Call
-import retrofit2.http.Body
-import retrofit2.http.Multipart
-import retrofit2.http.POST
-import retrofit2.http.Part
+import retrofit2.http.*
import java.io.File
interface NavinfoVolvoService {
@@ -23,4 +21,7 @@ interface NavinfoVolvoService {
suspend fun uploadAttachment(@Part attachmentFile: MultipartBody.Part):DefaultResponse>
@POST("/img/download")
suspend fun downLoadAttachment(@Body downloadData: Map):DefaultResponse
+ @Streaming
+ @GET
+ fun downloadFile(@Url url: String): Call
}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/volvo/model/Message.kt b/app/src/main/java/com/navinfo/volvo/model/Message.kt
deleted file mode 100644
index 82c591d..0000000
--- a/app/src/main/java/com/navinfo/volvo/model/Message.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.navinfo.volvo.model
-
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-import androidx.room.TypeConverters
-
-@Entity(tableName = "message")
-@TypeConverters(AttachmentConverters::class)
-data class Message @JvmOverloads constructor(
- @PrimaryKey(autoGenerate = true)
- var id: Long = 0,
-
- var netId: String = "",
- /**
- *标题
- */
- var title: String = "",
- /**
- * 信息内容
- */
- var message: String = "",
- /**
- * 操作时间
- */
- var optionDate: String = "",
- /**
- * 发送时间
- */
- var sendDate: String = "",
- /**
- * 信息状态
- */
- var status: Int = 1,
- /**
- * 发送者ID
- */
- var fromId: String = "",
- /**
- * 接收者ID
- */
- var toId: String = "",
- /**
- * 附件列表
- */
- var attachment: MutableList = mutableListOf()
-)
diff --git a/app/src/main/java/com/navinfo/volvo/model/network/NetworkPostMessage.kt b/app/src/main/java/com/navinfo/volvo/model/messagelist/NetworkMessageListPost.kt
similarity index 87%
rename from app/src/main/java/com/navinfo/volvo/model/network/NetworkPostMessage.kt
rename to app/src/main/java/com/navinfo/volvo/model/messagelist/NetworkMessageListPost.kt
index 8e452f6..91d0dd5 100644
--- a/app/src/main/java/com/navinfo/volvo/model/network/NetworkPostMessage.kt
+++ b/app/src/main/java/com/navinfo/volvo/model/messagelist/NetworkMessageListPost.kt
@@ -1,6 +1,6 @@
-package com.navinfo.volvo.model.network
+package com.navinfo.volvo.model.messagelist
-data class NetworkPostMessage(
+data class NetworkMessageListPost(
val name: String,//问候名称,非必填项
val who: String, //我是谁
val toWho: String, //发送给谁
diff --git a/app/src/main/java/com/navinfo/volvo/model/messagelist/NetworkMessageListResponse.kt b/app/src/main/java/com/navinfo/volvo/model/messagelist/NetworkMessageListResponse.kt
new file mode 100644
index 0000000..94b7a40
--- /dev/null
+++ b/app/src/main/java/com/navinfo/volvo/model/messagelist/NetworkMessageListResponse.kt
@@ -0,0 +1,8 @@
+package com.navinfo.volvo.model.messagelist
+
+import com.navinfo.volvo.database.entity.GreetingMessage
+
+data class NetworkMessageListResponse(
+ val total: Int,
+ val rows: List
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/volvo/repository/NetworkDataSource.kt b/app/src/main/java/com/navinfo/volvo/repository/NetworkDataSource.kt
index 0791642..dddf32f 100644
--- a/app/src/main/java/com/navinfo/volvo/repository/NetworkDataSource.kt
+++ b/app/src/main/java/com/navinfo/volvo/repository/NetworkDataSource.kt
@@ -1,9 +1,10 @@
package com.navinfo.volvo.repository
-import com.navinfo.volvo.model.Message
-import com.navinfo.volvo.model.network.NetworkPostMessage
+import com.navinfo.volvo.http.DefaultResponse
+import com.navinfo.volvo.model.messagelist.NetworkMessageListPost
+import com.navinfo.volvo.model.messagelist.NetworkMessageListResponse
import com.navinfo.volvo.util.NetResult
interface NetworkDataSource {
- suspend fun getCardList(message: NetworkPostMessage): NetResult>
+ suspend fun getCardList(message: NetworkMessageListPost): NetResult>
}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/volvo/repository/NetworkDataSourceImp.kt b/app/src/main/java/com/navinfo/volvo/repository/NetworkDataSourceImp.kt
index 9bf7e4b..2d662bb 100644
--- a/app/src/main/java/com/navinfo/volvo/repository/NetworkDataSourceImp.kt
+++ b/app/src/main/java/com/navinfo/volvo/repository/NetworkDataSourceImp.kt
@@ -1,15 +1,17 @@
package com.navinfo.volvo.repository
+import com.navinfo.volvo.database.AppDatabase
+import com.navinfo.volvo.database.dao.GreetingMessageDao
import com.navinfo.volvo.di.scope.IoDispatcher
-import com.navinfo.volvo.model.Message
-import com.navinfo.volvo.model.network.NetworkPostMessage
+import com.navinfo.volvo.database.entity.GreetingMessage
+import com.navinfo.volvo.http.DefaultResponse
+import com.navinfo.volvo.model.messagelist.NetworkMessageListPost
+import com.navinfo.volvo.model.messagelist.NetworkMessageListResponse
import com.navinfo.volvo.repository.service.NetworkService
import com.navinfo.volvo.tools.GsonUtil
import com.navinfo.volvo.util.NetResult
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
-import okhttp3.FormBody
-import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import javax.inject.Inject
@@ -17,17 +19,22 @@ import javax.inject.Inject
class NetworkDataSourceImp @Inject constructor(
private val netWorkService: NetworkService,
+ private val messageDao: GreetingMessageDao,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
) : NetworkDataSource {
- override suspend fun getCardList(message: NetworkPostMessage): NetResult> =
+ override suspend fun getCardList(message: NetworkMessageListPost): NetResult> =
withContext(ioDispatcher) {
return@withContext try {
- val stringBody = GsonUtil.getInstance().toJson(message).toRequestBody("application/json;charset=utf-8".toMediaType())
+ val stringBody = GsonUtil.getInstance().toJson(message)
+ .toRequestBody("application/json;charset=utf-8".toMediaType())
val result = netWorkService.queryCardListByApp(stringBody)
if (result.isSuccessful) {
- val list = result.body()
- NetResult.Success(list)
+ val body = result.body()
+ val list: MutableList =
+ listOf(body!!.data!!.rows) as MutableList
+ messageDao.insert(*list.map { it }.toTypedArray())
+ NetResult.Success(body)
} else {
NetResult.Success(null)
}
diff --git a/app/src/main/java/com/navinfo/volvo/repository/service/NetworkService.kt b/app/src/main/java/com/navinfo/volvo/repository/service/NetworkService.kt
index df62a9c..208ce28 100644
--- a/app/src/main/java/com/navinfo/volvo/repository/service/NetworkService.kt
+++ b/app/src/main/java/com/navinfo/volvo/repository/service/NetworkService.kt
@@ -1,6 +1,7 @@
package com.navinfo.volvo.repository.service
-import com.navinfo.volvo.model.Message
+import com.navinfo.volvo.http.DefaultResponse
+import com.navinfo.volvo.model.messagelist.NetworkMessageListResponse
import okhttp3.RequestBody
import retrofit2.Response
import retrofit2.http.Body
@@ -8,5 +9,5 @@ import retrofit2.http.POST
interface NetworkService {
@POST("/navi/cardDelivery/queryCardListByApp")
- suspend fun queryCardListByApp(@Body body: RequestBody): Response>
+ suspend fun queryCardListByApp(@Body body: RequestBody): Response>
}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/volvo/ui/MainActivity.kt b/app/src/main/java/com/navinfo/volvo/ui/MainActivity.kt
index 5775985..86b1b8a 100644
--- a/app/src/main/java/com/navinfo/volvo/ui/MainActivity.kt
+++ b/app/src/main/java/com/navinfo/volvo/ui/MainActivity.kt
@@ -10,6 +10,7 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.easytools.tools.FileUtils
+import com.elvishew.xlog.BuildConfig
import com.elvishew.xlog.LogConfiguration
import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog
@@ -25,7 +26,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
-import com.navinfo.volvo.BuildConfig
import com.navinfo.volvo.R
import com.navinfo.volvo.databinding.ActivityMainBinding
import com.navinfo.volvo.utils.SystemConstant
@@ -55,7 +55,8 @@ class MainActivity : AppCompatActivity() {
override fun onGranted(permissions: MutableList, all: Boolean) {
if (!all) {
- Toast.makeText(this@MainActivity, "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT).show()
+ Toast.makeText(this@MainActivity, "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT)
+ .show()
return
}
// 在SD卡创建项目目录
@@ -64,7 +65,8 @@ class MainActivity : AppCompatActivity() {
override fun onDenied(permissions: MutableList, never: Boolean) {
if (never) {
- Toast.makeText(this@MainActivity, "永久拒绝授权,请手动授权文件读写权限", Toast.LENGTH_SHORT).show()
+ Toast.makeText(this@MainActivity, "永久拒绝授权,请手动授权文件读写权限", Toast.LENGTH_SHORT)
+ .show()
// 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(this@MainActivity, permissions)
} else {
@@ -146,10 +148,11 @@ class MainActivity : AppCompatActivity() {
val consolePrinter: Printer = ConsolePrinter() // 通过 System.out 打印日志到控制台的打印器
- val filePrinter: Printer = FilePrinter.Builder("${SystemConstant.ROOT_PATH}/Logs") // 指定保存日志文件的路径
- .fileNameGenerator(DateFileNameGenerator()) // 指定日志文件名生成器,默认为 ChangelessFileNameGenerator("log")
- .backupStrategy(NeverBackupStrategy()) // 指定日志文件备份策略,默认为 FileSizeBackupStrategy(1024 * 1024)
- .build()
+ val filePrinter: Printer =
+ FilePrinter.Builder("${SystemConstant.ROOT_PATH}/Logs") // 指定保存日志文件的路径
+ .fileNameGenerator(DateFileNameGenerator()) // 指定日志文件名生成器,默认为 ChangelessFileNameGenerator("log")
+ .backupStrategy(NeverBackupStrategy()) // 指定日志文件备份策略,默认为 FileSizeBackupStrategy(1024 * 1024)
+ .build()
XLog.init( // 初始化 XLog
config, // 指定日志配置,如果不指定,会默认使用 new LogConfiguration.Builder().build()
diff --git a/app/src/main/java/com/navinfo/volvo/ui/adapter/MessageAdapter.kt b/app/src/main/java/com/navinfo/volvo/ui/adapter/MessageAdapter.kt
index 22875d9..cb7525c 100644
--- a/app/src/main/java/com/navinfo/volvo/ui/adapter/MessageAdapter.kt
+++ b/app/src/main/java/com/navinfo/volvo/ui/adapter/MessageAdapter.kt
@@ -7,18 +7,18 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.navinfo.volvo.R
-import com.navinfo.volvo.model.Message
+import com.navinfo.volvo.database.entity.GreetingMessage
class MessageAdapter : RecyclerView.Adapter() {
- var itemList: MutableList = mutableListOf()
+ var itemList: MutableList = mutableListOf()
- fun addItem(message: Message) {
+ fun addItem(message: GreetingMessage) {
itemList.add(message)
notifyItemInserted(itemList.size - 1)
}
- fun setItem(messageList: MutableList){
+ fun setItem(messageList: MutableList){
itemList = messageList
notifyDataSetChanged()
}
@@ -35,8 +35,8 @@ class MessageAdapter : RecyclerView.Adapter() {
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val message = itemList[position]
- holder.toName.text = message.fromId
- holder.messageText.text = message.message
+ holder.toName.text = message.toWho
+ holder.messageText.text = message.name
holder.sendTime.text = message.sendDate
}
diff --git a/app/src/main/java/com/navinfo/volvo/ui/fragments/home/MessageViewModel.kt b/app/src/main/java/com/navinfo/volvo/ui/fragments/home/MessageViewModel.kt
index 4bbe309..c65fd8f 100644
--- a/app/src/main/java/com/navinfo/volvo/ui/fragments/home/MessageViewModel.kt
+++ b/app/src/main/java/com/navinfo/volvo/ui/fragments/home/MessageViewModel.kt
@@ -3,8 +3,9 @@ package com.navinfo.volvo.ui.fragments.home
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.navinfo.volvo.model.Message
-import com.navinfo.volvo.model.network.NetworkPostMessage
+import com.navinfo.volvo.database.entity.GreetingMessage
+import com.navinfo.volvo.model.messagelist.NetworkMessageListPost
+import com.navinfo.volvo.model.messagelist.NetworkMessageListResponse
import com.navinfo.volvo.repository.NetworkDataSource
import com.navinfo.volvo.util.NetResult
import com.navinfo.volvo.util.asLiveData
@@ -18,18 +19,18 @@ class MessageViewModel @Inject constructor(
private val _isLoading = MutableLiveData()
val isLoading = _isLoading.asLiveData()
- private val _messageList = MutableLiveData>()
+ private val _messageList = MutableLiveData>()
val messageList = _messageList.asLiveData()
fun getMessageList() {
_isLoading.postValue(true)
viewModelScope.launch {
- val messagePost = NetworkPostMessage(who = "北京测试", toWho = "volvo测试")
+ val messagePost = NetworkMessageListPost(who = "北京测试", toWho = "volvo测试")
when (val result = repository.getCardList(messagePost)) {
is NetResult.Success -> {
_isLoading.value = false
if (result.data != null) {
- val list = result.data
+ val list = (result.data.data as NetworkMessageListResponse).rows
_messageList.value = list
}
}
diff --git a/app/src/main/java/com/navinfo/volvo/ui/fragments/login/LoginViewModel.kt b/app/src/main/java/com/navinfo/volvo/ui/fragments/login/LoginViewModel.kt
index 5c02c3e..ef6d19a 100644
--- a/app/src/main/java/com/navinfo/volvo/ui/fragments/login/LoginViewModel.kt
+++ b/app/src/main/java/com/navinfo/volvo/ui/fragments/login/LoginViewModel.kt
@@ -5,7 +5,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.navinfo.volvo.database.AppDatabase
-import com.navinfo.volvo.model.User
+import com.navinfo.volvo.database.entity.User
import javax.inject.Inject
class LoginViewModel @Inject constructor(private val dataBase: AppDatabase) : ViewModel() {
diff --git a/app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageFragment.kt b/app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageFragment.kt
index 43a4a65..ff01973 100644
--- a/app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageFragment.kt
+++ b/app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageFragment.kt
@@ -1,9 +1,11 @@
package com.navinfo.volvo.ui.fragments.message
import android.content.DialogInterface
+import android.graphics.Paint
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
+import android.view.MotionEvent
import android.view.View
import android.view.View.*
import android.view.ViewGroup
@@ -13,12 +15,17 @@ import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.Navigation
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.easytools.tools.DateUtils
+import com.easytools.tools.DeviceUtils
+import com.easytools.tools.DisplayUtils
+import com.easytools.tools.FileUtils
+import com.easytools.tools.ResourceUtils
import com.easytools.tools.ToastUtils
import com.elvishew.xlog.XLog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -28,15 +35,18 @@ import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.navinfo.volvo.R
import com.navinfo.volvo.RecorderLifecycleObserver
+import com.navinfo.volvo.database.entity.Attachment
+import com.navinfo.volvo.database.entity.AttachmentType
+import com.navinfo.volvo.database.entity.GreetingMessage
import com.navinfo.volvo.databinding.FragmentObtainMessageBinding
-import com.navinfo.volvo.http.NavinfoVolvoCall
-import com.navinfo.volvo.model.Attachment
-import com.navinfo.volvo.model.AttachmentType
-import com.navinfo.volvo.model.Message
+import com.navinfo.volvo.http.DownloadCallback
import com.navinfo.volvo.ui.markRequiredInRed
+import com.navinfo.volvo.util.PhotoLoader
import com.navinfo.volvo.utils.EasyMediaFile
import com.navinfo.volvo.utils.SystemConstant
import com.nhaarman.supertooltips.ToolTip
+import indi.liyi.viewer.Utils
+import indi.liyi.viewer.ViewData
import top.zibin.luban.Luban
import top.zibin.luban.OnCompressListener
import java.io.File
@@ -56,6 +66,9 @@ class ObtainMessageFragment: Fragment() {
RecorderLifecycleObserver()
}
+ private val dateSendFormat = "yyyy-MM-dd HH:mm:ss"
+ private val dateShowFormat = "yyyy-MM-dd HH:mm"
+
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
@@ -68,67 +81,71 @@ class ObtainMessageFragment: Fragment() {
_binding = FragmentObtainMessageBinding.inflate(inflater, container, false)
val root: View = binding.root
- obtainMessageViewModel.setCurrentMessage(Message())
+ obtainMessageViewModel.setCurrentMessage(GreetingMessage())
obtainMessageViewModel?.getMessageLiveData()?.observe(
viewLifecycleOwner, Observer {
// 初始化界面显示内容
- if(it.title?.isNotEmpty() == true)
- binding.tvMessageTitle?.setText(it.title)
+ if(it.name?.isNotEmpty() == true)
+ binding.tvMessageTitle?.setText(it.name)
if (it.sendDate?.isNotEmpty() == true) {
// 获取当前发送时间,如果早于当前时间,则显示现在
- val sendDate = DateUtils.str2Date(it.sendDate, "yyyy-MM-dd HH:mm:ss")
+ val sendDate = DateUtils.str2Date(it.sendDate, dateSendFormat)
if (sendDate<=Date()) {
binding.btnSendTime.text = "现在"
} else {
binding.btnSendTime.text = it.sendDate
}
+ } else { // 如果发送时间此时为空,自动设置发送时间为当前时间
+ it.sendDate = DateUtils.date2Str(Date(), dateSendFormat)
}
var hasPhoto = false
var hasAudio = false
- if (it.attachment.isNotEmpty()) {
- // 展示照片文件或录音文件
- for (attachment in it.attachment) {
- if (attachment.attachmentType == AttachmentType.PIC) {
- Glide.with(context!!)
- .asBitmap().fitCenter()
- .load(attachment.pathUrl)
- .diskCacheStrategy(DiskCacheStrategy.ALL)
- .into(binding.imgMessageAttachment)
- // 显示名称
- hasPhoto = true
-
- // 如果当前attachment文件是本地文件,开始尝试网络上传
- val str = attachment.pathUrl.replace("\\", "/")
- if (!str.startsWith("http")) {
- obtainMessageViewModel.uploadAttachment(File(attachment.pathUrl), attachment.attachmentType)
- binding.tvPhotoName.text = str.substringAfterLast("/", "picture.jpg")
- } else {
- binding.tvPhotoName.text = str.substring(str.lastIndexOf("/"), str.indexOf("?"))
- }
- }
- if (attachment.attachmentType == AttachmentType.AUDIO) {
- hasAudio = true
-
- // 如果当前attachment文件是本地文件,开始尝试网络上传
- val str = attachment.pathUrl.replace("\\", "/")
- if (!str.startsWith("http")) {
- obtainMessageViewModel.uploadAttachment(File(attachment.pathUrl), attachment.attachmentType)
- binding.tvAudioName.text = str.substringAfterLast("/", "audio.m4a")
- } else {
- val str = attachment.pathUrl.replace("\\", "/")
- binding.tvAudioName.text = str.substring(str.lastIndexOf("/"), str.indexOf("?"))
- }
+ if (it.imageUrl!=null&&it.imageUrl?.isNotEmpty() == true) {
+ hasPhoto = true
+// Glide.with(this@ObtainMessageFragment)
+// .asBitmap().fitCenter()
+// .load(it.imageUrl)
+// .diskCacheStrategy(DiskCacheStrategy.ALL)
+// .into(binding.imgMessageAttachment)
+ // 如果当前attachment文件是本地文件,开始尝试网络上传
+ val str = it.imageUrl?.replace("\\", "/")
+ binding.tvPhotoName.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG )
+ if (!str!!.startsWith("http")) {
+ obtainMessageViewModel.uploadAttachment(File(it.imageUrl), AttachmentType.PIC)
+ binding.tvPhotoName.text = str.substringAfterLast("/", "picture.jpg")
+ } else {
+ if (str.contains("?")) {
+ binding.tvPhotoName.text = str.substring(str.lastIndexOf("/")+1, str.indexOf("?"))
+ } else {
+ binding.tvPhotoName.text = str.substringAfterLast("/")
}
}
+ }
- // 如果当前attachment不为空,可以显示预览按钮
+ if (it.mediaUrl!=null&&it.mediaUrl?.isNotEmpty() == true) {
+ hasAudio = true
+ binding.tvAudioName.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG )
+ // 如果当前attachment文件是本地文件,开始尝试网络上传
+ val str = it.mediaUrl?.replace("\\", "/")
+ if (!str!!.startsWith("http")) {
+ obtainMessageViewModel.uploadAttachment(File(it.mediaUrl),AttachmentType.AUDIO)
+ binding.tvAudioName.text = str.substringAfterLast("/", "audio.m4a")
+ } else {
+ if (str.contains("?")) {
+ binding.tvAudioName.text = str.substring(str.lastIndexOf("/")+1, str.indexOf("?"))
+ } else {
+ binding.tvAudioName.text = str.substringAfterLast("/")
+ }
+ }
}
binding.layerPhotoResult.visibility = if (hasPhoto) VISIBLE else GONE
binding.layerGetPhoto.visibility = if (hasPhoto) GONE else VISIBLE
- binding.imgMessageAttachment.visibility = if (hasPhoto) VISIBLE else GONE
+// binding.imgMessageAttachment.visibility = if (hasPhoto) VISIBLE else GONE
+
binding.layerAudioResult.visibility = if (hasAudio) VISIBLE else GONE
binding.layerGetAudio.visibility = if (hasAudio) GONE else VISIBLE
+ binding.llAudioPlay.visibility = if (hasAudio) VISIBLE else GONE
}
)
lifecycle.addObserver(recorderLifecycleObserver)
@@ -138,27 +155,21 @@ class ObtainMessageFragment: Fragment() {
fun initView() {
// 设置问候信息提示的红色星号
-// binding.tiLayoutTitle.markRequiredInRed()
-// binding.tvMessageTitle.addTextChangedListener(afterTextChanged = {
-// obtainMessageViewModel.updateMessageTitle(it.toString())
-// })
-
- binding.tvMessageTitle.setOnFocusChangeListener { view, b ->
- if (!b) {
- obtainMessageViewModel.updateMessageTitle(binding.tvMessageTitle.text.toString())
- }
- }
+ binding.tiLayoutTitle.markRequiredInRed()
+ binding.tvMessageTitle.addTextChangedListener(afterTextChanged = {
+ obtainMessageViewModel.getMessageLiveData().value?.name = it.toString()
+ })
binding.edtSendFrom.addTextChangedListener (afterTextChanged = {
- obtainMessageViewModel.updateMessageSendFrom(it.toString())
+ obtainMessageViewModel.getMessageLiveData().value?.who = it.toString()
})
binding.imgPhotoDelete.setOnClickListener {
- obtainMessageViewModel.updateMessagePic(null)
+ obtainMessageViewModel.updateMessagePic("")
}
binding.imgAudioDelete.setOnClickListener {
- obtainMessageViewModel.updateMessageAudio(null)
+ obtainMessageViewModel.updateMessageAudio("")
}
val sendToArray = mutableListOf("绑定车辆1(LYVXFEFEXNL754427)")
@@ -166,7 +177,7 @@ class ObtainMessageFragment: Fragment() {
android.R.layout.simple_dropdown_item_1line, android.R.id.text1, sendToArray)
binding.edtSendTo.onItemSelectedListener = object: OnItemSelectedListener {
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
- obtainMessageViewModel.getMessageLiveData().value?.toId = sendToArray[p2]
+ obtainMessageViewModel.getMessageLiveData().value?.toWho = sendToArray[p2]
}
override fun onNothingSelected(p0: AdapterView<*>?) {
@@ -179,11 +190,11 @@ class ObtainMessageFragment: Fragment() {
val dialog = DateTimePickerFragment.newInstance().mode(0)
dialog.listener = object : DateTimePickerFragment.OnClickListener {
override fun onClickListener(selectTime: String) {
- val sendDate = DateUtils.str2Date(selectTime, "yyyy-MM-dd HH:mm")
+ val sendDate = DateUtils.str2Date(selectTime, dateShowFormat)
if (sendDate <= Date()) {
- obtainMessageViewModel.updateMessageSendTime(DateUtils.date2Str(Date(), "yyyy-MM-dd HH:mm:ss"))
+ obtainMessageViewModel.updateMessageSendTime(DateUtils.date2Str(Date(), dateSendFormat))
} else {
- obtainMessageViewModel.updateMessageSendTime(DateUtils.date2Str(sendDate, "yyyy-MM-dd HH:mm:ss"))
+ obtainMessageViewModel.updateMessageSendTime(DateUtils.date2Str(sendDate, dateSendFormat))
}
}
@@ -231,10 +242,9 @@ class ObtainMessageFragment: Fragment() {
photoHelper.setCrop(false).selectAudio(activity!!)
}
- // 开始录音
- binding.btnStartRecord.setOnClickListener {
+ binding.btnStartRecord.setOnTouchListener { view, motionEvent ->
// 申请权限
- XXPermissions.with(this)
+ XXPermissions.with(this@ObtainMessageFragment)
// 申请单个权限
.permission(Permission.RECORD_AUDIO)
.request(object : OnPermissionCallback {
@@ -243,17 +253,23 @@ class ObtainMessageFragment: Fragment() {
Toast.makeText(activity, "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT).show()
return
}
-
- if (it.isSelected) {
- it.isSelected = false
- val recorderAudioPath = recorderLifecycleObserver.stopAndReleaseRecorder()
- if (File(recorderAudioPath).exists()) {
- obtainMessageViewModel.updateMessageAudio(recorderAudioPath)
+ when(motionEvent.action) {
+ MotionEvent.ACTION_DOWN-> {
+ // 申请权限
+ recorderLifecycleObserver.initAndStartRecorder()
+ ToastUtils.showToast("开始录音!")
+ false
+ }
+ MotionEvent.ACTION_UP -> {
+ val recorderAudioPath = recorderLifecycleObserver.stopAndReleaseRecorder()
+ if (File(recorderAudioPath).exists()) {
+ obtainMessageViewModel.updateMessageAudio(recorderAudioPath)
+ }
+ false
+ }
+ else -> {
+ false
}
- } else{
- it.isSelected = true
-
- recorderLifecycleObserver.initAndStartRecorder()
}
}
@@ -268,6 +284,7 @@ class ObtainMessageFragment: Fragment() {
}
}
})
+ false
}
// 获取照片文件和音频文件
@@ -296,8 +313,15 @@ class ObtainMessageFragment: Fragment() {
if (!it.absolutePath.equals(file?.absolutePath)) {
it?.delete()
}
- // 跳转回原Fragment,展示拍摄的照片
- ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java).updateMessagePic(file!!.absolutePath)
+ // 如果当前文件不在camera缓存文件夹下,则移动该文件
+ if (!file!!.parentFile.absolutePath.equals(SystemConstant.CameraFolder)) {
+ FileUtils.renameFile(file.absolutePath, File(SystemConstant.CameraFolder, fileName).absolutePath)
+ // 跳转回原Fragment,展示拍摄的照片
+ ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java).updateMessagePic(File(SystemConstant.CameraFolder, fileName).absolutePath)
+ } else {
+ // 跳转回原Fragment,展示拍摄的照片
+ ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java).updateMessagePic(file!!.absolutePath)
+ }
}
override fun onError(e: Throwable) {
@@ -306,7 +330,12 @@ class ObtainMessageFragment: Fragment() {
}).launch()
} else if (fileName.endsWith(".mp3")||fileName.endsWith(".wav")||fileName.endsWith(".amr")||fileName.endsWith(".m4a")) {
ToastUtils.showToast(it.absolutePath)
- obtainMessageViewModel.updateMessageAudio(it.absolutePath)
+ if (!it.parentFile.parentFile.absolutePath.equals(SystemConstant.SoundFolder)) {
+ FileUtils.renameFile(it.absolutePath, File(SystemConstant.SoundFolder, fileName).absolutePath)
+ obtainMessageViewModel.updateMessageAudio(File(SystemConstant.SoundFolder, fileName).absolutePath)
+ } else {
+ obtainMessageViewModel.updateMessageAudio(it.absolutePath)
+ }
}
}
@@ -315,76 +344,108 @@ class ObtainMessageFragment: Fragment() {
ToastUtils.showToast(it.message)
}
+ binding.voicePlayerView.setOnClickListener {
+ // 判断当前播放的文件是否在缓存文件夹内,如果不在首先下载该文件
+ val fileUrl = obtainMessageViewModel.getMessageLiveData().value!!.mediaUrl!!
+ val localFile = obtainMessageViewModel.getLocalFileFromNetUrl(fileUrl, AttachmentType.AUDIO)
+ if (!localFile.exists()) {
+ obtainMessageViewModel.downLoadFile(fileUrl, localFile, object: DownloadCallback {
+ override fun progress(progress: Int) {
+ }
+
+ override fun error(throwable: Throwable) {
+ }
+
+ override fun success(file: File) {
+ binding.voicePlayerView.setAudio(localFile.absolutePath)
+ }
+
+ })
+ } else {
+ binding.voicePlayerView.setAudio(localFile.absolutePath)
+ }
+ }
+
binding.btnObtainMessageBack.setOnClickListener {
Navigation.findNavController(it).popBackStack()
}
binding.btnObtainMessageConfirm.setOnClickListener {
var checkResult = true
+ val toolTipBackColor = ResourceUtils.getColor(R.color.teal_200)
+ val toolTipTextColor = ResourceUtils.getColor(R.color.black)
// 检查当前输入数据
val messageData = obtainMessageViewModel.getMessageLiveData().value
- if (messageData?.title?.isEmpty() == true) {
+ if (messageData?.name?.isEmpty() == true) {
val toolTipRelativeLayout =
binding.ttTitle
val toolTip = ToolTip()
.withText("请输入问候信息")
- .withColor(R.color.white)
- .withTextColor(R.color.black)
+ .withColor(toolTipBackColor)
+ .withTextColor(toolTipTextColor)
+ .withoutShadow()
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
toolTipRelativeLayout.showToolTipForView(toolTip, binding.tiLayoutTitle)
checkResult = false
- }
- var hasPic = false
- var hasAudio = false
- for (attachment in messageData?.attachment!!) {
- if (attachment.attachmentType == AttachmentType.PIC) {
- hasPic = true
- }
- if (attachment.attachmentType == AttachmentType.AUDIO) {
- hasAudio = true
+ } else {
+ if (messageData?.name!!.length>10) {
+ val toolTipRelativeLayout =
+ binding.ttTitle
+ val toolTip = ToolTip()
+ .withText("问候信息长度不能超过10")
+ .withColor(toolTipBackColor)
+ .withTextColor(toolTipTextColor)
+ .withoutShadow()
+ .withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
+ toolTipRelativeLayout.showToolTipForView(toolTip, binding.tiLayoutTitle)
+ checkResult = false
}
}
- if (!hasPic) {
+ if (messageData?.imageUrl?.isEmpty() == true) {
val toolTipRelativeLayout =
binding.ttPic
val toolTip = ToolTip()
.withText("需要提供照片文件")
- .withColor(R.color.white)
- .withTextColor(R.color.black)
+ .withColor(toolTipBackColor)
+ .withTextColor(toolTipTextColor)
+ .withoutShadow()
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
toolTipRelativeLayout.showToolTipForView(toolTip, binding.tvUploadPic)
checkResult = false
}
- if (!hasAudio) {
+ if (messageData?.mediaUrl?.isEmpty() == true) {
val toolTipRelativeLayout =
binding.ttAudio
val toolTip = ToolTip()
.withText("需要提供音频文件")
- .withColor(R.color.white)
- .withTextColor(R.color.black)
+ .withColor(toolTipBackColor)
+ .withTextColor(toolTipTextColor)
+ .withoutShadow()
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
toolTipRelativeLayout.showToolTipForView(toolTip, binding.tvUploadPic)
checkResult = false
}
- if (messageData?.fromId?.isEmpty()==true) {
+ if (messageData?.who?.isEmpty()==true) {
val toolTipRelativeLayout =
binding.ttSendFrom
val toolTip = ToolTip()
.withText("请输入您的名称")
- .withColor(R.color.white)
- .withTextColor(R.color.black)
+ .withColor(toolTipBackColor)
+ .withTextColor(toolTipTextColor)
+ .withoutShadow()
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
toolTipRelativeLayout.showToolTipForView(toolTip, binding.edtSendFrom)
checkResult = false
}
- if (messageData?.toId?.isEmpty()==true) {
+ if (messageData?.toWho?.isEmpty()==true) {
val toolTipRelativeLayout =
binding.ttSendTo
val toolTip = ToolTip()
.withText("请选择要发送的车辆")
- .withColor(R.color.white)
- .withTextColor(R.color.black)
+ .withColor(toolTipBackColor)
+ .withTextColor(toolTipTextColor)
+ .withoutShadow()
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
toolTipRelativeLayout.showToolTipForView(toolTip, binding.edtSendTo)
checkResult = false
@@ -393,10 +454,13 @@ class ObtainMessageFragment: Fragment() {
if (checkResult) { // 检查通过
// 检查attachment是否为本地数据,如果是本地则弹出对话框尝试上传
val localAttachmentList = mutableListOf()
- for (attachment in messageData?.attachment!!) {
- if (!attachment.pathUrl.startsWith("http")) {
- localAttachmentList.add(attachment)
- }
+ if (messageData?.imageUrl?.startsWith("http") == false) {
+ val imageAttachment = Attachment("", messageData.imageUrl!!, AttachmentType.PIC)
+ localAttachmentList.add(imageAttachment)
+ }
+ if (messageData?.mediaUrl?.startsWith("http") == false) {
+ val audioAttachment = Attachment("", messageData.mediaUrl!!, AttachmentType.AUDIO)
+ localAttachmentList.add(audioAttachment)
}
if (localAttachmentList.isNotEmpty()) {
MaterialAlertDialogBuilder(context!!)
@@ -408,21 +472,50 @@ class ObtainMessageFragment: Fragment() {
obtainMessageViewModel.uploadAttachment(File(attachment.pathUrl), attachment.attachmentType)
}
})
+ .setNegativeButton("取消", DialogInterface.OnClickListener {
+ dialogInterface, i -> dialogInterface.dismiss()
+ })
.show()
return@setOnClickListener
}
// 检查发送时间
-
+ val sendDate = DateUtils.str2Date(messageData?.sendDate, dateSendFormat)
+ val cal = Calendar.getInstance()
+ cal.time = Date()
+ cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE)+1)
+ if (cal.time.time < sendDate.time) { // 发送时间设置小于当前时间1分钟前,Toast提示用户并自动设置发送时间
+ messageData?.sendDate = DateUtils.date2Str(cal.time, dateSendFormat)
+ ToastUtils.showToast("自动调整发送时间为1分钟后发送")
+ }
// 开始网络提交数据
- if (obtainMessageViewModel.getMessageLiveData().value?.netId!!.isEmpty()) { // 如果网络id为空,则调用更新操作
+ if (obtainMessageViewModel.getMessageLiveData().value?.id==0L) { // 如果网络id为空,则调用更新操作
obtainMessageViewModel.insertCardByApp()
} else {
obtainMessageViewModel.updateCardByApp()
}
}
}
+ // 点击照片名称
+ binding.tvPhotoName.setOnClickListener {
+ val viewData = ViewData()
+ viewData.imageSrc = obtainMessageViewModel.getMessageLiveData().value!!.imageUrl
+ viewData.targetX = Utils.dp2px(context, 10F).toFloat()
+ viewData.targetWidth = DisplayUtils.getScreenWidthPixels(activity) - Utils.dp2px(context, 20F)
+ viewData.targetHeight = Utils.dp2px(context, 200F)
+ val viewDataList = listOf(viewData)
+ binding.imageViewer.overlayStatusBar(true) // ImageViewer 是否会占据 StatusBar 的空间
+ .viewData(viewDataList) // 图片数据
+ .imageLoader(PhotoLoader()) // 设置图片加载方式
+ .showIndex(true) // 是否显示图片索引,默认为true
+ .watch(0) // 开启浏览
+
+ }
+ // 点击音频名称
+ binding.tvAudioName.setOnClickListener {
+
+ }
}
override fun onDestroyView() {
diff --git a/app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageViewModel.kt b/app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageViewModel.kt
index 3a026b1..8d101db 100644
--- a/app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageViewModel.kt
+++ b/app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageViewModel.kt
@@ -1,12 +1,18 @@
package com.navinfo.volvo.ui.fragments.message
import androidx.lifecycle.*
+import com.easytools.tools.FileUtils
import com.easytools.tools.ToastUtils
import com.elvishew.xlog.XLog
+import com.navinfo.volvo.database.entity.Attachment
+import com.navinfo.volvo.database.entity.AttachmentType
+import com.navinfo.volvo.database.entity.GreetingMessage
+import com.navinfo.volvo.http.DownloadCallback
+import com.navinfo.volvo.http.DownloadManager
+import com.navinfo.volvo.http.DownloadState
import com.navinfo.volvo.http.NavinfoVolvoCall
-import com.navinfo.volvo.model.Attachment
-import com.navinfo.volvo.model.AttachmentType
-import com.navinfo.volvo.model.Message
+import com.navinfo.volvo.utils.SystemConstant
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
@@ -17,72 +23,74 @@ import java.util.*
class ObtainMessageViewModel: ViewModel() {
- private val msgLiveData: MutableLiveData by lazy {
- MutableLiveData()
+ private val msgLiveData: MutableLiveData by lazy {
+ MutableLiveData()
}
- fun setCurrentMessage(msg: Message) {
+ fun setCurrentMessage(msg: GreetingMessage) {
msgLiveData.postValue(msg)
}
- fun getMessageLiveData(): MutableLiveData {
+ fun getMessageLiveData(): MutableLiveData {
return msgLiveData
}
// 更新消息标题
fun updateMessageTitle(title: String) {
- this.msgLiveData.value?.title = title
+ this.msgLiveData.value?.name = title
this.msgLiveData.postValue(this.msgLiveData.value)
}
// 更新消息附件中的照片文件
fun updateMessagePic(picUrl: String?) {
- var hasPic = false
+// var hasPic = false
- for (attachment in this.msgLiveData.value!!.attachment) {
- if (attachment.attachmentType == AttachmentType.PIC) {
- if (picUrl==null||picUrl.isEmpty()) {
- this.msgLiveData.value!!.attachment.remove(attachment)
- } else {
- attachment.pathUrl = picUrl
- }
- hasPic = true
- }
- }
- if (!hasPic&&picUrl!=null) {
- this.msgLiveData.value!!.attachment.add(Attachment(UUID.randomUUID().toString(), picUrl, AttachmentType.PIC))
- }
+ this.msgLiveData.value?.imageUrl = picUrl
+// for (attachment in this.msgLiveData.value!!.attachment) {
+// if (attachment.attachmentType == AttachmentType.PIC) {
+// if (picUrl==null||picUrl.isEmpty()) {
+// this.msgLiveData.value!!.attachment.remove(attachment)
+// } else {
+// attachment.pathUrl = picUrl
+// }
+// hasPic = true
+// }
+// }
+// if (!hasPic&&picUrl!=null) {
+// this.msgLiveData.value!!.attachment.add(Attachment(UUID.randomUUID().toString(), picUrl, AttachmentType.PIC))
+// }
this.msgLiveData.postValue(this.msgLiveData.value)
}
// 更新消息附件中的录音文件
fun updateMessageAudio(audioUrl: String?) {
- var hasAudio = false
- for (attachment in this.msgLiveData.value!!.attachment) {
- if (attachment.attachmentType == AttachmentType.AUDIO) {
- if (audioUrl==null||audioUrl.isEmpty()) {
- this.msgLiveData.value!!.attachment.remove(attachment)
- } else {
- attachment.pathUrl = audioUrl
- }
- hasAudio = true
- }
- }
- if (!hasAudio&&audioUrl!=null) {
- this.msgLiveData.value!!.attachment.add(Attachment(UUID.randomUUID().toString(), audioUrl, AttachmentType.AUDIO))
- }
+// var hasAudio = false
+// for (attachment in this.msgLiveData.value!!.attachment) {
+// if (attachment.attachmentType == AttachmentType.AUDIO) {
+// if (audioUrl==null||audioUrl.isEmpty()) {
+// this.msgLiveData.value!!.attachment.remove(attachment)
+// } else {
+// attachment.pathUrl = audioUrl
+// }
+// hasAudio = true
+// }
+// }
+// if (!hasAudio&&audioUrl!=null) {
+// this.msgLiveData.value!!.attachment.add(Attachment(UUID.randomUUID().toString(), audioUrl, AttachmentType.AUDIO))
+// }
+ this.msgLiveData.value?.mediaUrl = audioUrl
this.msgLiveData.postValue(this.msgLiveData.value)
}
// 更新发送人
fun updateMessageSendFrom(sendFrom: String) {
- this.msgLiveData.value?.fromId = sendFrom
+ this.msgLiveData.value?.who = sendFrom
this.msgLiveData.postValue(this.msgLiveData.value)
}
// 更新接收人
fun updateMessageSendTo(sendTo: String) {
- this.msgLiveData.value?.toId = sendTo
+ this.msgLiveData.value?.toWho = sendTo
this.msgLiveData.postValue(this.msgLiveData.value)
}
@@ -92,30 +100,25 @@ class ObtainMessageViewModel: ViewModel() {
this.msgLiveData.postValue(this.msgLiveData.value)
}
- // 获取照片url
- fun getImageAttachment(attachementList: List): Attachment? {
- for (attachment in attachementList) {
- if (attachment.attachmentType == AttachmentType.PIC) {
- return attachment
- }
- }
- return null
- }
-
- // 获取音频url
- fun getAudioAttachment(attachementList: List): Attachment? {
- for (attachment in attachementList) {
- if (attachment.attachmentType == AttachmentType.AUDIO) {
- return attachment
- }
- }
- return null
- }
-
- // 获取发送时间
- fun getSendDate(){
-
- }
+// // 获取照片url
+// fun getImageAttachment(attachementList: List): Attachment? {
+// for (attachment in attachementList) {
+// if (attachment.attachmentType == AttachmentType.PIC) {
+// return attachment
+// }
+// }
+// return null
+// }
+//
+// // 获取音频url
+// fun getAudioAttachment(attachementList: List): Attachment? {
+// for (attachment in attachementList) {
+// if (attachment.attachmentType == AttachmentType.AUDIO) {
+// return attachment
+// }
+// }
+// return null
+// }
// 上传附件文件
fun uploadAttachment(attachmentFile: File, attachmentType: AttachmentType) {
@@ -130,6 +133,21 @@ class ObtainMessageViewModel: ViewModel() {
if (result.code == 200) { // 请求成功
// 获取上传后的结果
val fileKey = result.data?.get("fileKey")
+ val newFileName = fileKey!!.substringAfterLast("/")
+ // 修改缓存文件名
+ if (attachmentType == AttachmentType.PIC) { // 修改当前文件在缓存文件夹的名称
+ val destFile = File(SystemConstant.CameraFolder, newFileName)
+ if (destFile.exists()) {
+ FileUtils.deleteFile(destFile)
+ }
+ FileUtils.renameFile(attachmentFile.absolutePath, destFile.absolutePath)
+ } else {
+ val destFile = File(SystemConstant.SoundFolder, newFileName)
+ if (destFile.exists()) {
+ FileUtils.deleteFile(destFile)
+ }
+ FileUtils.renameFile(attachmentFile.absolutePath, destFile.absolutePath)
+ }
if (fileKey!=null) {
downloadAttachment(fileKey, attachmentType)
}
@@ -173,16 +191,41 @@ class ObtainMessageViewModel: ViewModel() {
}
}
+ fun downLoadFile(url: String, destFile: File, downloadCallback: DownloadCallback){
+ viewModelScope.launch {
+ DownloadManager.download(
+ url,
+ destFile
+ ).collect {
+ when (it) {
+ is DownloadState.InProgress -> {
+ XLog.d("~~~", "download in progress: ${it.progress}.")
+ downloadCallback.progress(it.progress)
+ }
+ is DownloadState.Success -> {
+ XLog.d("~~~", "download finished.")
+ downloadCallback.success(it.file)
+ }
+ is DownloadState.Error -> {
+ XLog.d("~~~", "download error: ${it.throwable}.")
+ downloadCallback.error(it.throwable)
+ }
+ }
+ }
+ }
+ }
+
fun insertCardByApp() {
viewModelScope.launch {
try {
+ // TODO 首先保存数据到本地
val message = msgLiveData.value
val insertData = mapOf(
- "name" to message?.title,
- "imageUrl" to getImageAttachment(message?.attachment!!)?.pathUrl,
- "mediaUrl" to getAudioAttachment(message?.attachment!!)?.pathUrl,
- "who" to message?.fromId,
- "toWho" to message?.toId,
+ "name" to message?.name,
+ "imageUrl" to message?.imageUrl,
+ "mediaUrl" to message?.mediaUrl,
+ "who" to message?.who,
+ "toWho" to message?.toWho,
"sendDate" to message?.sendDate
)
val result = NavinfoVolvoCall.getApi().insertCardByApp(insertData as Map)
@@ -190,8 +233,9 @@ class ObtainMessageViewModel: ViewModel() {
if (result.code == 200) { // 请求成功
// 获取上传后的结果
val netId = result.data
- message.netId = netId!!
- // 尝试保存数据到本地
+ message?.id = netId!!.toLong()
+ // TODO 尝试更新本地数据
+
} else {
ToastUtils.showToast(result.msg)
}
@@ -206,21 +250,21 @@ class ObtainMessageViewModel: ViewModel() {
viewModelScope.launch {
try {
val message = msgLiveData.value
- val insertData = mapOf(
- "id" to message?.netId,
- "name" to message?.title,
- "imageUrl" to getImageAttachment(message?.attachment!!)?.pathUrl,
- "mediaUrl" to getAudioAttachment(message?.attachment!!)?.pathUrl,
- "who" to message?.fromId,
- "toWho" to message?.toId,
+ val updateData = mapOf(
+ "id" to message?.id,
+ "name" to message?.name,
+ "imageUrl" to message?.imageUrl,
+ "mediaUrl" to message?.mediaUrl,
+ "who" to message?.who,
+ "toWho" to message?.toWho,
"sendDate" to message?.sendDate
)
- val result = NavinfoVolvoCall.getApi().updateCardByApp(insertData as Map)
+ val result = NavinfoVolvoCall.getApi().updateCardByApp(updateData as Map)
XLog.d("updateCardByApp:${result.code}")
if (result.code == 200) { // 请求成功
// 获取上传后的结果
val netId = result.data
- message.netId = netId!!
+ message?.id = netId!!.toLong()
// 尝试保存数据到本地
} else {
ToastUtils.showToast(result.msg)
@@ -231,4 +275,20 @@ class ObtainMessageViewModel: ViewModel() {
}
}
}
+
+ /**
+ * 根据网络地址获取本地的缓存文件路径
+ * */
+ fun getLocalFileFromNetUrl(url: String, attachmentType: AttachmentType):File {
+ val folder = when(attachmentType) {
+ AttachmentType.PIC-> SystemConstant.CameraFolder
+ else -> SystemConstant.SoundFolder
+ }
+ var name = if (url.contains("?")) {
+ url.substring(url.lastIndexOf("/")+1, url.indexOf("?"))
+ } else {
+ url.substringAfterLast("/")
+ }
+ return File(folder, name)
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/navinfo/volvo/util/PhotoLoader.java b/app/src/main/java/com/navinfo/volvo/util/PhotoLoader.java
new file mode 100644
index 0000000..6c69e64
--- /dev/null
+++ b/app/src/main/java/com/navinfo/volvo/util/PhotoLoader.java
@@ -0,0 +1,50 @@
+package com.navinfo.volvo.util;
+
+import android.graphics.drawable.Drawable;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.target.CustomViewTarget;
+import com.bumptech.glide.request.transition.Transition;
+
+import indi.liyi.viewer.ImageLoader;
+
+public class PhotoLoader extends ImageLoader {
+ @Override
+ public void displayImage(final Object src, ImageView imageView, final LoadCallback callback) {
+ Glide.with(imageView.getContext())
+ .load(src)
+ .into(new CustomViewTarget(imageView) {
+
+ @Override
+ protected void onResourceLoading(@Nullable Drawable placeholder) {
+ super.onResourceLoading(placeholder);
+ if(callback!=null){
+ callback.onLoadStarted(placeholder);
+ }
+ }
+
+ @Override
+ public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
+ if(callback!=null) {
+ callback.onLoadSucceed(resource);
+ }
+ }
+
+ @Override
+ public void onLoadFailed(@Nullable Drawable errorDrawable) {
+ if(callback!=null) {
+ callback.onLoadFailed(errorDrawable);
+ }
+ }
+
+ @Override
+ protected void onResourceCleared(@Nullable Drawable placeholder) {
+
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/com/navinfo/volvo/utils/EasyMediaFile.kt b/app/src/main/java/com/navinfo/volvo/utils/EasyMediaFile.kt
index e04f57d..eebd1cf 100644
--- a/app/src/main/java/com/navinfo/volvo/utils/EasyMediaFile.kt
+++ b/app/src/main/java/com/navinfo/volvo/utils/EasyMediaFile.kt
@@ -131,7 +131,7 @@ class EasyMediaFile {
* 选择文件
*/
private fun selectFileInternal(intent: Intent, activity: Activity, type: Int) {
- val resolveInfoList = activity.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
+ var resolveInfoList = activity.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
if (resolveInfoList.isEmpty()) {
error?.invoke(IllegalStateException("No Activity found to handle Intent "))
} else {
diff --git a/app/src/main/res/layout/fragment_obtain_message.xml b/app/src/main/res/layout/fragment_obtain_message.xml
index b40c6bb..77f28cc 100644
--- a/app/src/main/res/layout/fragment_obtain_message.xml
+++ b/app/src/main/res/layout/fragment_obtain_message.xml
@@ -121,9 +121,10 @@
android:orientation="horizontal">
+ android:layout_weight="1">
@@ -147,7 +148,6 @@
@@ -156,6 +156,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
+ android:layout_marginVertical="@dimen/default_widget_padding"
android:orientation="horizontal">
-
+
+ android:orientation="horizontal">
+
+
+
@@ -283,7 +306,6 @@
@@ -379,4 +401,11 @@
android:layout_weight="1"
android:text="确认提交">
+
+
\ No newline at end of file