Skip to content

Commit f31e513

Browse files
authored
Merge pull request #18 from ened/fix/17
Fixes #17
2 parents 797228b + 5d8c952 commit f31e513

File tree

16 files changed

+433
-147
lines changed

16 files changed

+433
-147
lines changed

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ buildscript {
88
}
99

1010
dependencies {
11-
classpath 'com.android.tools.build:gradle:3.5.0'
11+
classpath 'com.android.tools.build:gradle:3.6.1'
1212
}
1313
}
1414

Lines changed: 62 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,76 @@
11
package com.baseflow.googleapiavailability;
22

3-
import android.app.Activity;
43
import android.content.Context;
5-
6-
import androidx.annotation.IntDef;
7-
import androidx.annotation.Nullable;
8-
9-
import com.google.android.gms.common.ConnectionResult;
10-
import com.google.android.gms.common.GoogleApiAvailability;
11-
12-
import java.lang.annotation.Retention;
13-
import java.lang.annotation.RetentionPolicy;
14-
4+
import androidx.annotation.NonNull;
155
import io.flutter.embedding.engine.plugins.FlutterPlugin;
166
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
177
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
188
import io.flutter.plugin.common.BinaryMessenger;
19-
import io.flutter.plugin.common.MethodCall;
209
import io.flutter.plugin.common.MethodChannel;
21-
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
22-
import io.flutter.plugin.common.MethodChannel.Result;
2310
import io.flutter.plugin.common.PluginRegistry.Registrar;
11+
import io.flutter.plugin.common.PluginRegistry.ViewDestroyListener;
12+
import io.flutter.view.FlutterNativeView;
2413

