diff --git a/app/build.gradle b/app/build.gradle index a6212aa7..9de2554f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,7 @@ plugins { id 'kotlin-kapt' id 'com.google.dagger.hilt.android' id 'realm-android' + id 'kotlin-parcelize' // 序列化 } android { namespace 'com.navinfo.omqs' @@ -11,7 +12,7 @@ android { defaultConfig { applicationId "com.navinfo.omqs" - minSdk 24 + minSdk 26 targetSdk 33 versionCode 1 versionName "1.0" @@ -36,14 +37,17 @@ android { viewBinding true dataBinding true } + } + + dependencies { implementation project(':collect-library') - implementation 'androidx.core:core-ktx:1.7.0' + implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.5.0' + implementation 'com.google.android.material:material:1.8.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3' implementation 'androidx.navigation:navigation-ui-ktx:2.5.3' @@ -55,17 +59,26 @@ dependencies { // 文件管理 https://github.com/K1rakishou/Fuck-Storage-Access-Framework implementation 'com.github.K1rakishou:Fuck-Storage-Access-Framework:v1.1.3' // Android工具类库 https://blankj.com/2016/07/31/android-utils-code/ - implementation 'com.blankj:utilcodex:1.30.1' + implementation 'com.blankj:utilcodex:1.31.1' //依赖注入 //hilt - implementation "com.google.dagger:hilt-android:2.44" - kapt "com.google.dagger:hilt-compiler:2.44" + implementation 'com.google.dagger:hilt-android:2.45' + kapt 'com.google.dagger:hilt-compiler:2.45' // Retrofit 网络请求相关 implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") - implementation("com.squareup.okhttp3:okhttp:4.9.0") - implementation("com.squareup.okhttp3:logging-interceptor:4.9.0") + implementation('com.squareup.okhttp3:okhttp:5.0.0-alpha.11') + implementation('com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.11') + + kapt 'android.arch.persistence.room:compiler:1.1.1'// compiler 需要用 room 的 + kapt "androidx.room:room-compiler:2.5.1" + kapt "androidx.room:room-ktx:2.5.1" + + //读取excel word等文件 + implementation 'org.apache.poi:poi:5.2.3' + implementation 'org.apache.poi:poi-ooxml:5.2.3' + } //允许引用生成的代码 kapt { diff --git a/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt b/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt index 27e26fa3..48dce657 100644 --- a/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt +++ b/app/src/main/java/com/navinfo/omqs/OMQSApplication.kt @@ -5,6 +5,7 @@ import android.util.Log import com.navinfo.omqs.tools.FileManager import dagger.hilt.android.HiltAndroidApp import io.realm.Realm +import io.realm.RealmConfiguration import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import java.io.File @@ -12,7 +13,17 @@ import java.io.File @HiltAndroidApp class OMQSApplication : Application() { override fun onCreate() { - FileManager.initRootDir(this) super.onCreate() + FileManager.initRootDir(this) + Realm.init(this) + val password = "password".encodeToByteArray().copyInto(ByteArray(64)) + // 1110000011000010111001101110011011101110110111101110010011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +// Log.d("", "密码是: ${BigInteger(1, password).toString(2).padStart(64, '0')}") + val config = RealmConfiguration.Builder() + .directory(File(Constant.DATA_PATH)) + .name("HDData") +// .encryptionKey(password) + .build() + Realm.setDefaultConfiguration(config) } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/bean/BaseBean.kt b/app/src/main/java/com/navinfo/omqs/bean/BaseBean.kt new file mode 100644 index 00000000..cedc7591 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/bean/BaseBean.kt @@ -0,0 +1,6 @@ +package com.navinfo.omqs.bean + +import java.io.Serializable + +open class BaseBean : Serializable, Cloneable { +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/bean/OfflineMapCityBean.kt b/app/src/main/java/com/navinfo/omqs/bean/OfflineMapCityBean.kt new file mode 100644 index 00000000..cb269e60 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/bean/OfflineMapCityBean.kt @@ -0,0 +1,57 @@ +package com.navinfo.omqs.bean + +import android.os.Parcelable +import androidx.room.Entity +import androidx.room.PrimaryKey +import kotlinx.parcelize.Parcelize + + +@Entity(tableName = "OfflineMapCity") +@Parcelize +data class OfflineMapCityBean @JvmOverloads constructor( + @PrimaryKey + var id: String = "", + var fileName: String = "", + var name: String = "", + var url: String = "", + var version: Long = 0L, + var fileSize: Long = 0L, + var currentSize: Long = 0L, + var status: Int = NONE +) : Parcelable { + + companion object Status { + const val NONE = 0 //无状态 + const val WAITING = 1 //等待中 + const val LOADING = 2 //下载中 + const val PAUSE = 3 //暂停 + const val ERROR = 4 //错误 + const val DONE = 5 //完成 + const val UPDATE = 6 //有新版本要更新 + } + +// // status的转换对象 +// var statusEnum: StatusEnum +// get() { +// return try { +// StatusEnum.values().find { it.status == status }!! +// } catch (e: IllegalArgumentException) { +// StatusEnum.NONE +// } +// } +// set(value) { +// status = value.status +// } + + fun getFileSizeText(): String { + return if (fileSize < 1024.0) + "$fileSize B" + else if (fileSize < 1048576.0) + "%.2f K".format(fileSize / 1024.0) + else if (fileSize < 1073741824.0) + "%.2f M".format(fileSize / 1048576.0) + else + "%.2f M".format(fileSize / 1073741824.0) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/bean/QsRecord.kt b/app/src/main/java/com/navinfo/omqs/bean/QsRecord.kt new file mode 100644 index 00000000..ecac7094 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/bean/QsRecord.kt @@ -0,0 +1,115 @@ +package com.navinfo.omqs.bean + +import io.realm.RealmObject +import io.realm.annotations.PrimaryKey + + +/** + * @author zhjch + * @version V1.0 + * @ClassName: Rd_qcRecord + * @Date 2016/1/12 + * @Description: ${TODO}(质检对象) + */ +open class QsRecord @JvmOverloads constructor( + /** + * id 主键 + * + */ + @PrimaryKey var id: String = "", + /** + * linkPid 绑定的道路ID + */ + var linkPid: String = "", + /** + *问题分类 + */ + var classType: String = "", + /** + * 问题类型 + */ + var type: String = "", + + /** + * 问题现象 + */ + var phenomenon: String = "", + /** + * 问题描述 + */ + var description: String = "", + /** + * 设置initial_cause + * @param initial_cause + * initial_cause + */ +// var initial_cause: String? = StringEntity.STRING_DEFAULT +// /** +// * 获取root_cause +// * @return root_cause +// */ +// /** +// * 设置root_cause +// * @param root_cause +// * root_cause +// */ +////根本原因(RCA) +// var root_cause: String? = StringEntity.STRING_DEFAULT +// /** +// * 获取check_userid +// * @return check_userid +// */ +// /** +// * 设置check_userid +// * @param check_userid +// * check_userid +// */ +////质检员 +// var check_userid: String? = StringEntity.STRING_DEFAULT +// /** +// * 获取check_time +// * @return check_time +// */ +// /** +// * 设置check_time +// * @param check_time +// * check_time +// */ +////质检日期 +// var check_time: String? = StringEntity.STRING_DEFAULT +// /** +// * 获取confirm_userid +// * @return confirm_userid +// */ +// /** +// * 设置confirm_userid +// * @param confirm_userid +// * confirm_userid +// */ +////确认人 +// var confirm_userid: String? = StringEntity.STRING_DEFAULT +// /** +// * 获取t_lifecycle +// * @return t_lifecycle +// */ +// /** +// * 设置t_lifecycle +// * @param t_lifecycle +// * t_lifecycle +// */ +////状态 0 无; 1 删除;2 更新;3 新增; +// var t_lifecycle = 0 +// /** +// * 获取t_status +// * @return t_status +// */ +// /** +// * 设置t_status +// * @param t_status +// * t_status +// */ +////问题记录提交状态 0 未提交;1 已提交; +// var t_status = 0 +) : RealmObject( + +) \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/bean/ScProblemTypeBean.kt b/app/src/main/java/com/navinfo/omqs/bean/ScProblemTypeBean.kt new file mode 100644 index 00000000..4ce71de7 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/bean/ScProblemTypeBean.kt @@ -0,0 +1,30 @@ +package com.navinfo.omqs.bean + +import android.os.Parcelable +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import kotlinx.parcelize.Parcelize + +@Entity(tableName = "ScProblemType") +@Parcelize +data class ScProblemTypeBean( + @PrimaryKey(autoGenerate = true) + var id: Long = 0, + /** + * 问题分类 + */ + @ColumnInfo("CLASS_TYPE") + var classType: String = "", + /** + * 问题类型 + */ + @ColumnInfo("TYPE") + var problemType: String = "", + /** + * 问题现象 + */ + @ColumnInfo("PHENOMENON") + var phenomenon: String = "" + +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/bean/ScRootCauseAnalysisBean.kt b/app/src/main/java/com/navinfo/omqs/bean/ScRootCauseAnalysisBean.kt new file mode 100644 index 00000000..221aeb89 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/bean/ScRootCauseAnalysisBean.kt @@ -0,0 +1,24 @@ +package com.navinfo.omqs.bean + +import android.os.Parcelable +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import kotlinx.parcelize.Parcelize + +@Entity(tableName = "ScRootCauseAnalysis") +@Parcelize +data class ScRootCauseAnalysisBean( + @PrimaryKey(autoGenerate = true) + var id: Long = 0, + /** + * 问题环节 + */ + @ColumnInfo("PROBLEM_LINK") + var problemLink: String = "", + /** + * 问题原因 + */ + @ColumnInfo("PROBLEM_CAUSE") + var problemCause: String = "", +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt b/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt new file mode 100644 index 00000000..260df186 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/db/RoomAppDatabase.kt @@ -0,0 +1,21 @@ +package com.navinfo.omqs.db + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.navinfo.omqs.bean.OfflineMapCityBean +import com.navinfo.omqs.bean.ScProblemTypeBean +import com.navinfo.omqs.bean.ScRootCauseAnalysisBean +import com.navinfo.omqs.db.dao.OfflineMapDao +import com.navinfo.omqs.db.dao.ScProblemTypeDao +import com.navinfo.omqs.db.dao.ScRootCauseAnalysisDao + +@Database( + entities = [OfflineMapCityBean::class, ScProblemTypeBean::class, ScRootCauseAnalysisBean::class], + version = 1, + exportSchema = false +) +abstract class RoomAppDatabase : RoomDatabase() { + abstract fun getOfflineMapDao(): OfflineMapDao + abstract fun getScProblemTypeDao(): ScProblemTypeDao + abstract fun getScRootCauseAnalysisDao(): ScRootCauseAnalysisDao +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/db/dao/OfflineMapDao.kt b/app/src/main/java/com/navinfo/omqs/db/dao/OfflineMapDao.kt new file mode 100644 index 00000000..f1256c9c --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/db/dao/OfflineMapDao.kt @@ -0,0 +1,23 @@ +package com.navinfo.omqs.db.dao + +import androidx.room.* +import com.navinfo.omqs.bean.OfflineMapCityBean + +@Dao +interface OfflineMapDao { + + @Insert + suspend fun insert(message: OfflineMapCityBean): Long + + @Update(onConflict = OnConflictStrategy.REPLACE) + suspend fun update(message: OfflineMapCityBean) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertOrUpdate(list: List) + + @Query("select * from OfflineMapCity order by id") + suspend fun getOfflineMapList(): List + + @Query("select * from OfflineMapCity where status != 0 order by id") + suspend fun getOfflineMapListWithOutNone(): List +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/db/dao/ScProblemTypeDao.kt b/app/src/main/java/com/navinfo/omqs/db/dao/ScProblemTypeDao.kt new file mode 100644 index 00000000..5c4b4351 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/db/dao/ScProblemTypeDao.kt @@ -0,0 +1,50 @@ +package com.navinfo.omqs.db.dao + +import androidx.room.* +import androidx.sqlite.db.SupportSQLiteDatabase +import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase.getDatabase +import com.navinfo.omqs.bean.ScProblemTypeBean + + +@Dao +interface ScProblemTypeDao { +// @Insert(onConflict = OnConflictStrategy.REPLACE) +// suspend fun insert(bean: ScProblemTypeBean): Long + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertList(list: List) + + + @Query("delete from ScProblemType") + suspend fun deleteAll() + + /** + * 更新整个数据库表,由于没有 + */ + @Transaction + suspend fun insertOrUpdateList(list: List) { + //先删除 + deleteAll() + //后插入 + insertList(list) + } + + /** + * 获取问题分类,并去重 + */ + @Query("select DISTINCT CLASS_TYPE from ScProblemType order by CLASS_TYPE") + suspend fun findClassTypeList(): List? + + /** + * 获取问题类型,并去重 + */ + @Query("select DISTINCT TYPE from ScProblemType where CLASS_TYPE=:type order by TYPE") + suspend fun findProblemTypeList(type: String): List + + /** + * + */ + @Query("select PHENOMENON from ScProblemType where CLASS_TYPE=:classType and TYPE=:type order by PHENOMENON") + suspend fun getPhenomenonList(classType: String, type: String): List + +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/db/dao/ScRootCauseAnalysisDao.kt b/app/src/main/java/com/navinfo/omqs/db/dao/ScRootCauseAnalysisDao.kt new file mode 100644 index 00000000..c10a5b68 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/db/dao/ScRootCauseAnalysisDao.kt @@ -0,0 +1,25 @@ +package com.navinfo.omqs.db.dao + +import androidx.room.* +import com.navinfo.omqs.bean.ScRootCauseAnalysisBean + + +@Dao +interface ScRootCauseAnalysisDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertList(list: List) + + + @Query("delete from ScRootCauseAnalysis") + suspend fun deleteAll() + + @Transaction + suspend fun insertOrUpdateList(list: List) { + //先删除 + deleteAll() + //后插入 + insertList(list) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt b/app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt index 4ace2b64..c3478149 100644 --- a/app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt +++ b/app/src/main/java/com/navinfo/omqs/hilt/GlobalModule.kt @@ -1,12 +1,16 @@ package com.navinfo.omqs.hilt import android.app.Application +import android.content.Context import android.util.Log +import androidx.room.Room import com.google.gson.Gson import com.navinfo.omqs.Constant import com.navinfo.omqs.OMQSApplication +import com.navinfo.omqs.db.RoomAppDatabase import com.navinfo.omqs.http.RetrofitNetworkServiceAPI -import com.navinfo.omqs.tools.RealmCoroutineScope +import com.tencent.wcdb.database.SQLiteCipherSpec +import com.tencent.wcdb.room.db.WCDBOpenHelperFactory import dagger.Lazy import dagger.Module import dagger.Provides @@ -95,12 +99,41 @@ class GlobalModule { return retrofit.create(RetrofitNetworkServiceAPI::class.java) } - /** - * realm 注册 - */ - @Provides @Singleton - fun provideRealmService(context: Application): RealmCoroutineScope { - return RealmCoroutineScope(context) + @Provides + fun provideDatabase(context: Application): RoomAppDatabase { + val DB_PASSWORD = "123456"; + val cipherSpec = SQLiteCipherSpec() + .setPageSize(1024) + .setSQLCipherVersion(3) + val factory = WCDBOpenHelperFactory() +// .passphrase(DB_PASSWORD.toByteArray()) // 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 + + return Room.databaseBuilder( + context, + RoomAppDatabase::class.java, + "${Constant.DATA_PATH}/omqs.db" + ) + + // [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(); } + +// /** +// * realm 注册 +// */ +// @Provides +// @Singleton +// fun provideRealmService(context: Application): RealmCoroutineScope { +// return RealmCoroutineScope(context) +// } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/hilt/MainActivityModule.kt b/app/src/main/java/com/navinfo/omqs/hilt/MainActivityModule.kt index 8560c38b..a2630bda 100644 --- a/app/src/main/java/com/navinfo/omqs/hilt/MainActivityModule.kt +++ b/app/src/main/java/com/navinfo/omqs/hilt/MainActivityModule.kt @@ -1,9 +1,9 @@ package com.navinfo.omqs.hilt import com.navinfo.collect.library.map.NIMapController +import com.navinfo.omqs.db.RoomAppDatabase import com.navinfo.omqs.http.RetrofitNetworkServiceAPI import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager -import com.navinfo.omqs.tools.RealmCoroutineScope import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -28,9 +28,10 @@ class MainActivityModule { @Provides fun providesOfflineMapDownloadManager( networkServiceAPI: RetrofitNetworkServiceAPI, - realmManager: RealmCoroutineScope + roomAppDatabase: RoomAppDatabase, + mapController: NIMapController ): OfflineMapDownloadManager = - OfflineMapDownloadManager(networkServiceAPI, realmManager) + OfflineMapDownloadManager(networkServiceAPI, roomAppDatabase, mapController) /** * 实验失败,这样创建,viewmodel不会在activity销毁的时候同时销毁 diff --git a/app/src/main/java/com/navinfo/omqs/http/NetworkService.kt b/app/src/main/java/com/navinfo/omqs/http/NetworkService.kt index eb4a6103..fde1d736 100644 --- a/app/src/main/java/com/navinfo/omqs/http/NetworkService.kt +++ b/app/src/main/java/com/navinfo/omqs/http/NetworkService.kt @@ -1,6 +1,6 @@ package com.navinfo.omqs.http -import com.navinfo.collect.library.data.entity.OfflineMapCityBean +import com.navinfo.omqs.bean.OfflineMapCityBean /** diff --git a/app/src/main/java/com/navinfo/omqs/http/NetworkServiceImpl.kt b/app/src/main/java/com/navinfo/omqs/http/NetworkServiceImpl.kt index bbcafc3e..4a67bf83 100644 --- a/app/src/main/java/com/navinfo/omqs/http/NetworkServiceImpl.kt +++ b/app/src/main/java/com/navinfo/omqs/http/NetworkServiceImpl.kt @@ -1,6 +1,6 @@ package com.navinfo.omqs.http -import com.navinfo.collect.library.data.entity.OfflineMapCityBean +import com.navinfo.omqs.bean.OfflineMapCityBean import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import javax.inject.Inject diff --git a/app/src/main/java/com/navinfo/omqs/http/RetrofitNetworkServiceAPI.kt b/app/src/main/java/com/navinfo/omqs/http/RetrofitNetworkServiceAPI.kt index 4bea1858..c4463b6d 100644 --- a/app/src/main/java/com/navinfo/omqs/http/RetrofitNetworkServiceAPI.kt +++ b/app/src/main/java/com/navinfo/omqs/http/RetrofitNetworkServiceAPI.kt @@ -1,6 +1,6 @@ package com.navinfo.omqs.http -import com.navinfo.collect.library.data.entity.OfflineMapCityBean +import com.navinfo.omqs.bean.OfflineMapCityBean import okhttp3.ResponseBody import retrofit2.Response import retrofit2.http.GET diff --git a/app/src/main/java/com/navinfo/omqs/http/offlinemapdownload/OfflineMapDownloadManager.kt b/app/src/main/java/com/navinfo/omqs/http/offlinemapdownload/OfflineMapDownloadManager.kt index e4aa57e1..87907e6e 100644 --- a/app/src/main/java/com/navinfo/omqs/http/offlinemapdownload/OfflineMapDownloadManager.kt +++ b/app/src/main/java/com/navinfo/omqs/http/offlinemapdownload/OfflineMapDownloadManager.kt @@ -2,16 +2,19 @@ package com.navinfo.omqs.http.offlinemapdownload import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.Observer -import com.navinfo.collect.library.data.entity.OfflineMapCityBean +import com.navinfo.collect.library.map.NIMapController +import com.navinfo.omqs.db.RoomAppDatabase +import com.navinfo.omqs.bean.OfflineMapCityBean import com.navinfo.omqs.http.RetrofitNetworkServiceAPI -import com.navinfo.omqs.tools.RealmCoroutineScope import java.util.concurrent.ConcurrentHashMap /** * 管理离线地图下载 */ class OfflineMapDownloadManager( - val netApi: RetrofitNetworkServiceAPI, val realmManager: RealmCoroutineScope + val netApi: RetrofitNetworkServiceAPI, + val roomDatabase: RoomAppDatabase, + val mapController: NIMapController ) { /** * 最多同时下载数量 diff --git a/app/src/main/java/com/navinfo/omqs/http/offlinemapdownload/OfflineMapDownloadScope.kt b/app/src/main/java/com/navinfo/omqs/http/offlinemapdownload/OfflineMapDownloadScope.kt index 0821f8c0..0e133dff 100644 --- a/app/src/main/java/com/navinfo/omqs/http/offlinemapdownload/OfflineMapDownloadScope.kt +++ b/app/src/main/java/com/navinfo/omqs/http/offlinemapdownload/OfflineMapDownloadScope.kt @@ -4,8 +4,8 @@ import android.util.Log import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer -import com.navinfo.collect.library.data.entity.OfflineMapCityBean import com.navinfo.omqs.Constant +import com.navinfo.omqs.bean.OfflineMapCityBean import kotlinx.coroutines.* import java.io.File import java.io.IOException @@ -32,8 +32,8 @@ class OfflineMapDownloadScope( /** * 管理观察者,同时只有一个就行了 */ -// private var observer: Observer? = null - private var lifecycleOwner: LifecycleOwner? = null + private val observer = Observer {} +// private var lifecycleOwner: LifecycleOwner? = null /** *通知UI更新 @@ -89,10 +89,10 @@ class OfflineMapDownloadScope( if (cityBean.status != status || status == OfflineMapCityBean.LOADING) { cityBean.status = status downloadData.postValue(cityBean) - - downloadManager.realmManager.launch { - downloadManager.realmManager.insertOrUpdate(cityBean) + launch(Dispatchers.IO) { + downloadManager.roomDatabase.getOfflineMapDao().update(cityBean) } + } } @@ -101,7 +101,7 @@ class OfflineMapDownloadScope( */ fun observer(owner: LifecycleOwner, ob: Observer) { removeObserver() - this.lifecycleOwner = owner +// this.lifecycleOwner = owner downloadData.observe(owner, ob) } @@ -156,6 +156,9 @@ class OfflineMapDownloadScope( fileTemp.renameTo(File("${Constant.OFFLINE_MAP_PATH}${cityBean.fileName}")) Log.e("jingo", "文件下载完成 修改文件 $res") change(OfflineMapCityBean.DONE) + withContext(Dispatchers.Main) { + downloadManager.mapController.layerManagerHandler.loadBaseMap() + } } else { change(OfflineMapCityBean.PAUSE) } @@ -168,9 +171,10 @@ class OfflineMapDownloadScope( } fun removeObserver() { - lifecycleOwner?.let { - downloadData.removeObservers(it) - null - } + downloadData.observeForever(observer) +// lifecycleOwner?.let { + downloadData.removeObserver(observer) +// null +// } } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/tools/FileManager.kt b/app/src/main/java/com/navinfo/omqs/tools/FileManager.kt index e40972ee..0f0c0244 100644 --- a/app/src/main/java/com/navinfo/omqs/tools/FileManager.kt +++ b/app/src/main/java/com/navinfo/omqs/tools/FileManager.kt @@ -1,9 +1,8 @@ package com.navinfo.omqs.tools import android.content.Context -import android.util.Log -import com.navinfo.collect.library.data.entity.OfflineMapCityBean import com.navinfo.omqs.Constant +import com.navinfo.omqs.bean.OfflineMapCityBean import java.io.File class FileManager { diff --git a/app/src/main/java/com/navinfo/omqs/tools/RealmCoroutineScope.kt b/app/src/main/java/com/navinfo/omqs/tools/RealmCoroutineScope.kt index 70880896..e3f6a76f 100644 --- a/app/src/main/java/com/navinfo/omqs/tools/RealmCoroutineScope.kt +++ b/app/src/main/java/com/navinfo/omqs/tools/RealmCoroutineScope.kt @@ -1,57 +1,47 @@ -package com.navinfo.omqs.tools - -import android.app.Application -import com.navinfo.collect.library.data.entity.OfflineMapCityBean -import com.navinfo.omqs.Constant -import io.realm.Realm -import io.realm.RealmConfiguration -import io.realm.RealmModel -import io.realm.Sort -import io.realm.kotlin.where -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.newSingleThreadContext -import java.io.File - -class RealmCoroutineScope(context: Application) : - CoroutineScope by CoroutineScope(newSingleThreadContext("RealmThread")) { - lateinit var realm: Realm - - init { - launch { - Realm.init(context) - val password = "password".encodeToByteArray().copyInto(ByteArray(64)) - // 1110000011000010111001101110011011101110110111101110010011001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -// Log.d("", "密码是: ${BigInteger(1, password).toString(2).padStart(64, '0')}") - val config = RealmConfiguration.Builder() - .directory(File(Constant.DATA_PATH)) - .name("HDData") -// .encryptionKey(password) - .build() - Realm.setDefaultConfiguration(config) - realm = Realm.getDefaultInstance() - } - } - - suspend fun getOfflineCityList(): List { - var list: List = mutableListOf() - realm.executeTransaction { - val objects = realm.where().findAll().sort("id", Sort.ASCENDING) - list = realm.copyFromRealm(objects) - } - return list - } - - suspend fun insertOrUpdate(objects: Collection?) { - realm.executeTransaction { - realm.insertOrUpdate(objects) - } - } - - suspend fun insertOrUpdate(realmModel: RealmModel?) { - realm.executeTransaction { - realm.insertOrUpdate(realmModel) - } - } - -} \ No newline at end of file +//package com.navinfo.omqs.tools +// +//import android.app.Application +//import com.navinfo.collect.library.data.entity.OfflineMapCityBean +//import com.navinfo.omqs.Constant +//import io.realm.Realm +//import io.realm.RealmConfiguration +//import io.realm.RealmModel +//import io.realm.Sort +//import io.realm.kotlin.where +//import kotlinx.coroutines.CoroutineScope +//import kotlinx.coroutines.launch +//import kotlinx.coroutines.newSingleThreadContext +//import java.io.File +// +//class RealmCoroutineScope(context: Application) : +// CoroutineScope by CoroutineScope(newSingleThreadContext("RealmThread")) { +// lateinit var realm: Realm +// +// init { +// launch { +// realm = Realm.getDefaultInstance() +// } +// } +// +// suspend fun getOfflineCityList(): List { +// var list: List = mutableListOf() +// realm.executeTransaction { +// val objects = realm.where().findAll().sort("id", Sort.ASCENDING) +// list = realm.copyFromRealm(objects) +// } +// return list +// } +// +// suspend fun insertOrUpdate(objects: Collection?) { +// realm.executeTransaction { +// realm.insertOrUpdate(objects) +// } +// } +// +// suspend fun insertOrUpdate(realmModel: RealmModel?) { +// realm.executeTransaction { +// realm.insertOrUpdate(realmModel) +// } +// } +// +//} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/MainActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/MainActivity.kt deleted file mode 100644 index 6bad71e2..00000000 --- a/app/src/main/java/com/navinfo/omqs/ui/MainActivity.kt +++ /dev/null @@ -1,84 +0,0 @@ -package com.navinfo.omqs.ui - -import android.content.Intent -import android.os.Bundle -import androidx.core.view.WindowCompat -import androidx.navigation.ui.AppBarConfiguration -import com.github.k1rakishou.fsaf.FileChooser -import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks -import com.navinfo.omqs.databinding.ActivityMainBinding -import com.navinfo.omqs.ui.activity.PermissionsActivity - -class MainActivity : PermissionsActivity(), FSAFActivityCallbacks { - - private lateinit var appBarConfiguration: AppBarConfiguration - private lateinit var binding: ActivityMainBinding - private val fileChooser by lazy { FileChooser(this@MainActivity) } - - override fun onCreate(savedInstanceState: Bundle?) { - WindowCompat.setDecorFitsSystemWindows(window, false) - super.onCreate(savedInstanceState) - - binding = ActivityMainBinding.inflate(layoutInflater) - setContentView(binding.root) - -// val navController = findNavController(R.id.nav_host_fragment_content_main) -// appBarConfiguration = AppBarConfiguration(navController.graph) -// setupActionBarWithNavController(navController, appBarConfiguration) - - fileChooser.setCallbacks(this@MainActivity) -// binding.fab.setOnClickListener { view -> -// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) -// .setAnchorView(R.id.fab) -// .setAction("Action", null).show() -// // 开始数据导入功能 -// fileChooser.openChooseFileDialog(object: FileChooserCallback() { -// override fun onCancel(reason: String) { -// } -// -// override fun onResult(uri: Uri) { -// val file = UriUtils.uri2File(uri) -// Snackbar.make(view, "文件大小为:${file.length()}", Snackbar.LENGTH_LONG) -// .show() -// } -// }) -// } - } - - override fun onPermissionsGranted() { - } - - override fun onPermissionsDenied() { - } - -// override fun onCreateOptionsMenu(menu: Menu): Boolean { -// // Inflate the menu; this adds items to the action bar if it is present. -// menuInflater.inflate(R.menu.menu_main, menu) -// return true -// } - -// override fun onOptionsItemSelected(item: MenuItem): Boolean { -// // Handle action bar item clicks here. The action bar will -// // automatically handle clicks on the Home/Up button, so long -// // as you specify a parent activity in AndroidManifest.xml. -// return when (item.itemId) { -// R.id.action_settings -> true -// else -> super.onOptionsItemSelected(item) -// } -// } -// -// override fun onSupportNavigateUp(): Boolean { -// val navController = findNavController(R.id.nav_host_fragment_content_main) -// return navController.navigateUp(appBarConfiguration) -// || super.onSupportNavigateUp() -// } - - override fun fsafStartActivityForResult(intent: Intent, requestCode: Int) { - startActivityForResult(intent, requestCode) - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - fileChooser.onActivityResult(requestCode, resultCode, data) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt index 76496b0d..e533560a 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt @@ -8,10 +8,10 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.navinfo.omqs.bean.LoginUserBean +import com.navinfo.omqs.db.RoomAppDatabase import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetworkService import com.navinfo.omqs.tools.FileManager -import com.navinfo.omqs.tools.RealmCoroutineScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* import okio.IOException @@ -57,7 +57,7 @@ enum class LoginStatus { @HiltViewModel class LoginViewModel @Inject constructor( private val networkService: NetworkService, - private val realmManager: RealmCoroutineScope + private val roomAppDatabase: RoomAppDatabase ) : ViewModel() { //用户信息 val loginUser: MutableLiveData = MutableLiveData() @@ -126,9 +126,7 @@ class LoginViewModel @Inject constructor( for (cityBean in result.data) { FileManager.checkOfflineMapFileInfo(cityBean) } - realmManager.launch { - realmManager.insertOrUpdate(result.data) - } + roomAppDatabase.getOfflineMapDao().insertOrUpdate(result.data) } } is NetResult.Error -> { 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 4126123b..3eee52bf 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 @@ -7,6 +7,7 @@ import androidx.activity.viewModels import androidx.core.view.WindowCompat import androidx.databinding.DataBindingUtil import androidx.lifecycle.viewModelScope +import androidx.navigation.findNavController import com.navinfo.collect.library.map.NIMapController import com.navinfo.omqs.Constant import com.navinfo.omqs.R @@ -28,6 +29,7 @@ class MainActivity : BaseActivity() { //注入地图控制器 @Inject lateinit var mapController: NIMapController + @Inject lateinit var offlineMapDownloadManager: OfflineMapDownloadManager @@ -39,9 +41,9 @@ class MainActivity : BaseActivity() { //初始化地图 mapController.init( this, - binding.mapView.mainActivityMap, + binding.mainActivityMap, null, - Constant.ROOT_PATH + "/map/" + Constant.MAP_PATH ) //关联生命周期 binding.lifecycleOwner = this @@ -83,4 +85,11 @@ class MainActivity : BaseActivity() { binding.mainActivityDrawer.open() } + /** + * 点击录音按钮 + */ + fun voiceOnclick() { + val naviController = findNavController(R.id.main_activity_right_fragment) + naviController.navigate(R.id.EvaluationResultFragment) + } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/empty/EmptyFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/empty/EmptyFragment.kt new file mode 100644 index 00000000..9128a761 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/empty/EmptyFragment.kt @@ -0,0 +1,32 @@ +package com.navinfo.omqs.ui.fragment.empty + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.navinfo.omqs.databinding.FragmentEmptyBinding + +class EmptyFragment :Fragment(){ + private var _binding: FragmentEmptyBinding? = null + + private val binding get() = _binding!! +// private val viewModel by lazy { viewModels().value} + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentEmptyBinding.inflate(inflater, container, false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultAdapter.kt new file mode 100644 index 00000000..4ac6dc7c --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultAdapter.kt @@ -0,0 +1,16 @@ +package com.navinfo.omqs.ui.fragment.evaluationresult + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter + +class EvaluationResultAdapter(activity: FragmentActivity, val fragmentList: List) : + FragmentStateAdapter(activity) { + override fun getItemCount(): Int { + return fragmentList.size + } + + override fun createFragment(position: Int): Fragment { + return fragmentList[position] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultFragment.kt new file mode 100644 index 00000000..430501f5 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultFragment.kt @@ -0,0 +1,131 @@ +package com.navinfo.omqs.ui.fragment.evaluationresult + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.navigation.fragment.findNavController +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayoutMediator +import com.navinfo.omqs.R +import com.navinfo.omqs.databinding.FragmentEvaluationResultBinding +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class EvaluationResultFragment : Fragment() { + private var _binding: FragmentEvaluationResultBinding? = null + + private val binding get() = _binding!! + private val viewModel by lazy { viewModels().value } + private var phenomenonFragmentAdapter: EvaluationResultAdapter? = null + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View { + _binding = FragmentEvaluationResultBinding.inflate(inflater, container, false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + //返回按钮 + binding.evaluationBar.setNavigationOnClickListener { + findNavController().popBackStack() + } + //监听数据变化 + viewModel.classTypeListLiveData.observe(viewLifecycleOwner) { + if (it == null || it.isEmpty()) { + Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show() + } else { + binding.evaluationClassType.adapter = + ArrayAdapter(requireContext(), R.layout.text_item_select, it) + } + } + //选择问题分类的回调 + binding.evaluationClassType.onItemSelectedListener = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, position: Int, id: Long + ) { + viewModel.getProblemTypeList(position) + } + + override fun onNothingSelected(parent: AdapterView<*>?) {} + } + /** + * 监听联动选择的内容 + */ + viewModel.problemTypeListLiveData.observe(viewLifecycleOwner) { + binding.evaluationClassTabLayout.let { tabLayout -> + tabLayout.removeAllTabs() + val fragmentList = mutableListOf() + for (item in it) { + val tab = tabLayout.newTab() + tab.text = item + tabLayout.addTab(tab) + fragmentList.add(PhenomenonFragment(viewModel.currentClassType,item)) + } + phenomenonFragmentAdapter = + activity?.let { a -> EvaluationResultAdapter(a, fragmentList) } + binding.evaluationViewpager.adapter = phenomenonFragmentAdapter + + TabLayoutMediator( + binding.evaluationClassTabLayout, + binding.evaluationViewpager + ) { tab, position -> + tab.text = it[position] + }.attach() + updateHeight(0) + } + + } + //获取数据 + viewModel.getClassTypeList() + binding.evaluationViewpager.registerOnPageChangeCallback(object : + ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + updateHeight(position) + } + }) + } + + + private fun updateHeight(position: Int) { + phenomenonFragmentAdapter?.let { + if (it.fragmentList.size > position) { + val fragment: Fragment = it.fragmentList[position] + if (fragment.view != null) { + val viewWidth = View.MeasureSpec.makeMeasureSpec( + fragment.requireView().width, View.MeasureSpec.EXACTLY + ) + val viewHeight = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) + fragment.requireView().measure(viewWidth, viewHeight) + binding.evaluationViewpager.let { viewpager -> + if (viewpager.layoutParams.height != fragment.requireView().measuredHeight) { + //必须要用对象去接收,然后修改该对象再采用该对象,否则无法生效... + val layoutParams: ViewGroup.LayoutParams = + viewpager.layoutParams + layoutParams.height = fragment.requireView().measuredHeight + viewpager.layoutParams = layoutParams + } + } + + } + } + } + + } + + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt new file mode 100644 index 00000000..cd926fe9 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt @@ -0,0 +1,73 @@ +package com.navinfo.omqs.ui.fragment.evaluationresult + +import android.util.Log +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.navinfo.omqs.db.RoomAppDatabase +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import okhttp3.Dispatcher +import javax.inject.Inject + +@HiltViewModel +class EvaluationResultViewModel @Inject constructor( + private val roomAppDatabase: RoomAppDatabase, +) : ViewModel() { + init { + Log.e("jingo", "EvaluationResultViewModel 创建了 ${hashCode()}") + } + + override fun onCleared() { + super.onCleared() + Log.e("jingo", "EvaluationResultViewModel 销毁了 ${hashCode()}") + } + + /** + * 问题分类 liveData + */ + + val classTypeListLiveData = MutableLiveData?>() + + /** + * 问题类型 liveData + */ + + val problemTypeListLiveData = MutableLiveData>() + + var currentClassType: String = "" + + /** + * 查询数据库,获取问题分类 + */ + fun getClassTypeList() { + viewModelScope.launch(Dispatchers.IO) { + val list = roomAppDatabase.getScProblemTypeDao().findClassTypeList() + classTypeListLiveData.postValue(list) + } + } + + /** + * 查询问题类型 + */ + fun getProblemTypeList(index: Int) { + viewModelScope.launch(Dispatchers.IO) { + classTypeListLiveData.value?.let { + if (index < it.size) { + currentClassType = it[index] + val list = + roomAppDatabase.getScProblemTypeDao().findProblemTypeList(currentClassType) + problemTypeListLiveData.postValue(list) + } + } + } + } + + fun getPhenomenonList() { + viewModelScope.launch (Dispatchers.IO){ + + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/PhenomenonAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/PhenomenonAdapter.kt new file mode 100644 index 00000000..4068dd07 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/PhenomenonAdapter.kt @@ -0,0 +1,24 @@ +package com.navinfo.omqs.ui.fragment.evaluationresult + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.navinfo.omqs.R +import com.navinfo.omqs.databinding.TextItemSelectBinding +import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter +import com.navinfo.omqs.ui.other.BaseViewHolder + +class PhenomenonAdapter() : BaseRecyclerViewAdapter() { + override fun getItemViewRes(position: Int): Int { + return R.layout.text_item_select + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { + val viewBinding = + TextItemSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return BaseViewHolder(viewBinding) + } + + override fun onBindViewHolder(holder: BaseViewHolder, position: Int) { + (holder.viewBinding as TextItemSelectBinding).itemId.text = data[position] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/PhenomenonFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/PhenomenonFragment.kt new file mode 100644 index 00000000..67038c37 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/PhenomenonFragment.kt @@ -0,0 +1,59 @@ +package com.navinfo.omqs.ui.fragment.evaluationresult + +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearLayoutManager +import com.navinfo.omqs.databinding.FragmentPhenomenonBinding +import com.navinfo.omqs.db.RoomAppDatabase +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch +import javax.inject.Inject + +@AndroidEntryPoint +class PhenomenonFragment(private val classType: String, private val title: String) : + Fragment() { + @Inject + lateinit var roomAppDatabase: RoomAppDatabase + private var _binding: FragmentPhenomenonBinding? = null + private val binding get() = _binding!! + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentPhenomenonBinding.inflate(inflater, container, false) + Log.e("jingo", "PhenomenonFragment onCreateView ${hashCode()}") + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.phenomenonRecyclerview.setHasFixedSize(true) + binding.phenomenonRecyclerview.layoutManager = LinearLayoutManager(context) + val adapter = PhenomenonAdapter() + binding.phenomenonRecyclerview.adapter = adapter + lifecycleScope.launch { + Log.e("jingo", "$classType $title ") + val list = roomAppDatabase.getScProblemTypeDao().getPhenomenonList(classType, title) + Log.e("jingo", "${list.toString()}") + adapter.refreshData(list) + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + Log.e("jingo", "PhenomenonFragment onDestroyView ${hashCode()}") + } + + override fun onResume() { + super.onResume() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapAdapter.kt index f3c863a4..4c1e6786 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapAdapter.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapAdapter.kt @@ -3,7 +3,6 @@ package com.navinfo.omqs.ui.fragment.offlinemap import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.viewpager2.adapter.FragmentStateAdapter -import dagger.hilt.EntryPoint /** * 离线地图主页面,viewpage适配器 diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapCityListAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapCityListAdapter.kt index d27594bd..0800abce 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapCityListAdapter.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapCityListAdapter.kt @@ -6,9 +6,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.lifecycle.Observer -import com.navinfo.collect.library.data.entity.OfflineMapCityBean import com.navinfo.omqs.R import com.navinfo.omqs.databinding.AdapterOfflineMapCityBinding +import com.navinfo.omqs.bean.OfflineMapCityBean import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter import com.navinfo.omqs.ui.other.BaseViewHolder @@ -22,7 +22,7 @@ import javax.inject.Inject *使用 LiveData 的 observeForever 然后在 ViewHolder 销毁前手动调用 removeObserver *使用 LifecycleRegistry 给 ViewHolder 分发生命周期(这里使用了这个) */ -class OfflineMapCityListAdapter @Inject constructor( +class OfflineMapCityListAdapter( private val downloadManager: OfflineMapDownloadManager, private val context: Context ) : BaseRecyclerViewAdapter() { @@ -126,7 +126,7 @@ class OfflineMapCityListAdapter @Inject constructor( } } - override fun getItemViewType(position: Int): Int { + override fun getItemViewRes(position: Int): Int { return R.layout.adapter_offline_map_city } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapCityListViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapCityListViewModel.kt index 1dbd04f0..245a82d7 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapCityListViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapCityListViewModel.kt @@ -4,14 +4,10 @@ import android.content.Context import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.navinfo.collect.library.data.entity.OfflineMapCityBean -import com.navinfo.omqs.tools.FileManager -import com.navinfo.omqs.tools.RealmCoroutineScope +import com.navinfo.omqs.db.RoomAppDatabase +import com.navinfo.omqs.bean.OfflineMapCityBean import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext -import io.realm.Realm -import io.realm.Sort -import io.realm.kotlin.where import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import javax.inject.Inject @@ -22,6 +18,7 @@ import javax.inject.Inject @HiltViewModel class OfflineMapCityListViewModel @Inject constructor( @ApplicationContext val context: Context, + private val roomDatabase: RoomAppDatabase ) : ViewModel() { val cityListLiveData = MutableLiveData>() @@ -31,13 +28,14 @@ class OfflineMapCityListViewModel @Inject constructor( */ fun getCityList() { viewModelScope.launch(Dispatchers.IO) { - val realm = Realm.getDefaultInstance() - val objects = realm.where().findAll().sort("id", Sort.ASCENDING) - val list = realm.copyFromRealm(objects) - realm.close() - for (item in list) { - FileManager.checkOfflineMapFileInfo(item) - } +// val realm = Realm.getDefaultInstance() +// val objects = realm.where().findAll().sort("id", Sort.ASCENDING) +// val list = realm.copyFromRealm(objects) +// realm.close() +// for (item in list) { +// FileManager.checkOfflineMapFileInfo(item) +// } + val list = roomDatabase.getOfflineMapDao().getOfflineMapList() cityListLiveData.postValue(list) } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapFragment.kt index 8f9da1e1..9755b2e4 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapFragment.kt @@ -1,23 +1,16 @@ package com.navinfo.omqs.ui.fragment.offlinemap import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController -import com.google.android.material.tabs.TabLayout -import com.google.android.material.tabs.TabLayout.OnTabSelectedListener import com.google.android.material.tabs.TabLayoutMediator import com.navinfo.omqs.databinding.FragmentOfflineMapBinding -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext /** - * 离线地图 + * 离线地图总页面 */ class OfflineMapFragment : Fragment() { diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapStateListFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapStateListFragment.kt index b4ae37f7..41c3b337 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapStateListFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapStateListFragment.kt @@ -6,16 +6,33 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import com.google.android.material.tabs.TabLayout -import com.google.android.material.tabs.TabLayoutMediator -import com.navinfo.omqs.databinding.FragmentOfflineMapBinding +import androidx.fragment.app.viewModels +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.recyclerview.widget.LinearLayoutManager import com.navinfo.omqs.databinding.FragmentOfflineMapStateListBinding +import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject - +/** + * 离线地图管理页面 + */ +@AndroidEntryPoint class OfflineMapStateListFragment : Fragment() { + @Inject + lateinit var downloadManager: OfflineMapDownloadManager private var _binding: FragmentOfflineMapStateListBinding? = null - + private val viewModel by viewModels() private val binding get() = _binding!! + + private val adapter: OfflineMapCityListAdapter by lazy { + OfflineMapCityListAdapter( + downloadManager, + requireContext() + ) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -27,11 +44,24 @@ class OfflineMapStateListFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + val layoutManager = LinearLayoutManager(context) + //// 设置 RecyclerView 的固定大小,避免在滚动时重新计算视图大小和布局,提高性能 + binding.offlineMapCityStateListRecyclerview.setHasFixedSize(true) + binding.offlineMapCityStateListRecyclerview.layoutManager = layoutManager + binding.offlineMapCityStateListRecyclerview.adapter = adapter + viewModel.cityListLiveData.observe(viewLifecycleOwner) { + adapter.refreshData(it) + } } override fun onDestroyView() { super.onDestroyView() _binding = null } + + override fun onResume() { + super.onResume() + viewModel.getCityList() + } + } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapStateListViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapStateListViewModel.kt new file mode 100644 index 00000000..1490e33c --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapStateListViewModel.kt @@ -0,0 +1,40 @@ +package com.navinfo.omqs.ui.fragment.offlinemap + +import android.content.Context +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.navinfo.omqs.db.RoomAppDatabase +import com.navinfo.omqs.bean.OfflineMapCityBean +import dagger.hilt.android.lifecycle.HiltViewModel +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import javax.inject.Inject + +/** + * 离线地图城市列表viewModel + */ +@HiltViewModel +class OfflineMapStateListViewModel @Inject constructor( + @ApplicationContext val context: Context, + private val roomDatabase: RoomAppDatabase +) : ViewModel() { + + val cityListLiveData = MutableLiveData>() + + /** + * 去获取正在下载或 已经下载的离线地图列表 + */ + fun getCityList() { + viewModelScope.launch(Dispatchers.IO) { + val list = roomDatabase.getOfflineMapDao().getOfflineMapListWithOutNone() + if (cityListLiveData.value != null) { + if (cityListLiveData.value!!.size != list.size) + cityListLiveData.postValue(list) + }else{ + cityListLiveData.postValue(list) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapViewHolder.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapViewHolder.kt deleted file mode 100644 index 02a03583..00000000 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/offlinemap/OfflineMapViewHolder.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.navinfo.omqs.ui.fragment.offlinemap - -import com.navinfo.omqs.databinding.AdapterOfflineMapCityBinding -import com.navinfo.omqs.ui.other.BaseViewHolder - -class OfflineMapViewHolder(dataBinding: AdapterOfflineMapCityBinding) : BaseViewHolder(dataBinding) { - init{ - dataBinding.offlineMapDownloadBtn - } -} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt index e0d21450..e5799c2d 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt @@ -15,10 +15,12 @@ import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks import com.github.k1rakishou.fsaf.callback.FileChooserCallback import com.navinfo.omqs.R import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding +import dagger.hilt.android.AndroidEntryPoint /** * 个人中心 */ +@AndroidEntryPoint class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks { private var _binding: FragmentPersonalCenterBinding? = null @@ -54,6 +56,18 @@ class PersonalCenterFragment : Fragment(), FSAFActivityCallbacks { } }) } + R.id.personal_center_menu_import_yuan_data->{ + // 用户选中导入数据,打开文件选择器,用户选择导入的数据文件目录 + fileChooser.openChooseFileDialog(object: FileChooserCallback() { + override fun onCancel(reason: String) { + } + + override fun onResult(uri: Uri) { + viewModel.importScProblemData(uri) + + } + }) + } } true } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt index a0217e7d..741c58b8 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterViewModel.kt @@ -1,16 +1,89 @@ package com.navinfo.omqs.ui.fragment.personalcenter +import android.net.Uri +import android.util.Log import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.blankj.utilcode.util.UriUtils +import com.navinfo.omqs.bean.ScProblemTypeBean +import com.navinfo.omqs.bean.ScRootCauseAnalysisBean +import com.navinfo.omqs.db.RoomAppDatabase +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import org.apache.poi.ss.usermodel.Cell +import org.apache.poi.ss.usermodel.Row +import org.apache.poi.ss.usermodel.Sheet +import org.apache.poi.ss.usermodel.WorkbookFactory import java.io.File +import java.io.FileInputStream +import java.io.IOException +import java.io.InputStream +import javax.inject.Inject -class PersonalCenterViewModel: ViewModel() { +@HiltViewModel +class PersonalCenterViewModel @Inject constructor( + private val roomAppDatabase: RoomAppDatabase +) : ViewModel() { fun importOmdbData(omdbFile: File) { // 检查File是否为sqlite数据库 - if (omdbFile == null || omdbFile.exists()) { + if (omdbFile == null || !omdbFile.exists()) { throw Exception("文件不存在") } if (!omdbFile.name.endsWith(".sqlite") and !omdbFile.name.endsWith("db")) { throw Exception("文件不存在") } } + + fun importScProblemData(uri: Uri) { + viewModelScope.launch(Dispatchers.IO) { + try { + val file = UriUtils.uri2File(uri) + val inputStream: InputStream = + FileInputStream(file) //getAssets().open("sample.xlsx") + val workbook = WorkbookFactory.create(inputStream) + //获取所有sheet + val sheet1 = workbook.getSheet("SC_PROBLEM_TYPE") + sheet1?.let { + val rowCount: Int = it.physicalNumberOfRows // 获取行数 + val list = mutableListOf() + for (i in 1 until rowCount) { + val row: Row = it.getRow(i) // 获取行 + val cellCount: Int = row.physicalNumberOfCells // 获取列数 + if (cellCount == 3) { + val bean = ScProblemTypeBean() + bean.classType = row.getCell(0).stringCellValue + bean.problemType = row.getCell(1).stringCellValue + bean.phenomenon = row.getCell(2).stringCellValue + list.add(bean) + Log.e("jingo", bean.toString()) + } + } + roomAppDatabase.getScProblemTypeDao().insertOrUpdateList(list) + } + val sheet2 = workbook.getSheet("SC_ROOT_CAUSE_ANALYSIS") + sheet2?.let { + val rowCount: Int = it.physicalNumberOfRows // 获取行数 + val list = mutableListOf() + for (i in 1 until rowCount) { + val row: Row = it.getRow(i) // 获取行 + val cellCount: Int = row.physicalNumberOfCells // 获取列数 + if (cellCount == 2) { + val bean = ScRootCauseAnalysisBean() + bean.problemLink = row.getCell(0).stringCellValue + bean.problemCause = row.getCell(1).stringCellValue + list.add(bean) + Log.e("jingo", bean.toString()) + } + } + roomAppDatabase.getScRootCauseAnalysisDao().insertOrUpdateList(list) + } + workbook.close() + } catch (e: IOException) { + e.printStackTrace() + Log.e("jingo", e.toString()) + } + } + + } } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/other/BaseRecyclerViewAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/other/BaseRecyclerViewAdapter.kt index fa964626..3f60af13 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/other/BaseRecyclerViewAdapter.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/other/BaseRecyclerViewAdapter.kt @@ -5,6 +5,7 @@ import android.view.View.OnClickListener import android.view.ViewGroup import androidx.databinding.DataBindingUtil import androidx.recyclerview.widget.RecyclerView +import com.navinfo.omqs.R /** * RecyclerView 适配器基础类 @@ -26,6 +27,11 @@ abstract class BaseRecyclerViewAdapter(var data: List = listOf()) : // ) // } + abstract fun getItemViewRes(position: Int): Int + + override fun getItemViewType(position: Int): Int { + return getItemViewRes(position) + } override fun getItemCount(): Int { return data.size diff --git a/app/src/main/res/drawable/baseline_delete_forever_24.xml b/app/src/main/res/drawable/baseline_delete_forever_24.xml new file mode 100644 index 00000000..32fc924a --- /dev/null +++ b/app/src/main/res/drawable/baseline_delete_forever_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/baseline_keyboard_voice_24.xml b/app/src/main/res/drawable/baseline_keyboard_voice_24.xml new file mode 100644 index 00000000..50ea1620 --- /dev/null +++ b/app/src/main/res/drawable/baseline_keyboard_voice_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/baseline_save_24.xml b/app/src/main/res/drawable/baseline_save_24.xml new file mode 100644 index 00000000..d4ab6604 --- /dev/null +++ b/app/src/main/res/drawable/baseline_save_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 780024d8..fe9c07a7 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -5,7 +5,6 @@ tools:context=".ui.activity.map.MainActivity"> - @@ -21,20 +20,65 @@ android:layout_height="match_parent" android:fitsSystemWindows="true"> - + tools:context=".ui.activity.map.MainActivity"> + + + + + + + + + + + + app:navGraph="@navigation/left_drawer_nav_graph" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map_test.xml b/app/src/main/res/layout/activity_map_test.xml deleted file mode 100644 index 0d477f41..00000000 --- a/app/src/main/res/layout/activity_map_test.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_empty.xml b/app/src/main/res/layout/fragment_empty.xml new file mode 100644 index 00000000..f59a4d2f --- /dev/null +++ b/app/src/main/res/layout/fragment_empty.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_evaluation_result.xml b/app/src/main/res/layout/fragment_evaluation_result.xml new file mode 100644 index 00000000..d53445ad --- /dev/null +++ b/app/src/main/res/layout/fragment_evaluation_result.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_map_download.xml b/app/src/main/res/layout/fragment_map_download.xml deleted file mode 100644 index f5b4982e..00000000 --- a/app/src/main/res/layout/fragment_map_download.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_offline_map.xml b/app/src/main/res/layout/fragment_offline_map.xml index 03bf1190..798d5e1c 100644 --- a/app/src/main/res/layout/fragment_offline_map.xml +++ b/app/src/main/res/layout/fragment_offline_map.xml @@ -26,20 +26,13 @@ android:text="城市列表" /> - + app:layout_constraintTop_toBottomOf="@id/offline_map_tab_layout" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_offline_map_city_list.xml b/app/src/main/res/layout/fragment_offline_map_city_list.xml index 0b0982b3..930bd830 100644 --- a/app/src/main/res/layout/fragment_offline_map_city_list.xml +++ b/app/src/main/res/layout/fragment_offline_map_city_list.xml @@ -6,8 +6,19 @@ android:layout_height="match_parent" tools:context=".ui.fragment.offlinemap.OfflineMapCityListFragment"> + + + android:layout_height="0dp" + app:layout_constraintTop_toBottomOf="@id/offline_map_search" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_offline_map_state_list.xml b/app/src/main/res/layout/fragment_offline_map_state_list.xml index 5de6383b..5df608e9 100644 --- a/app/src/main/res/layout/fragment_offline_map_state_list.xml +++ b/app/src/main/res/layout/fragment_offline_map_state_list.xml @@ -4,15 +4,11 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/default_red" tools:context=".ui.fragment.offlinemap.OfflineMapStateListFragment"> - + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_personal_center.xml b/app/src/main/res/layout/fragment_personal_center.xml index 4d137cf7..8e36ac72 100644 --- a/app/src/main/res/layout/fragment_personal_center.xml +++ b/app/src/main/res/layout/fragment_personal_center.xml @@ -2,7 +2,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/map_view.xml b/app/src/main/res/layout/map_view.xml deleted file mode 100644 index 0a7f8b09..00000000 --- a/app/src/main/res/layout/map_view.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/temp.xml b/app/src/main/res/layout/temp.xml new file mode 100644 index 00000000..3bce645a --- /dev/null +++ b/app/src/main/res/layout/temp.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/text_item_select.xml b/app/src/main/res/layout/text_item_select.xml new file mode 100644 index 00000000..66dd87d4 --- /dev/null +++ b/app/src/main/res/layout/text_item_select.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/evaluation_bar_mean.xml b/app/src/main/res/menu/evaluation_bar_mean.xml new file mode 100644 index 00000000..16c99b49 --- /dev/null +++ b/app/src/main/res/menu/evaluation_bar_mean.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/personal_center_menu.xml b/app/src/main/res/menu/personal_center_menu.xml index 4e3502df..d8860fdb 100644 --- a/app/src/main/res/menu/personal_center_menu.xml +++ b/app/src/main/res/menu/personal_center_menu.xml @@ -15,9 +15,9 @@ android:icon="@drawable/ic_baseline_import_export_24" android:title="导入数据" /> + android:id="@+id/personal_center_menu_import_yuan_data" + android:icon="@drawable/ic_baseline_import_export_24" + android:title="导入元数据" /> + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index da697ab5..63d6efae 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. + buildscript { dependencies { classpath "io.realm:realm-gradle-plugin:10.11.1" diff --git a/collect-library/build.gradle b/collect-library/build.gradle index 9cc1452d..0f109e87 100644 --- a/collect-library/build.gradle +++ b/collect-library/build.gradle @@ -1,11 +1,13 @@ plugins { id 'com.android.library' id 'org.jetbrains.kotlin.android' + id 'kotlin-parcelize' // 序列化 + id 'kotlin-android' + 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" @@ -31,7 +33,7 @@ android { } } ndk { - abiFilters "armeabi", "armeabi-v7a" + abiFilters "armeabi", "armeabi-v7a", "arm64-v8a" } } @@ -53,20 +55,22 @@ android { } } - +//configurations.all { +// resolutionStrategy { +// force 'com.intellij:annotations:13.0' +// } +//} dependencies { api fileTree(dir: 'libs', include: ['*.jar', '*.aar']) - api files('libs/BaiduLBS_AndroidSDK_Lib.aar') - implementation "androidx.appcompat:appcompat:$appcompatVersion" - implementation "com.google.android.material:material:$materialVersion" + api files('libs/BaiduLBS_Android.jar') testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' implementation 'com.yanzhenjie:kalle:0.1.7' // VTM依赖 implementation "net.sf.kxml:kxml2:2.3.0" - implementation "org.slf4j:slf4j-api:1.7.28" + implementation 'org.slf4j:slf4j-api:2.0.7' implementation "org.mapsforge:vtm:$vtmVersion" implementation "org.mapsforge:vtm-themes:$vtmVersion" implementation "org.mapsforge:vtm-android:$vtmVersion" @@ -94,30 +98,37 @@ dependencies { implementation "com.badlogicgames.gdx:gdx-backend-android:1.11.0" implementation "com.caverock:androidsvg:1.4" implementation "org.mapsforge:vtm-jts:$vtmVersion" - implementation "org.locationtech.jts:jts-core:1.18.2" - implementation "com.squareup.okhttp3:okhttp:3.12.13" - implementation "com.squareup.okio:okio:1.15.0" + implementation 'org.locationtech.jts:jts-core:1.19.0' + implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.11' + implementation 'com.squareup.okio:okio:3.3.0' implementation "com.fasterxml.jackson.core:jackson-annotations:2.9.9" implementation "com.fasterxml.jackson.core:jackson-core:2.9.9" implementation "com.fasterxml.jackson.core:jackson-databind:2.9.9" - implementation 'com.tencent.wcdb:room:1.0.8' // 代替 room-runtime,同时也不需要再引用 wcdb-android - implementation "androidx.sqlite:sqlite:2.0.1" - implementation "androidx.room:room-runtime:2.1.0" - annotationProcessor "androidx.room:room-compiler:2.1.0" - kapt "androidx.room:room-compiler:2.1.0" - androidTestImplementation 'androidx.room:room-testing:2.0.0' - implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' - kapt 'androidx.lifecycle:lifecycle-compiler:2.0.0' - implementation 'com.tencent.wcdb:wcdb-android:1.0.0' - implementation "androidx.core:core-ktx:1.8.0" - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - // 协程核心库 - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' - // 协程Android支持库 - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4' - // 协程Java8支持库 - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.6.4' + //room 数据库相关 + api 'com.tencent.wcdb:room:1.1-19' // 代替 room-runtime,同时也不需要再引用 wcdb-android + api 'androidx.sqlite:sqlite-ktx:2.3.1' + api "androidx.room:room-runtime:2.5.1" + api "androidx.room:room-ktx:2.5.1" + annotationProcessor "androidx.room:room-compiler:2.5.1" + 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.5.1" + kapt "androidx.room:room-ktx:2.5.1" + +// //分页加载 +// api "androidx.room:room-paging:$roomversion" +// api "androidx.paging:paging-runtime-ktx:3.1.1" + + androidTestImplementation "android.arch.persistence.room:testing:1.1.1" + api 'com.tencent.wcdb:wcdb-android:1.1-19' + +// // 协程核心库 +// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' +// // 协程Android支持库 +// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4' +// // 协程Java8支持库 +// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.6.4' } \ No newline at end of file diff --git a/collect-library/libs/BaiduLBS_Android.jar b/collect-library/libs/BaiduLBS_Android.jar new file mode 100644 index 00000000..07327d76 Binary files /dev/null and b/collect-library/libs/BaiduLBS_Android.jar differ diff --git a/collect-library/libs/BaiduLBS_AndroidSDK_Lib.aar b/collect-library/libs/BaiduLBS_AndroidSDK_Lib.aar deleted file mode 100644 index 18d4fe80..00000000 Binary files a/collect-library/libs/BaiduLBS_AndroidSDK_Lib.aar and /dev/null differ diff --git a/collect-library/libs/arm64-v8a/libindoor.so b/collect-library/libs/arm64-v8a/libindoor.so new file mode 100644 index 00000000..8b55e4c9 Binary files /dev/null and b/collect-library/libs/arm64-v8a/libindoor.so differ diff --git a/collect-library/libs/arm64-v8a/liblocSDK8b.so b/collect-library/libs/arm64-v8a/liblocSDK8b.so new file mode 100644 index 00000000..5b0d7afe Binary files /dev/null and b/collect-library/libs/arm64-v8a/liblocSDK8b.so differ diff --git a/collect-library/libs/armeabi-v7a/libindoor.so b/collect-library/libs/armeabi-v7a/libindoor.so new file mode 100644 index 00000000..e14d583d Binary files /dev/null and b/collect-library/libs/armeabi-v7a/libindoor.so differ diff --git a/collect-library/libs/armeabi-v7a/liblocSDK8b.so b/collect-library/libs/armeabi-v7a/liblocSDK8b.so new file mode 100644 index 00000000..c14b9199 Binary files /dev/null and b/collect-library/libs/armeabi-v7a/liblocSDK8b.so differ diff --git a/collect-library/libs/x86/liblocSDK8b.so b/collect-library/libs/x86/liblocSDK8b.so new file mode 100644 index 00000000..62a9a604 Binary files /dev/null and b/collect-library/libs/x86/liblocSDK8b.so differ diff --git a/collect-library/libs/x86_64/liblocSDK8b.so b/collect-library/libs/x86_64/liblocSDK8b.so new file mode 100644 index 00000000..4fe4fe81 Binary files /dev/null and b/collect-library/libs/x86_64/liblocSDK8b.so differ diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/OfflineMapCityBean.kt b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/OfflineMapCityBean.kt index 9d1f54fe..3621578b 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/OfflineMapCityBean.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/OfflineMapCityBean.kt @@ -1,57 +1,57 @@ -package com.navinfo.collect.library.data.entity - -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey - -//enum class StatusEnum(val status: Int) { -// NONE(0), WAITING(1), LOADING(2), PAUSE(3), -// ERROR(4), DONE(5), UPDATE(6) -//} - -open class OfflineMapCityBean @JvmOverloads constructor( - @PrimaryKey var id: String = "", - var fileName: String = "", - var name: String = "", - var url: String = "", - var version: Long = 0L, - var fileSize: Long = 0L, - var currentSize: Long = 0L, - var status: Int = NONE -) : RealmObject() { - - companion object Status{ - const val NONE = 0 //无状态 - const val WAITING = 1 //等待中 - const val LOADING = 2 //下载中 - const val PAUSE = 3 //暂停 - const val ERROR = 4 //错误 - const val DONE = 5 //完成 - const val UPDATE = 6 //有新版本要更新 - } - -// // status的转换对象 -// var statusEnum: StatusEnum -// get() { -// return try { -// StatusEnum.values().find { it.status == status }!! -// } catch (e: IllegalArgumentException) { -// StatusEnum.NONE -// } -// } -// set(value) { -// status = value.status -// } - - fun getFileSizeText(): String { - return if (fileSize < 1024.0) - "$fileSize B" - else if (fileSize < 1048576.0) - "%.2f K".format(fileSize / 1024.0) - else if (fileSize < 1073741824.0) - "%.2f M".format(fileSize / 1048576.0) - else - "%.2f M".format(fileSize / 1073741824.0) - } - - -} \ No newline at end of file +//package com.navinfo.collect.library.data.entity +// +//import io.realm.RealmObject +//import io.realm.annotations.PrimaryKey +// +////enum class StatusEnum(val status: Int) { +//// NONE(0), WAITING(1), LOADING(2), PAUSE(3), +//// ERROR(4), DONE(5), UPDATE(6) +////} +// +//open class OfflineMapCityBean @JvmOverloads constructor( +// @PrimaryKey var id: String = "", +// var fileName: String = "", +// var name: String = "", +// var url: String = "", +// var version: Long = 0L, +// var fileSize: Long = 0L, +// var currentSize: Long = 0L, +// var status: Int = NONE +//) : RealmObject() { +// +// companion object Status{ +// const val NONE = 0 //无状态 +// const val WAITING = 1 //等待中 +// const val LOADING = 2 //下载中 +// const val PAUSE = 3 //暂停 +// const val ERROR = 4 //错误 +// const val DONE = 5 //完成 +// const val UPDATE = 6 //有新版本要更新 +// } +// +//// // status的转换对象 +//// var statusEnum: StatusEnum +//// get() { +//// return try { +//// StatusEnum.values().find { it.status == status }!! +//// } catch (e: IllegalArgumentException) { +//// StatusEnum.NONE +//// } +//// } +//// set(value) { +//// status = value.status +//// } +// +// fun getFileSizeText(): String { +// return if (fileSize < 1024.0) +// "$fileSize B" +// else if (fileSize < 1048576.0) +// "%.2f K".format(fileSize / 1024.0) +// else if (fileSize < 1073741824.0) +// "%.2f M".format(fileSize / 1048576.0) +// else +// "%.2f M".format(fileSize / 1073741824.0) +// } +// +// +//} \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/OfflineMapCityRealmObject.kt b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/OfflineMapCityRealmObject.kt index 5bd0e80a..f42ad705 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/OfflineMapCityRealmObject.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/OfflineMapCityRealmObject.kt @@ -1,43 +1,43 @@ -package com.navinfo.collect.library.data.entity - -import io.realm.RealmModel -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import io.realm.annotations.RealmClass - -@RealmClass -open class OfflineMapCityRealmObject: RealmModel { - @PrimaryKey - var id: String = "" - var fileName: String="" - var name: String = "" - var url: String = "" - var version: Long = 0 - var fileSize: Long = 0 - var currentSize:Long = 0 - var status:Int = 0 - - constructor(){ - - } - - constructor( - id: String, - fileName: String, - name: String, - url: String, - version: Long, - fileSize: Long, - currentSize: Long, - status: Int - ) { - this.id = id - this.fileName = fileName - this.name = name - this.url = url - this.version = version - this.fileSize = fileSize - this.currentSize = currentSize - this.status = status - } -} \ No newline at end of file +//package com.navinfo.collect.library.data.entity +// +//import io.realm.RealmModel +//import io.realm.RealmObject +//import io.realm.annotations.PrimaryKey +//import io.realm.annotations.RealmClass +// +//@RealmClass +//open class OfflineMapCityRealmObject: RealmModel { +// @PrimaryKey +// var id: String = "" +// var fileName: String="" +// var name: String = "" +// var url: String = "" +// var version: Long = 0 +// var fileSize: Long = 0 +// var currentSize:Long = 0 +// var status:Int = 0 +// +// constructor(){ +// +// } +// +// constructor( +// id: String, +// fileName: String, +// name: String, +// url: String, +// version: Long, +// fileSize: Long, +// currentSize: Long, +// status: Int +// ) { +// this.id = id +// this.fileName = fileName +// this.name = name +// this.url = url +// this.version = version +// this.fileSize = fileSize +// this.currentSize = currentSize +// this.status = status +// } +//} \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt index 3db6b728..f8f64bab 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LayerManagerHandler.kt @@ -1,17 +1,20 @@ package com.navinfo.collect.library.map.handler import android.content.Context -import android.os.Environment import com.navinfo.collect.library.map.NIMapView -import com.navinfo.collect.library.map.NIMapView.LAYER_GROUPS import com.navinfo.collect.library.map.source.NavinfoMapRastorTileSource +import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource import com.navinfo.collect.library.system.Constant import okhttp3.Cache import okhttp3.OkHttpClient +import org.oscim.layers.GroupLayer import org.oscim.layers.Layer -import org.oscim.layers.LocationLayer import org.oscim.layers.tile.bitmap.BitmapTileLayer +import org.oscim.layers.tile.buildings.BuildingLayer +import org.oscim.layers.tile.vector.VectorTileLayer +import org.oscim.layers.tile.vector.labeling.LabelLayer import org.oscim.tiling.source.OkHttpEngine.OkHttpFactory +import org.oscim.tiling.source.mapfile.MapFileTileSource import java.io.File /** @@ -19,7 +22,8 @@ import java.io.File */ class LayerManagerHandler(context: Context, mapView: NIMapView) : BaseHandler(context, mapView) { - private var baseRasterLayer: Layer? = null + private var baseGroupLayer // 用于盛放所有基础底图的图层组,便于统一管理 + : GroupLayer? = null init { initMap() @@ -29,8 +33,10 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) : * 初始化地图 */ private fun initMap() { - switchBaseMapType(BASE_MAP_TYPE.CYCLE_MAP) + loadBaseMap() + mMapView.switchTileVectorLayerTheme(NIMapView.MAP_THEME.DEFAULT) + mMapView.vtmMap.updateMap() // initVectorTileLayer() // initMapLifeSource() } @@ -39,15 +45,60 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) : /** * 切换基础底图样式 */ - fun switchBaseMapType(type: BASE_MAP_TYPE) { - if (baseRasterLayer != null) { - mMapView.vtmMap.layers().remove(baseRasterLayer) - baseRasterLayer = null - mMapView.vtmMap.updateMap() + fun loadBaseMap() { + + if (baseGroupLayer == null) { + baseGroupLayer = GroupLayer(mMapView.vtmMap) + addLayer(baseGroupLayer!!, NIMapView.LAYER_GROUPS.BASE) + } + baseGroupLayer?.let { + for (layer in it.layers) { + removeLayer(layer) + } + it.layers.clear() + val builder = OkHttpClient.Builder() + val urlTileSource: NavinfoMultiMapFileTileSource = + NavinfoMultiMapFileTileSource.builder() + .httpFactory(OkHttpFactory(builder)) //.locale("en") + .build() + + // Cache the tiles into file system + val cacheDirectory = File(Constant.MAP_PATH, "cache") + val cacheSize = 200 * 1024 * 1024 // 10 MB + val cache = Cache(cacheDirectory, cacheSize.toLong()) + builder.cache(cache) + +// val headerMap = HashMap() +// headerMap["token"] = ""//Constant.TOKEN +// urlTileSource.setHttpRequestHeaders(headerMap) + val baseLayer = VectorTileLayer(mMapView.vtmMap, urlTileSource) + + val baseMapFolder = File("${Constant.MAP_PATH}offline") + + if (baseMapFolder.exists()) { + val dirFileList = baseMapFolder.listFiles() + if (dirFileList != null && dirFileList.isNotEmpty()) { + for (mapFile in dirFileList) { + if (!mapFile.isFile || !mapFile.name.endsWith(".map")) { + continue + } + val mTileSource = MapFileTileSource() + mTileSource.setPreferredLanguage("zh") + if (mTileSource.setMapFile(mapFile.absolutePath)) { + urlTileSource.add(mTileSource) + } + } + } + baseLayer.tileSource = urlTileSource + it.layers.add(baseLayer) + it.layers.add(BuildingLayer(mMapView.vtmMap, baseLayer)) + it.layers.add(LabelLayer(mMapView.vtmMap, baseLayer)) + for (layer in it.layers) { + addLayer(layer, NIMapView.LAYER_GROUPS.BASE) + } + mMapView.updateMap() + } } - baseRasterLayer = getRasterTileLayer(type.url, type.tilePath, true) - addLayer(baseRasterLayer!!, LAYER_GROUPS.BASE) - mMapView.updateMap() } private fun getRasterTileLayer( @@ -61,16 +112,13 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) : .httpFactory(OkHttpFactory(builder)).build() // 如果使用缓存 if (useCache) { - val cacheDirectory: File = - File(Constant.MAP_PATH, "tiles-raster") + val cacheDirectory = + File(Constant.MAP_PATH, "cache") val cacheSize = 300 * 1024 * 1024 // 300 MB val cache = Cache(cacheDirectory, cacheSize.toLong()) builder.cache(cache) } -// mTileSource.setHttpEngine(new OkHttpEngine.OkHttpFactory(builder)); -// mTileSource.setHttpRequestHeaders(Collections.singletonMap("User-Agent", "vtm-android-example")); -// mTileSource.setCache(new TileCache(mContext, defaultDir, url.substring(url.indexOf(":")+1))); return BitmapTileLayer(mMapView.vtmMap, mTileSource) } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt index 7ca739be..19134fe2 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt @@ -12,8 +12,7 @@ import com.navinfo.collect.library.map.NIMapView import org.oscim.layers.LocationLayer -class LocationLayerHandler(context: Context, mapView: NIMapView) : - BaseHandler(context, mapView) { +class LocationLayerHandler(context: Context, mapView: NIMapView) : BaseHandler(context, mapView) { private var mCurrentLocation: BDLocation? = null private var bFirst = true @@ -55,13 +54,11 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) : val errorCode = it.locType mCurrentLocation = it mLocationLayer.setPosition( - it.latitude, - it.longitude, - it.radius + it.latitude, it.longitude, it.radius ) //第一次定位成功显示当前位置 if (this.bFirst) { - animateToCurrentPosition() + animateToCurrentPosition(16.0) } } @@ -97,9 +94,7 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) : // locationOption.setOpenAutoNotifyMode() //设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者 locationOption.setOpenAutoNotifyMode( - 1000, - 1, - LocationClientOption.LOC_SENSITIVITY_HIGHT + 1000, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT ) //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用 locationClient.locOption = locationOption @@ -130,12 +125,21 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) : /** * 回到当前位置 */ - fun animateToCurrentPosition() - { + fun animateToCurrentPosition(zoom: Double) { + mCurrentLocation?.run { - val mapPosition = mMapView.vtmMap.mapPosition; - mapPosition.setPosition(this.latitude, this.longitude); - mMapView.vtmMap.animator().animateTo(300, mapPosition); + val mapPosition = mMapView.vtmMap.mapPosition + mapPosition.zoom = zoom + mapPosition.setPosition(this.latitude, this.longitude) + mMapView.vtmMap.animator().animateTo(300, mapPosition) + } + } + + fun animateToCurrentPosition() { + mCurrentLocation?.run { + val mapPosition = mMapView.vtmMap.mapPosition + mapPosition.setPosition(this.latitude, this.longitude) + mMapView.vtmMap.animator().animateTo(300, mapPosition) } } } @@ -143,8 +147,7 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) : /** * 实现定位回调 */ -private class MyLocationListener(callback: (BDLocation) -> Unit) : - BDAbstractLocationListener() { +private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLocationListener() { val call = callback; override fun onReceiveLocation(location: BDLocation) { call(location) diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/NavinfoMultiMapFileTileSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/NavinfoMultiMapFileTileSource.java index aea634f0..e4b064fa 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/NavinfoMultiMapFileTileSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/NavinfoMultiMapFileTileSource.java @@ -1,39 +1,38 @@ package com.navinfo.collect.library.map.source; +import android.util.Log; + +import com.navinfo.collect.library.system.Constant; + import org.oscim.core.BoundingBox; -import org.oscim.core.MapElement; -import org.oscim.core.Tag; import org.oscim.core.Tile; import org.oscim.tiling.ITileDataSource; import org.oscim.tiling.OverzoomTileDataSource; import org.oscim.tiling.source.UrlTileSource; -import org.oscim.tiling.source.geojson.GeojsonTileSource; import org.oscim.tiling.source.mapfile.IMapFileTileSource; import org.oscim.tiling.source.mapfile.MapDatabase; import org.oscim.tiling.source.mapfile.MapFileTileSource; -import org.oscim.utils.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /* - *com.navinfo.map.source + *com.nmp.map.source *zhjch *2021/9/17 *9:46 *说明() */ -public class NavinfoMultiMapFileTileSource extends GeojsonTileSource implements IMapFileTileSource { +public class NavinfoMultiMapFileTileSource extends UrlTileSource implements IMapFileTileSource { -// private static final String DEFAULT_URL = "http://cmp-gateway-sp9-port.ayiqdpfs.cloud.app.ncloud.navinfo.com/maponline/map/online"; - private static final String DEFAULT_URL = "http://epohvqjxts85k6u-port.ayiqdpfs.cloud.app.ncloud.navinfo.com/map/online/geoJson"; - private static final String DEFAULT_PATH = "x={X}&y={Y}&z={Z}"; + private static final String DEFAULT_URL = "http://c.tile.opencyclemap.org/cycle"; + + private static final String DEFAULT_PATH = "/{Z}}/{X}/{Y}.png"; private static final TileUrlFormatter mTileUrlFormatter = URL_FORMATTER; @@ -67,7 +66,6 @@ public class NavinfoMultiMapFileTileSource extends GeojsonTileSource implements public String getTileUrl(Tile tile) { StringBuilder sb = new StringBuilder(); sb.append(DEFAULT_URL).append("?").append(mTileUrlFormatter.formatTilePath(this, tile)); - System.out.println(sb.toString()); return sb.toString(); } @@ -125,66 +123,13 @@ public class NavinfoMultiMapFileTileSource extends GeojsonTileSource implements mapDatabase.restrictToZoomRange(zoomLevels[0], zoomLevels[1]); multiMapDatabase.add(mapDatabase); } catch (IOException e) { + Log.e("jingo", e.getMessage()); log.debug(e.getMessage()); } } // return new NavinfoMultiMapDatabase(this, new NavinfoVectorTileDecoder(locale), getHttpEngine()); return new OverzoomTileDataSource(multiMapDatabase, mOverZoom); } - private static Map mappings = new LinkedHashMap<>(); - - private static Tag addMapping(String key, String val) { - Tag tag = new Tag(key, val); - mappings.put(key + "=" + val, tag); - return tag; - } - @Override - public void decodeTags(MapElement mapElement, Map properties) { - boolean hasName = false; - String fallbackName = null; - - for (Map.Entry entry : properties.entrySet()) { - String key = entry.getKey(); - Object value = entry.getValue(); - String val = (value instanceof String) ? (String) value : String.valueOf(value); - - if (key.startsWith(Tag.KEY_NAME)) { - int len = key.length(); - if (len == 4) { - fallbackName = val; - continue; - } - if (len < 7) - continue; - if (locale.equals(key.substring(5))) { - hasName = true; - mapElement.tags.add(new Tag(Tag.KEY_NAME, val, false)); - } - continue; - } - - Tag tag = mappings.get(key + "=" + val); - if (tag == null) - tag = addMapping(key, val); - mapElement.tags.add(tag); - } - - if (!hasName && fallbackName != null) - mapElement.tags.add(new Tag(Tag.KEY_NAME, fallbackName, false)); - - // Calculate height of building parts - if (!properties.containsKey(Tag.KEY_HEIGHT)) { - if (properties.containsKey(Tag.KEY_VOLUME) && properties.containsKey(Tag.KEY_AREA)) { - Object volume = properties.get(Tag.KEY_VOLUME); - String volumeStr = (volume instanceof String) ? (String) volume : String.valueOf(volume); - Object area = properties.get(Tag.KEY_AREA); - String areaStr = (area instanceof String) ? (String) area : String.valueOf(area); - float height = Float.parseFloat(volumeStr) / Float.parseFloat(areaStr); - String heightStr = String.valueOf(FastMath.round2(height)); - mapElement.tags.add(new Tag(Tag.KEY_HEIGHT, heightStr, false)); - } - } - } @Override public OpenResult open() { @@ -194,8 +139,10 @@ public class NavinfoMultiMapFileTileSource extends GeojsonTileSource implements if (result != OpenResult.SUCCESS) openResult = result; } - if(openResult != OpenResult.SUCCESS) - return super.open(); + if(openResult != OpenResult.SUCCESS) { + + return super.open(); + } return openResult; } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/system/Constant.java b/collect-library/src/main/java/com/navinfo/collect/library/system/Constant.java index d6156d20..6b355bdb 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/system/Constant.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/system/Constant.java @@ -11,6 +11,9 @@ import java.util.Map; public class Constant { + //服务地址 + public static String URL_BASE = "http://cmp-gateway-sp9-port.ayiqdpfs.cloud.app.ncloud.navinfo.com/"; + public static String MAP_PATH = Environment.getExternalStorageDirectory() + "/map/"; public static void setVisibleTypeMap(Map visibleTypeMap) { diff --git a/settings.gradle b/settings.gradle index d591dffb..b39629d4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,30 +1,32 @@ pluginManagement { repositories { - gradlePluginPortal() google() + gradlePluginPortal() mavenCentral() - maven { url 'https://jitpack.io' } maven { url "https://maven.aliyun.com/repository/google" } maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/jcenter' } - maven { url 'https://download.flutter.io' } - maven { url 'https://storage.googleapis.com/download.flutter.io' } + maven { url 'https://maven.aliyun.com/repository/central' } + maven { url 'https://jitpack.io' } } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { + google() mavenCentral() gradlePluginPortal() - maven { url 'https://jitpack.io' } + maven { url "https://maven.aliyun.com/repository/google" } maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/jcenter' } - maven { url 'https://download.flutter.io' } - maven { url 'https://storage.googleapis.com/download.flutter.io' } + maven { url 'https://maven.aliyun.com/repository/central' } + maven { url 'https://jitpack.io' } + + } } rootProject.name = "OMQualityInspection"