diff --git a/packages/phone_log/android/src/main/java/com/jiajiabingcheng/phonelog/CallRecord.java b/packages/phone_log/android/src/main/java/com/jiajiabingcheng/phonelog/CallRecord.java index fba0e48..f183870 100644 --- a/packages/phone_log/android/src/main/java/com/jiajiabingcheng/phonelog/CallRecord.java +++ b/packages/phone_log/android/src/main/java/com/jiajiabingcheng/phonelog/CallRecord.java @@ -4,32 +4,32 @@ class CallRecord { - CallRecord() {} + CallRecord() {} - String formattedNumber; - String number; - String callType; - int dateYear; - int dateMonth; - int dateDay; - int dateHour; - int dateMinute; - int dateSecond; - long duration; + String formattedNumber; + String number; + String callType; + int dateYear; + int dateMonth; + int dateDay; + int dateHour; + int dateMinute; + int dateSecond; + long duration; - HashMap toMap() { - HashMap recordMap = new HashMap<>(); - recordMap.put("formattedNumber", formattedNumber); - recordMap.put("number", number); - recordMap.put("callType", callType); - recordMap.put("dateYear", dateYear); - recordMap.put("dateMonth", dateMonth); - recordMap.put("dateDay", dateDay); - recordMap.put("dateHour", dateHour); - recordMap.put("dateMinute", dateMinute); - recordMap.put("dateSecond", dateSecond); - recordMap.put("duration", duration); + HashMap toMap() { + HashMap recordMap = new HashMap<>(); + recordMap.put("formattedNumber", formattedNumber); + recordMap.put("number", number); + recordMap.put("callType", callType); + recordMap.put("dateYear", dateYear); + recordMap.put("dateMonth", dateMonth); + recordMap.put("dateDay", dateDay); + recordMap.put("dateHour", dateHour); + recordMap.put("dateMinute", dateMinute); + recordMap.put("dateSecond", dateSecond); + recordMap.put("duration", duration); - return recordMap; - } + return recordMap; + } } diff --git a/packages/phone_log/android/src/main/java/com/jiajiabingcheng/phonelog/PhoneLogPlugin.java b/packages/phone_log/android/src/main/java/com/jiajiabingcheng/phonelog/PhoneLogPlugin.java index cea08a3..c93fc34 100644 --- a/packages/phone_log/android/src/main/java/com/jiajiabingcheng/phonelog/PhoneLogPlugin.java +++ b/packages/phone_log/android/src/main/java/com/jiajiabingcheng/phonelog/PhoneLogPlugin.java @@ -7,186 +7,190 @@ import android.os.Build; import android.provider.CallLog; import android.util.Log; - import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry.Registrar; - import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; -/** - * PhoneLogPlugin - */ +/** PhoneLogPlugin */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) -public class PhoneLogPlugin implements MethodCallHandler, - PluginRegistry.RequestPermissionsResultListener { - private final Registrar registrar; - private Result pendingResult; - - private PhoneLogPlugin(Registrar registrar) { - this.registrar = registrar; +public class PhoneLogPlugin + implements MethodCallHandler, PluginRegistry.RequestPermissionsResultListener { + private final Registrar registrar; + private Result pendingResult; + + private PhoneLogPlugin(Registrar registrar) { + this.registrar = registrar; + } + + public static void registerWith(Registrar registrar) { + final MethodChannel channel = + new MethodChannel(registrar.messenger(), "github.com/jiajiabingcheng/phone_log"); + PhoneLogPlugin phoneLogPlugin = new PhoneLogPlugin(registrar); + channel.setMethodCallHandler(phoneLogPlugin); + registrar.addRequestPermissionsResultListener(phoneLogPlugin); + } + + @Override + public void onMethodCall(MethodCall call, Result result) { + if (pendingResult != null) { + pendingResult.error("multiple_requests", "Cancelled by a second request.", null); + pendingResult = null; } - - public static void registerWith(Registrar registrar) { - final MethodChannel channel = - new MethodChannel(registrar.messenger(), "github.com/jiajiabingcheng/phone_log"); - PhoneLogPlugin phoneLogPlugin = new PhoneLogPlugin(registrar); - channel.setMethodCallHandler(phoneLogPlugin); - registrar.addRequestPermissionsResultListener(phoneLogPlugin); + pendingResult = result; + switch (call.method) { + case "checkPermission": + pendingResult.success(checkPermission()); + pendingResult = null; + break; + case "requestPermission": + requestPermission(); + break; + case "getPhoneLogs": + String startDate = call.argument("startDate"); + String duration = call.argument("duration"); + fetchCallRecords(startDate, duration); + break; + default: + result.notImplemented(); } - - @Override - public void onMethodCall(MethodCall call, Result result) { - if (pendingResult != null) { - pendingResult.error("multiple_requests", "Cancelled by a second request.", null); - pendingResult = null; - } - pendingResult = result; - switch (call.method) { - case "checkPermission": - pendingResult.success(checkPermission()); - pendingResult = null; - break; - case "requestPermission": - requestPermission(); - break; - case "getPhoneLogs": - String startDate = call.argument("startDate"); - String duration = call.argument("duration"); - fetchCallRecords(startDate, duration); - break; - default: - result.notImplemented(); - } - } - - private void requestPermission() { - Log.i("PhoneLogPlugin", "Requesting permission : " + Manifest.permission.READ_CALL_LOG); - String[] perm = {Manifest.permission.READ_CALL_LOG}; - registrar.activity().requestPermissions(perm, 0); - } - - private String checkPermission() { - Log.i("PhoneLogPlugin", "Checking permission : " + Manifest.permission.READ_CALL_LOG); - boolean isGranted = PackageManager.PERMISSION_GRANTED - == registrar.activity().checkSelfPermission(Manifest.permission.READ_CALL_LOG); - if (isGranted){ - return "granted"; - } else if (registrar.activity().shouldShowRequestPermissionRationale(Manifest.permission.READ_CALL_LOG)){ - return "denied"; - } return "deniedAndCannotRequest"; + } + + private void requestPermission() { + Log.i("PhoneLogPlugin", "Requesting permission : " + Manifest.permission.READ_CALL_LOG); + String[] perm = {Manifest.permission.READ_CALL_LOG}; + registrar.activity().requestPermissions(perm, 0); + } + + private String checkPermission() { + Log.i("PhoneLogPlugin", "Checking permission : " + Manifest.permission.READ_CALL_LOG); + boolean isGranted = + PackageManager.PERMISSION_GRANTED + == registrar.activity().checkSelfPermission(Manifest.permission.READ_CALL_LOG); + if (isGranted) { + return "granted"; + } else if (registrar + .activity() + .shouldShowRequestPermissionRationale(Manifest.permission.READ_CALL_LOG)) { + return "denied"; } - - @Override - public boolean onRequestPermissionsResult(int requestCode, - String[] strings, - int[] grantResults) { - boolean res = false; - if (requestCode == 0 && grantResults.length > 0) { - res = grantResults[0] == PackageManager.PERMISSION_GRANTED; - pendingResult.success(res); - pendingResult = null; - } - return res; + return "deniedAndCannotRequest"; + } + + @Override + public boolean onRequestPermissionsResult(int requestCode, String[] strings, int[] grantResults) { + boolean res = false; + if (requestCode == 0 && grantResults.length > 0) { + res = grantResults[0] == PackageManager.PERMISSION_GRANTED; + pendingResult.success(res); + pendingResult = null; } - - private static final String[] PROJECTION = - {CallLog.Calls.CACHED_FORMATTED_NUMBER, - CallLog.Calls.CACHED_MATCHED_NUMBER, - CallLog.Calls.TYPE, - CallLog.Calls.DATE, - CallLog.Calls.DURATION,}; - - @TargetApi(Build.VERSION_CODES.M) - private void fetchCallRecords(String startDate, String duration) { - if (registrar.activity().checkSelfPermission(Manifest.permission.READ_CALL_LOG) - == PackageManager.PERMISSION_GRANTED) { - String selectionCondition = null; - if (startDate != null) { - selectionCondition = CallLog.Calls.DATE + "> " + startDate; - } - if (duration != null) { - String durationSelection = CallLog.Calls.DURATION + "> " + duration; - if (selectionCondition != null) { - selectionCondition = selectionCondition + " AND " + durationSelection; - } else { - selectionCondition = durationSelection; - } - } - Cursor cursor = registrar.context().getContentResolver().query( - CallLog.Calls.CONTENT_URI, PROJECTION, - selectionCondition, - null, CallLog.Calls.DATE + " DESC"); - - try { - ArrayList> records = getCallRecordMaps(cursor); - pendingResult.success(records); - pendingResult = null; - } catch (Exception e) { - Log.e("PhoneLog", "Error on fetching call record" + e); - pendingResult.error("PhoneLog", e.getMessage(), null); - pendingResult = null; - } finally { - if (cursor != null) { - cursor.close(); - } - } - + return res; + } + + private static final String[] PROJECTION = { + CallLog.Calls.CACHED_FORMATTED_NUMBER, + CallLog.Calls.CACHED_MATCHED_NUMBER, + CallLog.Calls.TYPE, + CallLog.Calls.DATE, + CallLog.Calls.DURATION, + }; + + @TargetApi(Build.VERSION_CODES.M) + private void fetchCallRecords(String startDate, String duration) { + if (registrar.activity().checkSelfPermission(Manifest.permission.READ_CALL_LOG) + == PackageManager.PERMISSION_GRANTED) { + String selectionCondition = null; + if (startDate != null) { + selectionCondition = CallLog.Calls.DATE + "> " + startDate; + } + if (duration != null) { + String durationSelection = CallLog.Calls.DURATION + "> " + duration; + if (selectionCondition != null) { + selectionCondition = selectionCondition + " AND " + durationSelection; } else { - pendingResult.error("PhoneLog", "Permission is not granted", null); - pendingResult = null; + selectionCondition = durationSelection; } - } - - - /** - * Builds the list of call record maps from the cursor - * - * @param cursor - * @return the list of maps - */ - private ArrayList> getCallRecordMaps(Cursor cursor) { - ArrayList> records = new ArrayList<>(); - - while (cursor != null && cursor.moveToNext()) { - CallRecord record = new CallRecord(); - record.formattedNumber = cursor.getString(0); - record.number = cursor.getString(1); - record.callType = getCallType(cursor.getInt(2)); - - Date date = new Date(cursor.getLong(3)); - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - record.dateYear = cal.get(Calendar.YEAR); - record.dateMonth = cal.get(Calendar.MONTH); - record.dateDay = cal.get(Calendar.DAY_OF_MONTH); - record.dateHour = cal.get(Calendar.HOUR_OF_DAY); - record.dateMinute = cal.get(Calendar.MINUTE); - record.dateSecond = cal.get(Calendar.SECOND); - record.duration = cursor.getLong(4); - - records.add(record.toMap()); + } + Cursor cursor = + registrar + .context() + .getContentResolver() + .query( + CallLog.Calls.CONTENT_URI, + PROJECTION, + selectionCondition, + null, + CallLog.Calls.DATE + " DESC"); + + try { + ArrayList> records = getCallRecordMaps(cursor); + pendingResult.success(records); + pendingResult = null; + } catch (Exception e) { + Log.e("PhoneLog", "Error on fetching call record" + e); + pendingResult.error("PhoneLog", e.getMessage(), null); + pendingResult = null; + } finally { + if (cursor != null) { + cursor.close(); } - return records; - } + } - private String getCallType(int anInt) { - switch (anInt) { - case CallLog.Calls.INCOMING_TYPE: - return "INCOMING_TYPE"; - case CallLog.Calls.OUTGOING_TYPE: - return "OUTGOING_TYPE"; - case CallLog.Calls.MISSED_TYPE: - return "MISSED_TYPE"; - default: - break; - } - return null; + } else { + pendingResult.error("PhoneLog", "Permission is not granted", null); + pendingResult = null; + } + } + + /** + * Builds the list of call record maps from the cursor + * + * @param cursor + * @return the list of maps + */ + private ArrayList> getCallRecordMaps(Cursor cursor) { + ArrayList> records = new ArrayList<>(); + + while (cursor != null && cursor.moveToNext()) { + CallRecord record = new CallRecord(); + record.formattedNumber = cursor.getString(0); + record.number = cursor.getString(1); + record.callType = getCallType(cursor.getInt(2)); + + Date date = new Date(cursor.getLong(3)); + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + record.dateYear = cal.get(Calendar.YEAR); + record.dateMonth = cal.get(Calendar.MONTH); + record.dateDay = cal.get(Calendar.DAY_OF_MONTH); + record.dateHour = cal.get(Calendar.HOUR_OF_DAY); + record.dateMinute = cal.get(Calendar.MINUTE); + record.dateSecond = cal.get(Calendar.SECOND); + record.duration = cursor.getLong(4); + + records.add(record.toMap()); + } + return records; + } + + private String getCallType(int anInt) { + switch (anInt) { + case CallLog.Calls.INCOMING_TYPE: + return "INCOMING_TYPE"; + case CallLog.Calls.OUTGOING_TYPE: + return "OUTGOING_TYPE"; + case CallLog.Calls.MISSED_TYPE: + return "MISSED_TYPE"; + default: + break; } + return null; + } } diff --git a/packages/phone_log/example/android/app/src/main/java/com/example/phonelogexample/MainActivity.java b/packages/phone_log/example/android/app/src/main/java/com/example/phonelogexample/MainActivity.java index 1c73ade..d534655 100644 --- a/packages/phone_log/example/android/app/src/main/java/com/example/phonelogexample/MainActivity.java +++ b/packages/phone_log/example/android/app/src/main/java/com/example/phonelogexample/MainActivity.java @@ -1,7 +1,6 @@ package com.example.phonelogexample; import android.os.Bundle; - import io.flutter.app.FlutterActivity; import io.flutter.plugins.GeneratedPluginRegistrant; diff --git a/packages/phone_log/example/ios/Runner/AppDelegate.h b/packages/phone_log/example/ios/Runner/AppDelegate.h index cf210d2..36e21bb 100644 --- a/packages/phone_log/example/ios/Runner/AppDelegate.h +++ b/packages/phone_log/example/ios/Runner/AppDelegate.h @@ -1,5 +1,5 @@ -#import #import +#import @interface AppDelegate : FlutterAppDelegate diff --git a/packages/phone_log/example/ios/Runner/AppDelegate.m b/packages/phone_log/example/ios/Runner/AppDelegate.m index 112becd..59a72e9 100644 --- a/packages/phone_log/example/ios/Runner/AppDelegate.m +++ b/packages/phone_log/example/ios/Runner/AppDelegate.m @@ -3,7 +3,8 @@ @implementation AppDelegate -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. return [super application:application didFinishLaunchingWithOptions:launchOptions]; diff --git a/packages/phone_log/example/ios/Runner/main.m b/packages/phone_log/example/ios/Runner/main.m index 0ccc450..dff6597 100644 --- a/packages/phone_log/example/ios/Runner/main.m +++ b/packages/phone_log/example/ios/Runner/main.m @@ -1,8 +1,8 @@ -#import #import +#import #import "AppDelegate.h" -int main(int argc, char * argv[]) { +int main(int argc, char* argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } diff --git a/packages/phone_log/example/lib/main.dart b/packages/phone_log/example/lib/main.dart index 0ee8802..2310058 100644 --- a/packages/phone_log/example/lib/main.dart +++ b/packages/phone_log/example/lib/main.dart @@ -25,7 +25,6 @@ class _MyAppState extends State { }); } - void requestPermission() async { bool res = await phoneLog.requestPermission(); print("permission request result is: " + res.toString()); @@ -36,7 +35,6 @@ class _MyAppState extends State { print("permission is: " + res.toString()); } - @override Widget build(BuildContext context) { var children = [ @@ -107,4 +105,3 @@ class _MyAppState extends State { ); } } - diff --git a/packages/phone_log/ios/Classes/PhoneLogPlugin.m b/packages/phone_log/ios/Classes/PhoneLogPlugin.m index 16fd6df..90a1e2c 100644 --- a/packages/phone_log/ios/Classes/PhoneLogPlugin.m +++ b/packages/phone_log/ios/Classes/PhoneLogPlugin.m @@ -2,21 +2,21 @@ @implementation PhoneLogPlugin + (void)registerWithRegistrar:(NSObject*)registrar { - FlutterMethodChannel* channel = [FlutterMethodChannel - methodChannelWithName:@"github.com/jiajiabingcheng/phone_log" - binaryMessenger:[registrar messenger]]; + FlutterMethodChannel* channel = + [FlutterMethodChannel methodChannelWithName:@"github.com/jiajiabingcheng/phone_log" + binaryMessenger:[registrar messenger]]; PhoneLogPlugin* instance = [[PhoneLogPlugin alloc] init]; [registrar addMethodCallDelegate:instance channel:channel]; } - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { - if ([@"checkPermission" isEqualToString:call.method] || - [@"requestPermission" isEqualToString:call.method] || - [@"getPhoneLogs" isEqualToString:call.method]) { - result(nil); - } else { - result(FlutterMethodNotImplemented); - } + if ([@"checkPermission" isEqualToString:call.method] || + [@"requestPermission" isEqualToString:call.method] || + [@"getPhoneLogs" isEqualToString:call.method]) { + result(nil); + } else { + result(FlutterMethodNotImplemented); + } } @end diff --git a/packages/phone_log/lib/phone_log.dart b/packages/phone_log/lib/phone_log.dart index d0d0246..6e530e6 100644 --- a/packages/phone_log/lib/phone_log.dart +++ b/packages/phone_log/lib/phone_log.dart @@ -10,7 +10,7 @@ import 'package:flutter/services.dart'; /// request is denied previously and user has checked 'never ask again' check /// box. In this case calling [requestPermission] method, the request /// permission dialog would not pop up. -enum PermissionStatus {granted, denied, deniedAndCannotRequest} +enum PermissionStatus { granted, denied, deniedAndCannotRequest } /// Provide methods to access and fetch the phone log. class PhoneLog { @@ -23,7 +23,7 @@ class PhoneLog { factory PhoneLog() => _instance; @visibleForTesting - PhoneLog.private(MethodChannel platformChannel):_channel = platformChannel; + PhoneLog.private(MethodChannel platformChannel) : _channel = platformChannel; /// Check a [permission] and return a [Future] of the [PermissionStatus]. Future checkPermission() async { @@ -44,11 +44,11 @@ class PhoneLog { ///The unit of [duration] is second. Future> getPhoneLogs( {Int64 startDate, Int64 duration}) async { - var _startDate = startDate?.toString(); - var _duration = duration?.toString(); - Iterable records = await _channel.invokeMethod( + final _startDate = startDate?.toString(); + final _duration = duration?.toString(); + Iterable> records = await _channel.invokeMethod( 'getPhoneLogs', {"startDate": _startDate, "duration": _duration}); - return records?.map((m) => new CallRecord.fromMap(m)); + return records?.map((Map m) => new CallRecord.fromMap(m)); } } @@ -76,7 +76,7 @@ class CallRecord { String formattedNumber, number, callType; int dateYear, dateMonth, dateDay, dateHour, dateMinute, dateSecond, duration; - CallRecord.fromMap(Map m) { + CallRecord.fromMap(Map m) { formattedNumber = m['formattedNumber']; number = m['number']; callType = m['callType']; diff --git a/packages/phone_log/pubspec.yaml b/packages/phone_log/pubspec.yaml index 099c723..a2b65bc 100644 --- a/packages/phone_log/pubspec.yaml +++ b/packages/phone_log/pubspec.yaml @@ -5,7 +5,7 @@ author: Jiaming Cheng homepage: https://github.com/jiajiabingcheng/phone_log environment: - sdk: ">=1.19.0 <2.0.0" + sdk: ">=2.0.0 <3.0.0" dependencies: flutter: @@ -19,6 +19,6 @@ flutter: pluginClass: PhoneLogPlugin dev_dependencies: - mockito: ^2.0.2 + mockito: 3.0.0 flutter_test: sdk: flutter diff --git a/packages/phone_log/test/phone_log_test.dart b/packages/phone_log/test/phone_log_test.dart index 7564adf..16fa04a 100644 --- a/packages/phone_log/test/phone_log_test.dart +++ b/packages/phone_log/test/phone_log_test.dart @@ -23,14 +23,15 @@ void main() { mockChannelForDenied = new MockPlatformChannel(); mockChannelForDeniedCannotRequest = new MockPlatformChannel(); - when(mockChannel.invokeMethod(typed(any), any)) + when(mockChannel.invokeMethod(typed(any), any)) .thenAnswer((Invocation invocation) { invokedMethod = invocation.positionalArguments[0]; arguments = invocation.positionalArguments[1]; + return null; }); when(mockChannelForGetLogs.invokeMethod('getPhoneLogs', any)) - .thenAnswer((_) => new Future(() => [ + .thenAnswer((_) => new Future>>(() => [ { 'formattedNumber': '123 123 1234', 'number': '1231231234', @@ -46,13 +47,13 @@ void main() { ])); when(mockChannelForGranted.invokeMethod('checkPermission', any)) - .thenAnswer((_) => new Future(() => 'granted')); + .thenAnswer((_) => new Future(() => 'granted')); when(mockChannelForDenied.invokeMethod('checkPermission', any)) - .thenAnswer((_) => new Future(() => 'denied')); + .thenAnswer((_) => new Future(() => 'denied')); when(mockChannelForDeniedCannotRequest.invokeMethod('checkPermission', any)) - .thenAnswer((_) => new Future(() => 'deniedAndCannotRequest')); + .thenAnswer((_) => new Future(() => 'deniedAndCannotRequest')); }); group('Phone log plugin', () { @@ -96,8 +97,10 @@ void main() { expect(permissionDenied, PermissionStatus.denied); - var phoneLogCannotRequest = new PhoneLog.private(mockChannelForDeniedCannotRequest); - var permissionCannotRequest = await phoneLogCannotRequest.checkPermission(); + var phoneLogCannotRequest = + new PhoneLog.private(mockChannelForDeniedCannotRequest); + var permissionCannotRequest = + await phoneLogCannotRequest.checkPermission(); expect(permissionCannotRequest, PermissionStatus.deniedAndCannotRequest); });