app/src/main/AndroidManifest.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
app/src/main/java/com/example/firstapp/activity/ContentDetailActivity.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
app/src/main/java/com/example/firstapp/database/response/ContentResponse.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
app/src/main/java/com/example/firstapp/database/service/ApiService.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
app/src/main/res/layout/activity_content_detail.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
app/src/main/res/values/themes.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
app/src/main/res/xml/network_security_config.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
app/src/main/AndroidManifest.xml
@@ -107,6 +107,10 @@ <activity android:name=".activity.PickupActivity" android:exported="false"/> <activity android:name=".activity.ContentDetailActivity" android:theme="@style/Theme.ContentDetail" android:exported="false" /> </application> app/src/main/java/com/example/firstapp/activity/ContentDetailActivity.kt
对比新文件 @@ -0,0 +1,84 @@ package com.example.firstapp.activity import android.os.Bundle import android.webkit.WebView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.example.firstapp.R import com.example.firstapp.database.service.RetrofitClient import kotlinx.coroutines.launch class ContentDetailActivity : AppCompatActivity() { private lateinit var webView: WebView private lateinit var toolbar: androidx.appcompat.widget.Toolbar companion object { const val EXTRA_CONTENT_TYPE = "content_type" const val EXTRA_TITLE = "title" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_content_detail) // 初始化视图 webView = findViewById(R.id.webView) toolbar = findViewById(R.id.toolbar) // 设置标题 val title = intent.getStringExtra(EXTRA_TITLE) ?: "内容详情" toolbar.title = title setSupportActionBar(toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) toolbar.setNavigationOnClickListener { finish() } // 获取内容类型 val contentType = intent.getStringExtra(EXTRA_CONTENT_TYPE) if (contentType != null) { loadContent(contentType) } else { Toast.makeText(this, "参数错误", Toast.LENGTH_SHORT).show() finish() } } private fun loadContent(type: String) { lifecycleScope.launch { try { val response = RetrofitClient.apiService.getContentByType(type) if (response.code == 200 && response.data != null) { // 构建HTML内容 val htmlContent = """ <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { padding: 16px; font-size: 16px; line-height: 1.5; } </style> </head> <body> ${response.data.content} </body> </html> """.trimIndent() webView.loadDataWithBaseURL(null, htmlContent, "text/html", "UTF-8", null) } else { Toast.makeText(this@ContentDetailActivity, "获取内容失败", Toast.LENGTH_SHORT).show() } } catch (e: Exception) { Toast.makeText(this@ContentDetailActivity, "网络错误", Toast.LENGTH_SHORT).show() } } } } app/src/main/java/com/example/firstapp/database/response/ContentResponse.kt
对比新文件 @@ -0,0 +1,20 @@ package com.example.firstapp.database.response data class ContentResponse( val code: Int, val msg: String, val data: ContentData? ) data class ContentData( val id: Long, val type: String, val title: String, val content: String, val version: String, val status: Int, val createTime: String, val updateTime: String, val creator: String?, val updater: String? ) app/src/main/java/com/example/firstapp/database/service/ApiService.kt
@@ -2,10 +2,11 @@ import com.example.firstapp.database.entity.ApiResponse import com.example.firstapp.database.entity.KeywordConfig import com.example.firstapp.database.entity.KeywordEntity import com.example.firstapp.database.response.ContentResponse import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import retrofit2.http.GET import retrofit2.http.Query /** * API调用接口 @@ -14,12 +15,15 @@ @GET("keywords") suspend fun getKeywords():ApiResponse<List<KeywordConfig>> //异步挂起 @GET("cloudContent/getByType") suspend fun getContentByType(@Query("type") type: String): ContentResponse } // 创建Retrofit实例(单例) object RetrofitClient{ private const val BASE_URL ="http://47.96.225.205:9009/cloud/" private const val BASE_URL ="http://192.168.1.213:8888/jshERP-boot/" //添加Gson解析器,用于自动将JSON响应转换为Kotlin/Java对象 private val retrofit = Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build() app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
@@ -15,6 +15,7 @@ import androidx.navigation.fragment.findNavController import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.example.firstapp.R import com.example.firstapp.activity.ContentDetailActivity import com.example.firstapp.databinding.FragmentNotificationsBinding import com.example.firstapp.ui.reminderOther.ReminderOtherAddActivity2 import com.example.firstapp.ui.reminderOther.ReminderSettingsFragmentOther @@ -74,6 +75,16 @@ // 分享给好友 binding.shareToFriends.setOnClickListener { shareToWechat() } // 隐私协议 binding.privacyPolicy.setOnClickListener { startContentActivity("privacy_policy", "隐私协议") } // 如何使用 binding.howToUse.setOnClickListener { startContentActivity("user_guide", "使用说明") } } @@ -137,6 +148,14 @@ } } private fun startContentActivity(type: String, title: String) { val intent = Intent(requireContext(), ContentDetailActivity::class.java).apply { putExtra(ContentDetailActivity.EXTRA_CONTENT_TYPE, type) putExtra(ContentDetailActivity.EXTRA_TITLE, title) } startActivity(intent) } override fun onDestroyView() { super.onDestroyView() _binding = null app/src/main/res/layout/activity_content_detail.xml
对比新文件 @@ -0,0 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> app/src/main/res/values/themes.xml
@@ -25,4 +25,10 @@ <item name="fullscreenBackgroundColor">@color/light_blue_600</item> <item name="fullscreenTextColor">@color/light_blue_A200</item> </style> <style name="Theme.ContentDetail" parent="Theme.MaterialComponents.Light.NoActionBar"> <!-- 其他属性保持不变 --> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style> </resources> app/src/main/res/xml/network_security_config.xml
@@ -2,6 +2,11 @@ <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">47.96.225.205</domain> <domain includeSubdomains="true">192.168.1.213</domain> <!-- 可添加其他域名或IP(如192.168.0.101) --> <!-- 如果本地服务使用自签名证书,需在 network_security_config.xml 中信任该证书:--> <!-- <trust-anchors>--> <!-- <certificates src="@raw/my_custom_cert"/> <!– 证书放在 res/raw 目录 –>--> <!-- </trust-anchors>--> </domain-config> </network-security-config>