setting.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <!--
  2. 修改了语音开关,提供语音安装包下载途径,实际实现了语音控制
  3. 编写人:吴宝松
  4. 最后修改时间:2024.9.28
  5. 本代码是设置页面,提供设置选项。设置包括使用说明书、联系人排序方式、地理位置显示、语音播报、版本查询及更新。
  6. 编写人:张志宏
  7. 最后更新时间:8.21
  8. 修改联系人排序及来电地址显示框高度
  9. -->
  10. <template>
  11. <view class="content">
  12. <!-- 使用说明书 -->
  13. <view class="using-manual">
  14. <p class="text-left">使用说明书</p>
  15. <image class="enter-right" src="../../static/pics/enter-right.png" mode=""></image>
  16. </view>
  17. <!-- 语音播报 -->
  18. <view class="voice-broadcast" @click="toggleSwitch()">
  19. <p class="text-left">语音播报</p>
  20. <view class="icon">
  21. <image v-if="switchStatus" class="voice-switch" src="../../static/pics/switch-on.png" mode=""></image>
  22. <image v-else class="voice-switch" src="../../static/pics/switch-off.png" mode=""></image>
  23. </view>
  24. </view>
  25. <!-- 版本信息 -->
  26. <view class="version-details">
  27. <p class="text-left">当前版本</p>
  28. {{version_number}}
  29. </view>
  30. <view class="version-details">
  31. <p class="text-left">到期时间</p>
  32. {{version_number}}
  33. </view>
  34. <view class="version-details" @click="navigateToPage()">
  35. <p class="text-left">联系我们</p>
  36. <image class="enter-right" src="../../static/pics/enter-right.png" mode=""></image>
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. export default{
  42. data(){
  43. return{
  44. version_number:"",
  45. switchStatus:false,//语音播报开关初始为关闭状态
  46. };
  47. },
  48. methods: {
  49. navigateToPage() {
  50. uni.navigateTo({
  51. url: '/pages/contact/contact'
  52. });
  53. },
  54. currentVersion() {
  55. this.version_number = "1.0.0";
  56. },
  57. // 判断是否为 Android 平台的 App 环境
  58. isApp() {
  59. const platform = uni.getSystemInfoSync().platform;
  60. return platform === 'android' && typeof plus !== 'undefined';
  61. },
  62. // 检测 TTS 引擎是否已安装
  63. checkTTSInstalled(packageName) {
  64. if (this.isApp()) {
  65. try {
  66. return plus.runtime.isApplicationExist({ pname: packageName });
  67. } catch (error) {
  68. console.error("检测TTS安装失败: ", error);
  69. }
  70. }
  71. return false;
  72. },
  73. // 请求 Android 权限
  74. requestAndroidPermissions(callback) {
  75. if (this.isApp()) {
  76. const main = plus.android.runtimeMainActivity();
  77. const permissions = [
  78. "android.permission.WRITE_EXTERNAL_STORAGE",
  79. "android.permission.REQUEST_INSTALL_PACKAGES"
  80. ];
  81. const ActivityCompat = plus.android.importClass("androidx.core.app.ActivityCompat");
  82. permissions.forEach(permission => {
  83. const hasPermission = ActivityCompat.checkSelfPermission(main, permission);
  84. if (hasPermission !== 0) {
  85. ActivityCompat.requestPermissions(main, [permission], 0);
  86. }
  87. });
  88. callback();
  89. }
  90. },
  91. // 安装 APK
  92. installAPK() {
  93. if (this.isApp()) {
  94. const apkPath = plus.io.convertLocalFileSystemURL("/static/tts_engine.apk");
  95. plus.runtime.install(apkPath, {}, () => {
  96. console.log('APK安装成功');
  97. this.switchStatus = true; // 安装成功后开启开关
  98. this.saveSwitchStatus(); // 保存当前开关状态
  99. }, (error) => {
  100. console.error('APK安装失败: ', error.message);
  101. });
  102. }
  103. },
  104. // 切换开关状态
  105. toggleSwitch() {
  106. const ttsPackageName = "com.iflytek.speechcloud";
  107. if (this.switchStatus) {
  108. // 关闭语音播报的逻辑
  109. console.log("关闭语音播报");
  110. // 可以添加其他关闭逻辑,例如停止 TTS 服务
  111. this.switchStatus = false; // 切换状态为关闭
  112. } else {
  113. // 开启语音播报,先请求权限再检测 TTS 是否已安装
  114. this.requestAndroidPermissions(() => {
  115. if (!this.checkTTSInstalled(ttsPackageName)) {
  116. this.installAPK();
  117. } else {
  118. console.log('TTS引擎已安装');
  119. this.switchStatus = true; // 切换状态为开启
  120. }
  121. });
  122. }
  123. this.saveSwitchStatus(); // 保存当前开关状态
  124. },
  125. // 保存当前开关状态到本地存储
  126. saveSwitchStatus() {
  127. uni.setStorageSync('voiceBroadcastSwitch', this.switchStatus);
  128. },
  129. // 初始化应用时读取本地存储的开关状态
  130. initializeApp() {
  131. const ttsPackageName = "com.iflytek.speechcloud";
  132. // 从本地存储中读取开关状态
  133. const storedSwitchStatus = uni.getStorageSync('voiceBroadcastSwitch');
  134. console.log("读取的本地存储状态:", storedSwitchStatus);
  135. // 检测 TTS 引擎是否存在
  136. const isTTSInstalled = this.checkTTSInstalled(ttsPackageName);
  137. if (typeof storedSwitchStatus === 'boolean') {
  138. // 如果本地存储的开关状态为开启,但 TTS 引擎已被卸载
  139. if (storedSwitchStatus && !isTTSInstalled) {
  140. console.log("检测到本地存储为开启状态,但 TTS 引擎已被卸载,重置为关闭状态");
  141. this.switchStatus = false;
  142. uni.setStorageSync('voiceBroadcastSwitch', false); // 更新存储状态为关闭
  143. } else {
  144. this.switchStatus = storedSwitchStatus;
  145. }
  146. } else if (isTTSInstalled) {
  147. // 如果没有存储的状态,但检测到 TTS 引擎已安装,默认开启
  148. console.log("检测到 TTS 引擎已安装,默认开启语音播报");
  149. this.switchStatus = true;
  150. uni.setStorageSync('voiceBroadcastSwitch', true); // 存储状态为开启
  151. } else {
  152. // 如果没有存储的状态,且 TTS 引擎未安装,则默认关闭
  153. console.log("TTS 引擎未安装,默认关闭语音播报");
  154. this.switchStatus = false;
  155. }
  156. },
  157. contactUs() {
  158. uni.showModal({
  159. title: '联系我们',
  160. content: '邮箱:example@example.com',
  161. showCancel: false, // 是否显示取消按钮
  162. confirmText: '确定', // 确认按钮文字
  163. success: (res) => {
  164. if (res.confirm) {
  165. console.log('用户点击确定');
  166. }
  167. }
  168. });
  169. }
  170. },
  171. mounted() {
  172. this.initializeApp(); // 初始化应用
  173. },
  174. //创建时启动方法
  175. created() {
  176. this.currentVersion();
  177. }
  178. }
  179. </script>
  180. <style>
  181. .content{
  182. /*整体容器,flex布局,垂直排列子元素并居中对齐,子元素从上开始对齐,高度占满整个视口*/
  183. display: flex;
  184. align-items: center;
  185. flex-direction: column;
  186. justify-content: flex-start;
  187. width: 100vw;
  188. height: 100vh;
  189. background-color: #f0efef;
  190. }
  191. .using-manual{
  192. /*使用说明书,flex布局,文本与enter-right两侧对齐*/
  193. display: flex;
  194. align-items: center;
  195. justify-content: space-between;
  196. height: 90rpx;
  197. margin-top: 30rpx;
  198. font-size: 60rpx;
  199. font-weight: 60;
  200. }
  201. .enter-right{
  202. /*使用说明书右侧按钮,右对齐,高度,宽度。*/
  203. margin-right: 10rpx;
  204. height: 60rpx;
  205. width: 60rpx;
  206. }
  207. .numbers-of-call{
  208. margin-top: 10rpx;
  209. }
  210. .voice-broadcast{
  211. /*语音播报flex布局,space-between水平均匀分布,为每个块元素之间添加间距*/
  212. display: flex;
  213. align-items: center;
  214. justify-content: space-between;
  215. height: 90rpx;
  216. margin-bottom: 10rpx;
  217. font-size: 60rpx;
  218. font-weight: 60;
  219. }
  220. .voice-switch{
  221. margin-top: 10rpx;
  222. width: 120rpx;
  223. height: 130rpx;
  224. }
  225. .version-details {
  226. display: flex;
  227. align-items: center;
  228. justify-content: space-between;
  229. height: 90rpx;
  230. font-size: 60rpx;
  231. font-weight: 60;
  232. }
  233. .using-manual,.contact-sorting, .incoming-call-address-display,.voice-broadcast,.version-details {
  234. /*所有组件的间距、宽度、边框、内间距、背景颜色、边框弧度、左右外间距、字体类型*/
  235. margin-bottom: 10rpx;
  236. width: 90%;
  237. border: 1px solid #e0e0e0;
  238. padding: 10rpx;
  239. background-color: #ffffff;
  240. border-radius: 20rpx;
  241. margin-left: 10rpx;
  242. margin-right: 10rpx;
  243. margin-bottom: 10rpx;
  244. }
  245. .line{
  246. /*分隔线,宽度、height参数为分隔线的粗细、颜色、上下间隔*/
  247. width: 96%;
  248. height: 1rpx;
  249. background-color: #dbdbdb;
  250. margin: 9rpx 0;
  251. }
  252. .initial{
  253. text-align: left;
  254. }
  255. .text-left{
  256. text-align: left;
  257. }
  258. </style>