123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- <!--
- 更新内容:解决第一次授予权限获取不到通话记录
- 更新人:吴宝松
- 更新时间:2024/8/28
- 更新内容:点击详情可以获取同一个联系人所有号码
- 更新人:方新力
- 更新时间:2024/9.1
- 更新内容:修改顶部标题样式、通话记录中联系人未接没有标红问题
- 更新人:张志宏
- 时间:24/9/3
- -->
- <template>
- <view class="content">
- <!-- 顶部标题 -->
- <view class="head">
- <text >通话记录</text>
- </view>
- <!-- 显示通话记录 -->
- <view class="text-area">
- <view v-if="telephoneLog.length" v-for="(log, index) in limitedItems" :key="index">
- <view class="name-btn">
-
- <view v-if="switchStatus" style="display: flex;flex-direction: row; ">
- <view class="loud" @click="play(getContactName(log.number).name||getContactName(log.number).phoneNumbers[0].value)">
- <image style="width: 80%;height: 40%;margin-left: 35rpx" src="../../static/pics/laba.png"></image>
- </view>
- <view class="con-mes" @click="goToDetails(getContactName(log.number))">
- <text v-if="!getContactName(log.number).name" :style="{color:getLogDateColor(log.type)}">{{ formatPhoneNumber(getContactName(log.number).phoneNumbers[0].value) }}</text>
- <text v-else :style="{color:getLogDateColor(log.type)}">{{ truncate(getContactName(log.number).name) }}</text>
- </view>
- </view>
-
- <view v-else>
- <view class="con-mes-null" @click="goToDetails(getContactName(log.number))">
- <text v-if="!getContactName(log.number).name" :style="{color:getLogDateColor(log.type)}">{{ formatPhoneNumber(getContactName(log.number).phoneNumbers[0].value) }}</text>
- <text v-else :style="{color:getLogDateColor(log.type)}">{{ truncate(getContactName(log.number).name) }}</text>
- </view>
- </view>
-
- <view class="btn" @click="CallPhone(log.number)">
- <image class="Call" src="../../static/pics/call-out.png"></image>
- </view>
- </view>
- </view>
- <view v-else class="notFind">
- 最近无通话记录
- </view>
- </view>
- </view>
- </template>
- <script>
- const FvvUniTTS=uni.requireNativePlugin('Fvv-UniTTS');
- export default {
- data() {
- return {
- searchText: '', // 用户输入的搜索文本
- telephoneLog: [], // 存储通话记录
- contacts: [], // 存储联系人数据
- searchActive: true,
- hasPermission: false, // 用于存储权限状态
- switchStatus:false,
- isLoudVisible: true, // 初始状态为显示
- };
- },
- mounted() {
- this.requestPermissions(); // 请求权限
- },
- onShow() {
- this.init();
- this.getM();
- this.handleGetCallLogs();
- },
- computed: {
- limitedItems() {
- return this.telephoneLog.slice(0, 100); // 只获取前 200 个项目
- }//记得v-for的数组改了
- },
-
- methods: {
-
- goToDetails(item){
- console.error('item',item)
- const phoneNumbers=item.phoneNumbers
- const name=item.name;
- const phoneNumbersString=JSON.stringify(phoneNumbers)
- const phoenNumberCount=item.phoneNumbers.length;
- console.error("通话记录中的姓名",name)
- console.error("phonenumber",phoneNumbers)
- console.error("phoenNumberCount",phoenNumberCount)
- uni.navigateTo({
- url: `/pages/ContactDetails/ContactDetails?name=${encodeURIComponent(name)}&phoneNumbers=${encodeURIComponent(phoneNumbersString)}&count=${phoenNumberCount}`
- });
- },
- // 格式化电话号码
- formatPhoneNumber(value) {
- // 移除所有非数字字符
- value = value.replace(/\D/g, '');
-
- if (value.length === 11) {
- // 如果长度为11, 在第4和第9位插入空格
- return value.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3');
- } else {
- // 如果长度不为11,每4个字符插入一个空格
- return value.replace(/(\d{4})(?=\d)/g, '$1 ');
- }
- },
- truncate(value) {
- if (value.length > 9) {
- return value.slice(0, 5) + '\n' + value.substring(5, 9) + '...';
- }
- else{
- return value.slice(0, 5) + '\n' + value.substring(5, 9)
- }
- return value;
- },
- getM(){//获取本地语音开关信息
- // 从本地存储中读取开关状态
- const storedSwitchStatus = uni.getStorageSync('voiceBroadcastSwitch');
- console.log("读取的本地存储状态1:", storedSwitchStatus);
-
- if (typeof storedSwitchStatus === 'boolean') {
- this.switchStatus = storedSwitchStatus;
- }
- },
- init(){
-
- FvvUniTTS.init((callback) => {
- console.log(callback);
- },"com.iflytek.speechcloud");
-
- FvvUniTTS.onStart((res) => {
- console.log("onStart:" + res)
- });
-
- FvvUniTTS.onDone((res) => {
- console.log("onDone:" + res)
- });
-
- FvvUniTTS.onError((res) => {
- console.log("onError:" + res)
- });
- FvvUniTTS.getInstallTTS(res => {
- console.log(res)
- })
- },
- play(e){
- console.log("播放",e)
- FvvUniTTS.speak({
- text:e,
- id:2,
- });
-
- FvvUniTTS.getInstallTTS(res => {
- console.log(res+"11")
- })
- },
- setLanguage(){
- console.log("set lang : " + FvvUniTTS.setLanguage("CHINESE"));
- },
- setEngines(){
- let setEngine = "com.iflytek.speechcloud"
-
- //获取已安装的引擎
- FvvUniTTS.getInstallTTS(res => {
- if(res == null || res.length <= 0){
- return
- }
- console.log(res)
- if(JSON.stringify(res).indexOf(setEngine) < 0){
- console.log("未安装该语音引擎")
- return
- }
- console.log("set engine : " + FvvUniTTS.setEngine(setEngine));
- FvvUniTTS.speak({
- text:"设置成功",
- id:2,
- });
- })
- },
- saveFile(){
- FvvUniTTS.saveAudioFile({
- text:"hello",
- id:3,
- path:"/sdcard/test/1.wav"
- })
- },
- setVoice(){
- FvvUniTTS.setPitch(100)
- FvvUniTTS.setSpeechRate(100)
- },
- showBar() {
- this.searchActive = !this.searchActive;
- },
- requestPermissions() {
- console.log("start")
- if (plus.android && plus.android.runtimeMainActivity()) {
- const activity = plus.android.runtimeMainActivity();
- const ContextCompat = plus.android.importClass("androidx.core.content.ContextCompat");
- const ActivityCompat = plus.android.importClass("androidx.core.app.ActivityCompat");
- const PERMISSIONS = [plus.android.importClass("android.Manifest$permission").READ_CALL_LOG];
- const PackageManager = plus.android.importClass("android.content.pm.PackageManager");
- console.log("end")
- const checkPermissions = () => {
- // 检查是否已经授予权限
- if (PERMISSIONS.every(permission => ContextCompat.checkSelfPermission(activity, permission) === PackageManager.PERMISSION_GRANTED)) {
- console.log("权限已授予");
- clearInterval(permissionCheckInterval); // 停止重复检查
- this.handleGetCallLogs(); // 获取通话记录
- this.getContacts(); // 获取通讯录
- } else {
- console.log("权限未授予,继续请求权限");
- ActivityCompat.requestPermissions(activity, PERMISSIONS, 1);
- }
- };
-
-
- // 设置一个重复定时器,每2秒检查一次权限
- const permissionCheckInterval = setInterval(checkPermissions, 1000);
-
- // 回调函数处理权限请求结果
- activity.onRequestPermissionsResult = (requestCode, permissions, grantResults) => {
- if (requestCode === 1) {
- if (grantResults.length > 0 && grantResults[0] === PackageManager.PERMISSION_GRANTED) {
- console.log("权限已成功授予");
- } else {
- console.error("权限被拒绝");
- }
- }
- };
-
- // 立即检查一次权限
- checkPermissions();
- }
- },
- handleGetCallLogs() {
- if (plus.android) {
- try {
- const MainActivity = plus.android.runtimeMainActivity();
- const CallLogHelper = plus.android.importClass("com.example.mylibrary.CallLogHelper");
-
- if (CallLogHelper) {
- const logsJson = CallLogHelper.getCallLogs(MainActivity);
- console.log("Raw logsJson:", logsJson); // 打印原始数据
-
- const logsArray = JSON.parse(logsJson);
- console.log("Parsed logsArray:", logsArray); // 打印解析后的数据
-
- if (Array.isArray(logsArray)) {
- this.telephoneLog = logsArray;
- } else {
- console.error("解析后的数据不是数组");
- }
- } else {
- console.error("CallLogHelper 类未加载");
- }
- } catch (e) {
- console.error("获取通话记录失败:", e);
- }
- } else {
- console.error("Android 环境未准备好");
- }
- },
- getContacts() {
- const that = this;
- plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) {
- addressbook.find(
- ["displayName", "phoneNumbers"],
- function(contacts) {
- that.contacts = contacts.map(contact => ({
- id: contact.id,
- name: contact.displayName,
- phoneNumbers: contact.phoneNumbers.map(phone => phone.value)
- }));
- console.log("获取到的联系人数据:", that.contacts);
- },
- function(error) {
- console.error("获取通讯录失败: " + error.message);
- },
- { multiple: true }
- );
- });
- },
- getContactName(number) {
- // 清理电话号码,移除所有非数字字符
- const cleanedNumber = number.replace(/\D/g, '');
-
- // 查找匹配的联系人
- const contact = this.contacts.find(contact =>
- contact.phoneNumbers.some(phone => phone.replace(/\D/g, '') === cleanedNumber)
- );
-
- // 判断是否找到联系人并设置 phoneNumbersArray
- let phoneNumbersArray = contact === undefined ?[number]: contact.phoneNumbers ;
-
- phoneNumbersArray = phoneNumbersArray.map(number => ({
- "value": number
- }));
-
- // 返回包含姓名和电话号码的对象,其中电话号码是 JSON 格式的字符串
- return {
- name: contact && contact.name ? contact.name : null,
- phoneNumbers: phoneNumbersArray
- };
- },
- CallPhone(number) {
- plus.device.dial(number, false);
- // 延迟刷新通话记录
- setTimeout(() => {
- this.handleGetCallLogs();
- }, 2000); // 等待 2 秒,确保通话记录有时间更新
- },
- getLogDateColor(callType){
- return callType==3 ? '#ff0000' : '#000000'
- },
- filterContacts() {
- // 实现模糊查找逻辑
- const searchText = this.searchText.toLowerCase();
- this.filteredContacts = this.contacts.filter(contact => {
- return (contact.name || '').toLowerCase().includes(searchText) ||
- contact.phoneNumbers.some(phone => phone.toLowerCase().includes(searchText));
- });
- }
- },
- mounted() {
- this.getM();
- }
- }
- </script>
- <style>
- /* 样式定义 */
- .null {}
- /*顶部标题与屏幕顶部间隔8%*/
- .head{
- width: 100%;
- height: 100px;
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- background-color: #f0efef;
- margin-top: 10%;
- margin-bottom: 10rpx;
- padding: 8rpx;
- font-size: 90rpx;
- box-shadow: 0 2rpx 3rpx rgba(143, 143, 143, 0.2);
- }
- hr{
- height: 2px;
- width: 90%;
- margin-top: 10px;
- }
- /* 顶部导航栏样式 */
- .navbar {
- display: flex;
- justify-content: space-around;
- align-items: center;
- width: 100%;
- background-color: #F8F8F8;
- height: 90px;
- position: fixed;
- top: 0;
- z-index: 999;
- }
- .icon {
- justify-content: space-around;
- width: 100rpx;
- height: 100rpx;
- }
- /* 搜索框样式 */
- .uni-column {
- width: 690rpx;
- height: 180rpx;
- border: 1px solid black;
- margin-top: 18rpx;
- border-radius: 20rpx;
- font-size: 50rpx;
- display: flex;
- justify-content: space-between;
- }
- .search-input {
- width: 75%;
- display: flex;
- align-items: center;
- }
- .search-img {
- width: 25%;
- display: flex;
- border-left: 1px solid black;
- justify-content: center;
- align-items: center;
- }
- .search-input input {
- width: 90%;
- height: 80%;
- font-size: 50rpx;
- padding: 10px;
- }
- .search-img image {
- width: 50%;
- height: 50%;
- font-size: 50rpx;
- }
- /* 通话记录区域样式 */
- .content {
- min-height: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- background-color: #f0efef;
- }
- .con-mes,.con-mes-null {
- line-height: 1.1;
- font-size: 35px;
- font-weight: 700;
- display: flex;
- align-items: center;
- justify-content: center;
- text-align: center;
- white-space: pre-line; /* 保证换行符有效 */
- word-wrap: break-word; /* 确保长单词换行 */
- width: 410rpx;
- height: 200rpx;
- border: none;
- background-color: white;
- }
- .con-mes-null{
- border-radius: 20rpx 0rpx 0rpx 20rpx;
- width: 510rpx;
- height: 200rpx;
- }
- .name-btn {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 690rpx;
- height: 200rpx;
- border: 1px solid black;
- margin-top: 18rpx;
- border-radius: 20rpx;
- font-size: 50rpx;
- }
- .text-area {
- height: 70%;
- display: flex;
- flex-direction: column;
- align-items: center;
- }
- .loud {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100rpx;
- height: 200rpx;
- border-radius: 20rpx 0rpx 0rpx 20rpx;
- background-color: white;
- }
- .btn {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 180rpx;
- height: 200rpx;
- background-color: #ecfff3;
- border-radius: 0rpx 20rpx 20rpx 0rpx;
- }
- .Call {
- width: 100rpx;
- height: 100rpx;
- object-fit: contain;
- }
- .notFind {
- height: 100%;
- font-size: 50rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- color: black;
- margin-top: 50rpx;
- }
- </style>
|