2514
/**
2615
* GoogleApiAvailabilityPlugin
2716
*/
28-
public class GoogleApiAvailabilityPlugin implements MethodCallHandler, FlutterPlugin, ActivityAware {
29-
private static final int REQUEST_GOOGLE_PLAY_SERVICES = 1000;
30-
31-
//GOOGLE_PLAY_SERVICES_AVAILABILITY
32-
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SUCCESS = 0;
33-
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_MISSING = 1;
34-
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_UPDATING = 2;
35-
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_VERSION_UPDATE_REQUIRED = 3;
36-
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_DISABLED = 4;
37-
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_INVALID = 5;
38-
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_NOT_AVAILABLE_ON_PLATFORM = 6;
39-
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_UNKNOWN = 7;
40-
41-
@Retention(RetentionPolicy.SOURCE)
42-
@IntDef({
43-
GOOGLE_PLAY_SERVICES_AVAILABILITY_SUCCESS,
44-
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_MISSING,
45-
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_UPDATING,
46-
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_VERSION_UPDATE_REQUIRED,
47-
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_DISABLED,
48-
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_INVALID,
49-
GOOGLE_PLAY_SERVICES_AVAILABILITY_NOT_AVAILABLE_ON_PLATFORM,
50-
GOOGLE_PLAY_SERVICES_AVAILABILITY_UNKNOWN,
51-
})
52-
private @interface GooglePlayServicesAvailability {
53-
}
54-
55-
private Context applicationContext;
56-
private @Nullable Activity activity;
57-
private MethodChannel methodChannel;
58-
59-
60-
public static void registerWith(Registrar registrar) {
61-
final GoogleApiAvailabilityPlugin plugin = new GoogleApiAvailabilityPlugin();
62-
plugin.registerPlugin(
63-
registrar.context(),
64-
registrar.activity(),
65-
registrar.messenger());
66-
}
67-
68-
@Override
69-
public void onAttachedToEngine(FlutterPluginBinding binding) {
70-
registerPlugin(
71-
binding.getApplicationContext(),
72-
null,
73-
binding.getBinaryMessenger());
74-
}
75-
76-
@Override
77-
public void onDetachedFromEngine(FlutterPluginBinding binding) {
78-
applicationContext = null;
79-
methodChannel.setMethodCallHandler(null);
80-
methodChannel = null;
81-
}
82-
83-
@Override
84-
public void onAttachedToActivity(ActivityPluginBinding binding) {
85-
activity = binding.getActivity();
86-
}
87-
88-
@Override
89-
public void onDetachedFromActivityForConfigChanges() {
90-
activity = null;
91-
}
92-
93-
@Override
94-
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
95-
activity = binding.getActivity();
96-
}
97-
98-
@Override
99-
public void onDetachedFromActivity() {
100-
activity = null;
101-
}
102-
103-
private void registerPlugin(Context applicationContext, Activity activity, BinaryMessenger messenger) {
104-
this.applicationContext = applicationContext;
105-
this.activity = activity;
106-
methodChannel = new MethodChannel(messenger, "flutter.baseflow.com/google_api_availability/methods");
107-
methodChannel.setMethodCallHandler(this);
108-
}
109-
110-
@Override
111-
public void onMethodCall(MethodCall call, Result result) {
112-
if (call.method.equals("checkPlayServicesAvailability")) {
113-
final Boolean showDialog = call.argument("showDialog");
114-
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
115-
final int connectionResult = googleApiAvailability.isGooglePlayServicesAvailable(applicationContext);
116-
117-
if (activity != null && showDialog != null && showDialog) {
118-
googleApiAvailability.showErrorDialogFragment(activity, connectionResult, REQUEST_GOOGLE_PLAY_SERVICES);
119-
}
120-
121-
final int availability = toPlayServiceAvailability(connectionResult);
122-
result.success(availability);
123-
} else {
124-
result.notImplemented();
125-
}
126-
}
127-
128-
@GooglePlayServicesAvailability
129-
private int toPlayServiceAvailability(int connectionResult) {
130-
switch (connectionResult) {
131-
case ConnectionResult.SUCCESS:
132-
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SUCCESS;
133-
case ConnectionResult.SERVICE_MISSING:
134-
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_MISSING;
135-
case ConnectionResult.SERVICE_UPDATING:
136-
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_UPDATING;
137-
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
138-
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_VERSION_UPDATE_REQUIRED;
139-
case ConnectionResult.SERVICE_DISABLED:
140-
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_DISABLED;
141-
case ConnectionResult.SERVICE_INVALID:
142-
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_INVALID;
143-
default:
144-
return GOOGLE_PLAY_SERVICES_AVAILABILITY_UNKNOWN;
145-
}
146-
}
17+
public class GoogleApiAvailabilityPlugin implements FlutterPlugin, ActivityAware {
18+
19+
private MethodChannel channel;
20+
private MethodCallHandlerImpl methodCallHandler;
21+
22+
@Override
23+
public void onAttachedToActivity(ActivityPluginBinding binding) {
24+
methodCallHandler.setActivity(binding.getActivity());
25+
}
26+
27+
@Override
28+
public void onDetachedFromActivity() {
29+
methodCallHandler.setActivity(null);
30+
}
31+
32+
@Override
33+
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
34+
methodCallHandler.setActivity(binding.getActivity());
35+
}
36+
37+
@Override
38+
public void onDetachedFromActivityForConfigChanges() {
39+
methodCallHandler.setActivity(null);
40+
}
41+
42+
@Override
43+
public void onAttachedToEngine(FlutterPluginBinding binding) {
44+
registerPlugin(binding.getApplicationContext(), binding.getBinaryMessenger());
45+
}
46+
47+
@Override
48+
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
49+
unregisterPlugin();
50+
}
51+
52+
public static void registerWith(Registrar registrar) {
53+
final GoogleApiAvailabilityPlugin plugin = new GoogleApiAvailabilityPlugin();
54+
plugin.registerPlugin(registrar.context(), registrar.messenger());
55+
plugin.methodCallHandler.setActivity(registrar.activity());
56+
57+
registrar.addViewDestroyListener(new ViewDestroyListener() {
58+
@Override
59+
public boolean onViewDestroy(FlutterNativeView view) {
60+
plugin.unregisterPlugin();
61+
return false;
62+
}
63+
});
64+
}
65+
66+
private void registerPlugin(Context context, BinaryMessenger messenger) {
67+
methodCallHandler = new MethodCallHandlerImpl(context);
68+
channel = new MethodChannel(messenger, "flutter.baseflow.com/google_api_availability/methods");
69+
channel.setMethodCallHandler(methodCallHandler);
70+
}
71+
72+
private void unregisterPlugin() {
73+
channel.setMethodCallHandler(null);
74+
channel = null;
75+
}
14776
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.baseflow.googleapiavailability;
2+
3+
import android.app.Activity;
4+
import android.content.Context;
5+
import androidx.annotation.IntDef;
6+
import androidx.annotation.NonNull;
7+
import androidx.annotation.Nullable;
8+
import com.google.android.gms.common.ConnectionResult;
9+
import com.google.android.gms.common.GoogleApiAvailability;
10+
import io.flutter.plugin.common.MethodCall;
11+
import io.flutter.plugin.common.MethodChannel;
12+
import io.flutter.plugin.common.MethodChannel.Result;
13+
import java.lang.annotation.Retention;
14+
import java.lang.annotation.RetentionPolicy;
15+
16+
public class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
17+
18+
MethodCallHandlerImpl(Context applicationContext) {
19+
this.applicationContext = applicationContext;
20+
}
21+
22+
private final Context applicationContext;
23+
24+
@Nullable
25+
private Activity activity;
26+
27+
void setActivity(@Nullable Activity activity) {
28+
this.activity = activity;
29+
}
30+
31+
private static final int REQUEST_GOOGLE_PLAY_SERVICES = 1000;
32+
33+
//GOOGLE_PLAY_SERVICES_AVAILABILITY
34+
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SUCCESS = 0;
35+
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_MISSING = 1;
36+
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_UPDATING = 2;
37+
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_VERSION_UPDATE_REQUIRED = 3;
38+
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_DISABLED = 4;
39+
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_INVALID = 5;
40+
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_NOT_AVAILABLE_ON_PLATFORM = 6;
41+
private static final int GOOGLE_PLAY_SERVICES_AVAILABILITY_UNKNOWN = 7;
42+
43+
@Retention(RetentionPolicy.SOURCE)
44+
@IntDef({
45+
GOOGLE_PLAY_SERVICES_AVAILABILITY_SUCCESS,
46+
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_MISSING,
47+
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_UPDATING,
48+
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_VERSION_UPDATE_REQUIRED,
49+
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_DISABLED,
50+
GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_INVALID,
51+
GOOGLE_PLAY_SERVICES_AVAILABILITY_NOT_AVAILABLE_ON_PLATFORM,
52+
GOOGLE_PLAY_SERVICES_AVAILABILITY_UNKNOWN,
53+
})
54+
private @interface GooglePlayServicesAvailability {
55+
56+
}
57+
58+
@Override
59+
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
60+
if (call.method.equals("checkPlayServicesAvailability")) {
61+
final Boolean showDialog = call.argument("showDialog");
62+
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
63+
final int connectionResult = googleApiAvailability
64+
.isGooglePlayServicesAvailable(applicationContext);
65+
66+
if (activity != null) {
67+
if (showDialog != null && showDialog) {
68+
googleApiAvailability
69+
.showErrorDialogFragment(activity, connectionResult, REQUEST_GOOGLE_PLAY_SERVICES);
70+
}
71+
}
72+
73+
final int availability = toPlayServiceAvailability(connectionResult);
74+
result.success(availability);
75+
} else {
76+
result.notImplemented();
77+
}
78+
}
79+
80+
@GooglePlayServicesAvailability
81+
private int toPlayServiceAvailability(int connectionResult) {
82+
switch (connectionResult) {
83+
case ConnectionResult.SUCCESS:
84+
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SUCCESS;
85+
case ConnectionResult.SERVICE_MISSING:
86+
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_MISSING;
87+
case ConnectionResult.SERVICE_UPDATING:
88+
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_UPDATING;
89+
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
90+
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_VERSION_UPDATE_REQUIRED;
91+
case ConnectionResult.SERVICE_DISABLED:
92+
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_DISABLED;
93+
case ConnectionResult.SERVICE_INVALID:
94+
return GOOGLE_PLAY_SERVICES_AVAILABILITY_SERVICE_INVALID;
95+
default:
96+
return GOOGLE_PLAY_SERVICES_AVAILABILITY_UNKNOWN;
97+
}
98+
}
99+
}

example/android/app/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ android {
3838
targetSdkVersion 29
3939
versionCode flutterVersionCode.toInteger()
4040
versionName flutterVersionName
41+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
4142
}
4243

4344
buildTypes {
@@ -51,4 +52,10 @@ android {
5152

5253
flutter {
5354
source '../..'
55+
}
56+
57+
dependencies {
58+
androidTestImplementation 'androidx.test:runner:1.2.0'
59+
androidTestImplementation 'androidx.test:rules:1.2.0'
60+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
5461
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.baseflow.googleapiavailability;
2+
3+
import androidx.test.rule.ActivityTestRule;
4+
import com.baseflow.googleapiavailabilityexample.EmbeddingV1Activity;
5+
import dev.flutter.plugins.e2e.FlutterTestRunner;
6+
import org.junit.Rule;
7+
import org.junit.runner.RunWith;
8+
9+
@RunWith(FlutterTestRunner.class)
10+
public class EmbeddingV1ActivityTest {
11+
12+
@Rule
13+
public ActivityTestRule<EmbeddingV1Activity> rule =
14+
new ActivityTestRule<>(EmbeddingV1Activity.class);
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baseflow.googleapiavailability;
2+
3+
import androidx.test.rule.ActivityTestRule;
4+
import dev.flutter.plugins.e2e.FlutterTestRunner;
5+
import org.junit.Rule;
6+
import org.junit.runner.RunWith;
7+
8+
@RunWith(FlutterTestRunner.class)
9+
public class MainActivityTest {
10+
11+
@Rule
12+
public ActivityTestRule<io.flutter.embedding.android.FlutterActivity> rule = new ActivityTestRule<>(
13+
io.flutter.embedding.android.FlutterActivity.class);
14+
}

example/android/app/src/main/AndroidManifest.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
android:launchMode="singleTop"
1515
android:theme="@style/LaunchTheme"
1616
android:windowSoftInputMode="adjustResize">
17-
<meta-data android:name="flutterEmbedding" android:value="2"/>
17+
<meta-data android:name="flutterEmbedding" android:value="2"/>
1818
<!-- This keeps the window background of the activity showing
1919
until Flutter renders its first frame. It can be removed if
2020
there is no splash screen (such as the default splash screen
@@ -27,5 +27,14 @@
2727
<category android:name="android.intent.category.LAUNCHER" />
2828
</intent-filter>
2929
</activity>
30+
31+
<activity
32+
android:name=".EmbeddingV1Activity"
33+
android:theme="@style/LaunchTheme"
34+
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
35+
android:hardwareAccelerated="true"
36+
android:windowSoftInputMode="adjustResize" />
37+
38+
<meta-data android:name="flutterEmbedding" android:value="2"/>
3039
</application>
3140
</manifest>

0 commit comments

Comments
 (0)