Skip to content

Commit 9ac9195

Browse files
committed
Added extra functionality
1 parent 3d5c8c8 commit 9ac9195

File tree

8 files changed

+422
-53
lines changed

8 files changed

+422
-53
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## 4.0.0
2+
3+
* Changed the structure of the native code;
4+
* Updated the example app;
5+
* Added `makeGooglePlayServicesAvailable` ;
6+
* Added `getErrorString`;
7+
* Added `isUserResolvable`;
8+
* Added `showErrorNotification`;
9+
* Added extra tests for the newly added methods.
10+
111
## 3.0.2
212

313
* Updated `pubspec.yaml` to newer versions of `SDK` and `flutter` and adding `flutter_lints` as a dependency;
Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package com.baseflow.googleapiavailability;
22

33
import android.app.Activity;
4+
import android.app.Dialog;
5+
import android.app.PendingIntent;
46
import android.content.Context;
57
import android.util.Log;
68

9+
import com.google.android.gms.common.ConnectionResult;
710
import com.google.android.gms.common.GoogleApiAvailability;
811

12+
import java.util.List;
13+
914
public class GoogleApiAvailabilityManager {
1015

1116
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
@@ -16,19 +21,34 @@ interface SuccessCallback {
1621
}
1722

1823
@FunctionalInterface
19-
interface MakeGooglePlayServicesAvailable {
24+
interface MakeGooglePlayServicesAvailableCallback {
2025
void onSuccess(boolean makeGooglePlayServicesAvailable);
2126
}
2227

28+
@FunctionalInterface
29+
interface getErrorStringCallback {
30+
void onSuccess(String errorString);
31+
}
32+
33+
@FunctionalInterface
34+
interface isUserResolvableCallback {
35+
void onSuccess(boolean isUserResolvable);
36+
}
37+
38+
@FunctionalInterface
39+
interface showErrorNotificationCallback {
40+
void onSuccess(boolean showErrorNotificationCallback);
41+
}
42+
2343
@FunctionalInterface
2444
interface ErrorCallback {
2545
void onError(String errorCode, String errorDescription);
2646
}
2747

28-
void checkPlayServicesAvailability(Boolean showDialog, Context applicationContext, SuccessCallback successCallback, ErrorCallback errorCallback) {
29-
if (applicationContext == null) {
30-
Log.d(GoogleApiAvailabilityConstants.LOG_TAG, "Context cannot be null.");
31-
errorCallback.onError("GoogleApiAvailability.GoogleApiAvailabilityManager", "Android context cannot be null.");
48+
void checkPlayServicesAvailability(Boolean showDialog, Activity activity, Context applicationContext, SuccessCallback successCallback, ErrorCallback errorCallback) {
49+
if (applicationContext == null || activity == null) {
50+
Log.d(GoogleApiAvailabilityConstants.LOG_TAG, "Context and/or activity cannot be null.");
51+
errorCallback.onError("GoogleApiAvailability.GoogleApiAvailabilityManager", "Android context and/or activity cannot be null.");
3252
return;
3353
}
3454

@@ -37,13 +57,13 @@ void checkPlayServicesAvailability(Boolean showDialog, Context applicationContex
3757

3858
if (showDialog != null && showDialog) {
3959
googleApiAvailability
40-
.showErrorDialogFragment((Activity) applicationContext, connectionResult, GoogleApiAvailabilityConstants.REQUEST_GOOGLE_PLAY_SERVICES);
60+
.showErrorDialogFragment(activity, connectionResult, GoogleApiAvailabilityConstants.REQUEST_GOOGLE_PLAY_SERVICES);
4161
}
4262

4363
successCallback.onSuccess(GoogleApiAvailabilityConstants.toPlayServiceAvailability(connectionResult));
4464
}
4565

46-
void makeGooglePlayServicesAvailable(Activity activity, MakeGooglePlayServicesAvailable successCallback, ErrorCallback errorCallback){
66+
void makeGooglePlayServicesAvailable(Activity activity, MakeGooglePlayServicesAvailableCallback successCallback, ErrorCallback errorCallback){
4767
if (activity == null){
4868
Log.d(GoogleApiAvailabilityConstants.LOG_TAG, "Activity cannot be null.");
4969
errorCallback.onError("GoogleApiAvailability.makeGooglePlayServicesAvailable", "Android Activity cannot be null.");
@@ -53,4 +73,52 @@ void makeGooglePlayServicesAvailable(Activity activity, MakeGooglePlayServicesAv
5373
final boolean status = googleApiAvailability.makeGooglePlayServicesAvailable(activity).isSuccessful();
5474
successCallback.onSuccess(status);
5575
}
76+
77+
void getErrorString(Context applicationContext, getErrorStringCallback successCallback, ErrorCallback errorCallback){
78+
if (applicationContext == null){
79+
Log.d(GoogleApiAvailabilityConstants.LOG_TAG, "Context cannot be null.");
80+
errorCallback.onError("GoogleApiAvailability.getErrorString", "Android context cannot be null.");
81+
return;
82+
}
83+
84+
final String errorString = googleApiAvailability.getErrorString(googleApiAvailability.isGooglePlayServicesAvailable(applicationContext));
85+
86+
successCallback.onSuccess(errorString);
87+
}
88+
89+
void isUserResolvable(Context applicationContext, isUserResolvableCallback successCallback, ErrorCallback errorCallback){
90+
if (applicationContext == null){
91+
Log.d(GoogleApiAvailabilityConstants.LOG_TAG, "Context cannot be null.");
92+
errorCallback.onError("GoogleApiAvailability.isUserResolvable", "Android context cannot be null.");
93+
return;
94+
}
95+
96+
final int connectionResult = googleApiAvailability
97+
.isGooglePlayServicesAvailable(applicationContext);
98+
99+
successCallback.onSuccess(googleApiAvailability.isUserResolvableError(connectionResult));
100+
}
101+
102+
void showErrorNotification(Context applicationContext, showErrorNotificationCallback successCallback, ErrorCallback errorCallback){
103+
if (applicationContext == null){
104+
Log.d(GoogleApiAvailabilityConstants.LOG_TAG, "Context cannot be null.");
105+
errorCallback.onError("GoogleApiAvailability.showErrorNotification", "Android context cannot be null.");
106+
return;
107+
}
108+
109+
final int connectionResult = googleApiAvailability
110+
.isGooglePlayServicesAvailable(applicationContext);
111+
112+
googleApiAvailability.showErrorNotification(applicationContext, connectionResult);
113+
114+
if (connectionResult == GoogleApiAvailabilityConstants.GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_DISABLED ||
115+
connectionResult == GoogleApiAvailabilityConstants.GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_INVALID ||
116+
connectionResult == GoogleApiAvailabilityConstants.GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_MISSING ||
117+
connectionResult == GoogleApiAvailabilityConstants.GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_UPDATING ||
118+
connectionResult == GoogleApiAvailabilityConstants.GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_VERSION_UPDATE_REQUIRED){
119+
successCallback.onSuccess(true);
120+
}
121+
122+
successCallback.onSuccess(false);
123+
}
56124
}

android/src/main/java/com/baseflow/googleapiavailability/MethodCallHandlerImpl.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
4242
switch (call.method) {
4343
case "checkPlayServicesAvailability": {
4444
final Boolean showDialog = call.argument("showDialog");
45-
googleApiAvailabilityManager.checkPlayServicesAvailability(showDialog, applicationContext, result::success,
45+
googleApiAvailabilityManager.checkPlayServicesAvailability(showDialog, activity, applicationContext, result::success,
4646
(String errorCode, String errorDescription) -> result.error(
4747
errorCode,
4848
errorDescription,
@@ -57,6 +57,27 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
5757
null));
5858
break;
5959
}
60+
case "getErrorString": {
61+
googleApiAvailabilityManager.getErrorString(applicationContext, result::success,(String errorCode, String errorDescription) -> result.error(
62+
errorCode,
63+
errorDescription,
64+
null));
65+
break;
66+
}
67+
case "isUserResolvable": {
68+
googleApiAvailabilityManager.isUserResolvable(applicationContext, result::success,(String errorCode, String errorDescription) -> result.error(
69+
errorCode,
70+
errorDescription,
71+
null));
72+
break;
73+
}
74+
case "showErrorNotification": {
75+
googleApiAvailabilityManager.showErrorNotification(applicationContext, result::success,(String errorCode, String errorDescription) -> result.error(
76+
errorCode,
77+
errorDescription,
78+
null));
79+
break;
80+
}
6081
default:
6182
result.notImplemented();
6283
break;

coverage/lcov.info

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
SF:lib\src\google_api_availability.dart
2+
DA:11,1
3+
DA:16,1
4+
DA:28,1
5+
DA:30,2
6+
DA:34,2
7+
DA:36,1
8+
DA:42,1
9+
DA:50,1
10+
DA:51,2
11+
DA:56,2
12+
DA:63,0
13+
DA:64,0
14+
DA:69,0
15+
DA:77,0
16+
DA:78,0
17+
DA:83,0
18+
DA:95,0
19+
DA:97,0
20+
LF:18
21+
LH:10
22+
end_of_record
23+
SF:lib\src\models\google_play_services_availability.dart
24+
DA:5,1
25+
DA:8,0
26+
DA:13,0
27+
DA:76,0
28+
DA:77,0
29+
LF:5
30+
LH:1
31+
end_of_record

example/lib/main.dart

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ class _MyAppState extends State<MyApp> {
1919
GooglePlayServicesAvailability _playStoreAvailability =
2020
GooglePlayServicesAvailability.unknown;
2121
bool _madeGooglePlayServiceAvailable = false;
22+
String _errorString = "unknown";
23+
bool _isUserResolvable = false;
24+
bool _errorNotificationShown = false;
2225

2326
// Platform messages are asynchronous, so we initialize in an async method.
2427
Future<void> checkPlayServices([bool showDialog = false]) async {
@@ -53,9 +56,6 @@ class _MyAppState extends State<MyApp> {
5356
madeGooglePlayServiceAvailable = false;
5457
}
5558

56-
// If the widget was removed from the tree while the asynchronous platform
57-
// message was in flight, we want to discard the reply rather than calling
58-
// setState to update our non-existent appearance.
5959
if (!mounted) {
6060
return;
6161
}
@@ -65,6 +65,62 @@ class _MyAppState extends State<MyApp> {
6565
});
6666
}
6767

68+
Future<void> getErrorString() async {
69+
String errorString;
70+
71+
try {
72+
errorString = await GoogleApiAvailability.instance.getErrorString();
73+
} on PlatformException {
74+
errorString = "Not available on non Android devices";
75+
}
76+
77+
if (!mounted) {
78+
return;
79+
}
80+
81+
setState(() {
82+
_errorString = errorString;
83+
});
84+
}
85+
86+
Future<void> isUserResolvable() async {
87+
bool isUserResolvable;
88+
89+
try {
90+
isUserResolvable =
91+
await GoogleApiAvailability.instance.isUserResolvable();
92+
} on PlatformException {
93+
isUserResolvable = false;
94+
}
95+
96+
if (!mounted) {
97+
return;
98+
}
99+
100+
setState(() {
101+
_isUserResolvable = isUserResolvable;
102+
});
103+
}
104+
105+
Future<void> showErrorNotification() async {
106+
bool errorNotificationShown;
107+
108+
try {
109+
errorNotificationShown =
110+
await GoogleApiAvailability.instance.showErrorNotification();
111+
} on PlatformException {
112+
errorNotificationShown = false;
113+
}
114+
115+
if (!mounted) {
116+
return;
117+
}
118+
119+
setState(() {
120+
_errorNotificationShown = errorNotificationShown;
121+
});
122+
}
123+
68124
@override
69125
Widget build(BuildContext context) {
70126
return MaterialApp(
@@ -79,6 +135,15 @@ class _MyAppState extends State<MyApp> {
79135
child: const Text('Get PlayServices availability'),
80136
color: Colors.red,
81137
),
138+
Center(
139+
child: Text(
140+
'Google Play Store status: ${_playStoreAvailability.toString().split('.').last}\n')),
141+
MaterialButton(
142+
onPressed: () => checkPlayServices(true),
143+
child:
144+
const Text('Get PlayServices availability with fix dialog'),
145+
color: Colors.redAccent,
146+
),
82147
Center(
83148
child: Text(
84149
'Google Play Store status: ${_playStoreAvailability.toString().split('.').last}\n')),
@@ -89,13 +154,29 @@ class _MyAppState extends State<MyApp> {
89154
),
90155
Center(
91156
child: Text(
92-
'Make available: $_madeGooglePlayServiceAvailable\n')),
157+
'Made available: $_madeGooglePlayServiceAvailable\n')),
93158
MaterialButton(
94-
onPressed: () => checkPlayServices(true),
95-
child:
96-
const Text('Get PlayServices availability with fix dialog'),
97-
color: Colors.redAccent,
159+
onPressed: () => getErrorString(),
160+
child: const Text('Get string of the error code'),
161+
color: Colors.red,
162+
),
163+
Center(child: Text('Error string: $_errorString\n')),
164+
MaterialButton(
165+
onPressed: () => isUserResolvable(),
166+
child: const Text('Error resolvable by user'),
167+
color: Colors.red,
168+
),
169+
Center(
170+
child:
171+
Text('Error resolvable by user: $_isUserResolvable\n')),
172+
MaterialButton(
173+
onPressed: () => showErrorNotification(),
174+
child: const Text('Show error notification'),
175+
color: Colors.red,
98176
),
177+
Center(
178+
child: Text(
179+
'Error notification shown: $_errorNotificationShown\n')),
99180
],
100181
)),
101182
);

0 commit comments

Comments
 (0)