获取通话记录
This commit is contained in:
parent
87c41341fd
commit
a82e726d5f
|
|
@ -21,14 +21,13 @@ android {
|
|||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId = "com.czg.cashier_reserve"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||
minSdk = flutter.minSdkVersion
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutter.versionCode
|
||||
versionName = flutter.versionName
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 33
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
|
@ -43,3 +42,8 @@ android {
|
|||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(name:'callmodule-release',ext:'aar')
|
||||
implementation('com.android.support:appcompat-v7:28.0.0')
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,7 +1,10 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
|
||||
<application
|
||||
android:label="cashier_reserve"
|
||||
android:name="${applicationName}"
|
||||
android:name=".CzgApplication"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package com.czg.cashier_reserve;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
|
||||
public class ContextHolder {
|
||||
private static ContextHolder instance;
|
||||
private Context context;
|
||||
private BinaryMessenger binaryMessenger;
|
||||
|
||||
private ContextHolder() {}
|
||||
|
||||
public static ContextHolder getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ContextHolder();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setBinaryMessenger(BinaryMessenger binaryMessenger) {
|
||||
this.binaryMessenger = binaryMessenger;
|
||||
}
|
||||
|
||||
public BinaryMessenger getBinaryMessenger() {
|
||||
return binaryMessenger;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.czg.cashier_reserve;
|
||||
|
||||
import cn.kaer.callmodule.KeSdk;
|
||||
import io.flutter.Log;
|
||||
import io.flutter.app.FlutterApplication;
|
||||
|
||||
public class CzgApplication extends FlutterApplication {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,46 @@
|
|||
package com.czg.cashier_reserve;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.czg.cashier_reserve.channel.ChannelManager;
|
||||
|
||||
import cn.kaer.callmodule.KeSdk;
|
||||
import io.flutter.Log;
|
||||
import io.flutter.embedding.android.FlutterActivity;
|
||||
import io.flutter.embedding.engine.FlutterEngine;
|
||||
|
||||
public class MainActivity extends FlutterActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getFlutterEngine()!= null && getFlutterEngine().getDartExecutor().getBinaryMessenger()!= null) {
|
||||
Log.i("MainActivity","onCreate +++ " + this);
|
||||
} else {
|
||||
Log.e("MainActivity", "FlutterEngine or BinaryMessenger is null, cannot setup EventChannel.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine);
|
||||
|
||||
Log.i("MainActivity","configureFlutterEngine +++ " + this);
|
||||
|
||||
ContextHolder.getInstance().setContext(this);
|
||||
ContextHolder.getInstance().setBinaryMessenger(flutterEngine.getDartExecutor().getBinaryMessenger());
|
||||
|
||||
KeSdk.get().init(new KeSdk.Builder().setContext(this)//必选
|
||||
.setClz(MainActivity.class)//可选 设置拉起通话页面
|
||||
.setPstnIncomingDelay(2000)//可选 设置有线振铃延迟时间,默认1500
|
||||
.setAutoAnswerByHookoff(true)//可选 设置来电摘手柄自动接听,默认false
|
||||
.setRingPlayAuto(true)//可选 设置来电自动播放铃声,默认true
|
||||
.setPstnRingType(0)//可选 pstn设置铃声 0系统铃声 1和弦铃声
|
||||
.setAutoTermByHookon(true)//可选 设置放手柄自动挂断,默认false
|
||||
.setAutoChangeChannelByHookoff(true));//可选 设置通话中摘手柄自动切换到手柄通道,默认false
|
||||
|
||||
ChannelManager.createChannel(flutterEngine.getDartExecutor().getBinaryMessenger());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
package com.czg.cashier_reserve.call;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.provider.CallLog;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.czg.cashier_reserve.ContextHolder;
|
||||
import com.czg.cashier_reserve.channel.EventChannelManager;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import io.flutter.Log;
|
||||
|
||||
public class CallManager {
|
||||
private static final String[] columns = {CallLog.Calls.CACHED_NAME// 通话记录的联系人
|
||||
, CallLog.Calls.NUMBER// 通话记录的电话号码
|
||||
, CallLog.Calls.DATE// 通话记录的日期
|
||||
, CallLog.Calls.DURATION// 通话时长
|
||||
, CallLog.Calls.TYPE};// 通话类型}
|
||||
|
||||
public static void loadCallLog() {
|
||||
Context mainActivityContext = ContextHolder.getInstance().getContext();
|
||||
Log.i("CallManager","loadCallLog -- " + mainActivityContext);
|
||||
Cursor cursor = mainActivityContext.getContentResolver().query(CallLog.Calls.CONTENT_URI,
|
||||
columns, null, null, null);
|
||||
|
||||
JSONArray callLogArray = new JSONArray();
|
||||
|
||||
Log.i("CallManager","cursor count:" + cursor.getCount());
|
||||
while (cursor.moveToNext()) {
|
||||
@SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)); //姓名
|
||||
@SuppressLint("Range") String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)); //号码
|
||||
@SuppressLint("Range") long dateLong = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE)); //获取通话日期
|
||||
@SuppressLint("SimpleDateFormat") String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(dateLong));
|
||||
// @SuppressLint("SimpleDateFormat") String time = new SimpleDateFormat("HH:mm").format(new Date(dateLong));
|
||||
@SuppressLint("Range") int duration = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION));//获取通话时长,值为多少秒
|
||||
@SuppressLint("Range") int type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE)); //获取通话类型:1.呼入2.呼出3.未接
|
||||
// @SuppressLint("SimpleDateFormat") String dayCurrent = new SimpleDateFormat("dd").format(new Date());
|
||||
// @SuppressLint("SimpleDateFormat") String dayRecord = new SimpleDateFormat("dd").format(new Date(dateLong));
|
||||
|
||||
JSONObject callLog = new JSONObject();
|
||||
try {
|
||||
callLog.put("name", name);
|
||||
callLog.put("number", number);
|
||||
callLog.put("date", date);
|
||||
callLog.put("duration", duration);
|
||||
callLog.put("type", type);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
callLogArray.put(callLog);
|
||||
}
|
||||
|
||||
Log.i("CallManager", "callLogArray: " + callLogArray);
|
||||
|
||||
Intent broad = new Intent(EventChannelManager.Action.GET_CALL_LOG_FINISH);
|
||||
broad.putExtra("callLog", callLogArray.toString());
|
||||
mainActivityContext.sendBroadcast(broad);
|
||||
Log.i("CallManager", "send broadcast");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.czg.cashier_reserve.channel;
|
||||
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
|
||||
public class ChannelManager {
|
||||
public static void createChannel(BinaryMessenger messenger) {
|
||||
MessageChannel.addMessageChannel(messenger);
|
||||
EventChannelManager.addEventChannel(messenger);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.czg.cashier_reserve.channel;
|
||||
|
||||
public class ChannelNames {
|
||||
public static final String BASE_NAME = "com.czg.cashier_reserve/";
|
||||
|
||||
public static final String GET_CALL_LOG = "getCallLog";
|
||||
|
||||
public static final String CALL_LOG_CALLBACK = "callLogCallback";
|
||||
|
||||
public static String getChannelName(String name) {
|
||||
return BASE_NAME + name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package com.czg.cashier_reserve.channel;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.czg.cashier_reserve.ContextHolder;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.Log;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
|
||||
public class EventChannelManager {
|
||||
public static Map<String, BroadcastReceiver> receiverMap = new HashMap<>();
|
||||
public static List<BroadcastReceiver> broadcastReceiverList = new ArrayList<>();
|
||||
|
||||
private static EventChannel callLogChannel;
|
||||
|
||||
public static void addEventChannel(BinaryMessenger messenger) {
|
||||
getCallLogCallback(messenger);
|
||||
}
|
||||
|
||||
public static void getCallLogCallback(BinaryMessenger messenger) {
|
||||
if (messenger == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i("EventChannelManager", "getCallLogCallback");
|
||||
|
||||
callLogChannel = new EventChannel(messenger, ChannelNames.getChannelName(ChannelNames.CALL_LOG_CALLBACK));
|
||||
|
||||
callLogChannel.setStreamHandler(new EventChannel.StreamHandler() {
|
||||
private BroadcastReceiver broadCast;
|
||||
|
||||
@Override
|
||||
public void onListen(Object o, EventChannel.EventSink eventSink) {
|
||||
Log.i("EventChannelManager", "onListen");
|
||||
broadCast = EventChannelManager.getBroadCast(eventSink);
|
||||
Context context = ContextHolder.getInstance().getContext();
|
||||
IntentFilter intentFilter = new IntentFilter(EventChannelManager.Action.GET_CALL_LOG_FINISH);
|
||||
context.registerReceiver(broadCast, intentFilter);
|
||||
receiverMap.put(EventChannelManager.Action.GET_CALL_LOG_FINISH, broadCast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(Object o) {
|
||||
Context context = ContextHolder.getInstance().getContext();
|
||||
context.unregisterReceiver(broadCast);
|
||||
broadcastReceiverList.remove(broadCast);
|
||||
broadCast = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static BroadcastReceiver getBroadCast(EventChannel.EventSink eventSink) {
|
||||
BroadcastReceiver b = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.i("EventChannelManager", "onReceive");
|
||||
String action = intent.getAction();
|
||||
Log.i("EventChannelManager", "action name == " + action);
|
||||
if (Action.GET_CALL_LOG_FINISH.equals(action)) {
|
||||
String extra = intent.getStringExtra("callLog");
|
||||
eventSink.success(extra);
|
||||
} else {
|
||||
eventSink.error("没有该事件", null, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
broadcastReceiverList.add(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
// 这里假设Action是一个定义了相关常量的类,示例如下,你可以根据实际情况调整
|
||||
public static class Action {
|
||||
public static final String GET_CALL_LOG_FINISH = ChannelNames.BASE_NAME + "get_call_log_finish";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.czg.cashier_reserve.channel;
|
||||
|
||||
import com.czg.cashier_reserve.call.CallManager;
|
||||
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class MessageChannel {
|
||||
public static void addMessageChannel(BinaryMessenger messenger) {
|
||||
callLogChannel(messenger);
|
||||
}
|
||||
|
||||
public static void callLogChannel(BinaryMessenger messenger) {
|
||||
if (messenger == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
MethodChannel methodChannel = new MethodChannel(messenger, ChannelNames.getChannelName(ChannelNames.GET_CALL_LOG));
|
||||
|
||||
methodChannel.setMethodCallHandler((call, result) -> {
|
||||
System.out.println("call.method: " + call.method);
|
||||
if (call.method.equals(ChannelNames.GET_CALL_LOG)) {
|
||||
System.out.println("加载通话记录");
|
||||
result.success(null);
|
||||
CallManager.loadCallLog();
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -15,4 +15,13 @@
|
|||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="DialerDigit" parent="@android:style/TextAppearance.Medium">
|
||||
<item name="android:padding">5dp</item>
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="android:layout_centerInParent">true</item>
|
||||
<item name="android:soundEffectsEnabled">false</item>
|
||||
<!-- <item name="android:background">@drawable/keyboard_numb_bg</item>-->
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,33 @@
|
|||
allprojects {
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs 'libs'
|
||||
}
|
||||
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
afterEvaluate { project ->
|
||||
if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) {
|
||||
println "project: ${project.name} Namespace get: ${project.android.namespace}"
|
||||
def packageName = project.android.namespace ?: project.android.defaultConfig.applicationId ?: project.android.sourceSets.main.manifest.srcFile.text.find(/package="([^"]*)"/) ?: project.group
|
||||
// project.android.namespace = packageName
|
||||
// println "Namespace set to: ${packageName} for project: ${project.name}"
|
||||
|
||||
// 如果包名不包含 "com.baidu",则设置命名空间
|
||||
if (!packageName.contains('com.baidu')) {
|
||||
project.android.namespace = packageName
|
||||
println "Namespace set to: ${packageName} for project: ${project.name}"
|
||||
} else {
|
||||
println "Skipping namespace setting for project ${project.name} as the package name contains 'com.baidu'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = "../build"
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
import 'package:cashier_reserve/common/print/print.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'names.dart';
|
||||
|
||||
class MyEventChannel {
|
||||
static void startListener() {
|
||||
onGetCallLogResult();
|
||||
}
|
||||
|
||||
static void onGetCallLogResult() {
|
||||
EventChannel channel = EventChannel(getChannelName(kCallLogCallback));
|
||||
channel.receiveBroadcastStream().listen((Object? o) {
|
||||
yjPrint("onGetCallLogResult");
|
||||
yjPrint(o);
|
||||
// AlipayPayResultEvent event = AlipayPayResultEvent();
|
||||
// if (o is int) {
|
||||
// event.resultStatus = o;
|
||||
// } else {
|
||||
// event.resultStatus = int.parse(o as String);
|
||||
// }
|
||||
// EventManager.postEvent(event);
|
||||
}, onError: (Object error) {
|
||||
yjPrint("onGetCallLogResult error");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../print/print.dart';
|
||||
import 'names.dart';
|
||||
|
||||
class ChannelManager {
|
||||
static Future<void> getCallLog(String param) async {
|
||||
MethodChannel channel = MethodChannel(getChannelName(kGetCallLog));
|
||||
try {
|
||||
final result = await channel.invokeMethod(kGetCallLog, param);
|
||||
yjPrint(result);
|
||||
} on PlatformException catch (e) {
|
||||
yjPrint('$kGetCallLog 发生异常:$e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
const String kChannelBaseName = 'com.czg.cashier_reserve/';
|
||||
|
||||
const String kGetCallLog = 'getCallLog';
|
||||
|
||||
const String kCallLogCallback = 'callLogCallback';
|
||||
|
||||
String getChannelName(name) {
|
||||
return kChannelBaseName + name;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../channel/channel_event.dart';
|
||||
|
||||
class AppManager {
|
||||
static Future<void> initThirdPackage() async {
|
||||
MyEventChannel.startListener();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
void yjPrint(Object? object) {
|
||||
if (kDebugMode) {
|
||||
print(object);
|
||||
}
|
||||
}
|
||||
|
|
@ -77,7 +77,9 @@ class ReserveView extends BaseUI {
|
|||
width: 5,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
provider.loadCallLog();
|
||||
},
|
||||
child: const SizedBox(
|
||||
width: 40,
|
||||
height: 40,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cashier_reserve/common/base/ui_model.dart';
|
||||
import 'package:cashier_reserve/common/channel/channel_manager.dart';
|
||||
|
||||
class ReserveViewModel extends BaseUIModel {
|
||||
Map<int, String> weekdayMap = {
|
||||
|
|
@ -17,6 +18,14 @@ class ReserveViewModel extends BaseUIModel {
|
|||
2: "后",
|
||||
};
|
||||
|
||||
// ReserveViewModel() {
|
||||
// loadData();
|
||||
// }
|
||||
|
||||
void loadCallLog() {
|
||||
ChannelManager.getCallLog("getCallLog");
|
||||
}
|
||||
|
||||
String getCurrentDate() {
|
||||
DateTime now = DateTime.now();
|
||||
return "${now.year}/${now.month}/${now.day}";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cashier_reserve/common/manager/app_manager.dart';
|
||||
import 'package:cashier_reserve/root_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
|
@ -8,7 +9,7 @@ import 'package:flutter_localizations/flutter_localizations.dart';
|
|||
import 'common/base/widgets.dart';
|
||||
import 'common/local/cupertino_localizations_delegate.dart';
|
||||
|
||||
void main() {
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
/// 状态栏沉浸
|
||||
|
|
@ -16,6 +17,9 @@ void main() {
|
|||
statusBarColor: Colors.transparent,
|
||||
statusBarIconBrightness: getAppBrightness(false),
|
||||
statusBarBrightness: getAppBrightness(false)));
|
||||
|
||||
await AppManager.initThirdPackage();
|
||||
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue