Update enableLocationService method (#19)

* enableLocationService return type changed to Future<bool>

* callback added to enableLocationService

* typos fixes #15

* fix #15 added to changelog and bug fixes
This commit is contained in:
Gourav Saini 2020-08-15 18:02:14 +05:30 committed by GitHub
parent 81519d7571
commit e7edb9865b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 295 additions and 115 deletions

View File

@ -1,3 +1,9 @@
## 2.0.0-dev
* enableLocationService return type changed to Future<bool>
* Updated Example accordingly
* Readme Fixes
* Typos Fixed
## 1.1.1+1
* Corrected supported platforms in pubpsec
@ -5,7 +11,7 @@
* Updated Android Nearby version from 16.0.0 to 17.0.0
* Updated Example
* **Location/GPS service must be turned on** or devices may disconnect
more often, some devices may disconnect immediately. 2 convinience methods are added
more often, some devices may disconnect immediately. 2 convenience methods are added
`enableLocationServices` and `checkLocationEnabled`
## 1.0.3
@ -24,7 +30,7 @@ more often, some devices may disconnect immediately. 2 convinience methods are a
## 1.0.1
* Changed convinience methods for asking permissions(location+storage)
* Changed convenience methods for asking permissions(location+storage)
* Updated example
## 1.0.0
@ -43,7 +49,7 @@ more often, some devices may disconnect immediately. 2 convinience methods are a
## 0.1.0
* Added pub maintanence suggestions
* Added pub maintenance suggestions
## 0.0.2

View File

@ -44,7 +44,7 @@ Add these to AndroidManifest.xml
```
Since ACCESS_FINE_LOCATION and READ_EXTERNAL_STORAGE is considered to be dangerous system permissions, in addition to adding them to your manifest, you must request these permissions at runtime.
#### As a **convinience** this library provides methods to check and request location and external read/write permissions
#### As a **convenience** this library provides methods to check and request location and external read/write permissions
```dart
// returns true/false asynchronously
bool a = await Nearby().checkLocationPermissions()
@ -68,12 +68,13 @@ The work flow is similar to the [Android Nearby Connections library](https://dev
**Location/GPS service must be turned on** or devices may disconnect
more often, some devices may disconnect immediately.
For convinience this library provides methods to check and enable location
For convenience this library provides methods to check and enable location
```dart
bool b = await Nearby().checkLocationEnabled();
// opens settings where user can enable it
Nearby().enableLocationServices();
// opens dialogue to enable location service
// returns true/false if the location service is turned on/off resp.
bool b = await Nearby().enableLocationServices();
```
### Advertise for connection
```dart

View File

@ -35,3 +35,7 @@ android {
api 'com.google.android.gms:play-services-nearby:17.0.0'
}
}
dependencies {
implementation 'com.google.android.gms:play-services-location:17.0.0'
}

View File

@ -1,3 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pkmnapps.nearby_connections">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>

View File

@ -0,0 +1,110 @@
package com.pkmnapps.nearby_connections;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;
class LocationEnabler implements PluginRegistry.ActivityResultListener {
@Nullable
private Activity activity;
private static final int LOCATION_ENABLE_REQUEST = 777;
private LocationSettingsRequest mLocationSettingsRequest;
private Result pendingResult;
private LocationEnabler(@Nullable Activity activity) {
this.activity = activity;
}
LocationEnabler(PluginRegistry.Registrar registrar) {
this(registrar.activity());
}
LocationEnabler() {
this.activity = null;
}
void setActivity(@Nullable Activity activity) {
this.activity = activity;
initiateLocationServiceRequest();
}
@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (pendingResult == null) {
return false;
}
if (requestCode == LOCATION_ENABLE_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
pendingResult.success(true);
} else {
pendingResult.success(false);
}
pendingResult = null;
return true;
}
return false;
}
private void initiateLocationServiceRequest() {
LocationRequest mLocationRequest = LocationRequest.create();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest
.Builder()
.addLocationRequest(mLocationRequest)
.setAlwaysShow(true);
mLocationSettingsRequest = builder.build();
}
void requestLocationEnable(final Result result) {
this.pendingResult = result;
Task<LocationSettingsResponse> task = LocationServices.getSettingsClient(activity)
.checkLocationSettings(mLocationSettingsRequest);
task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
@Override
public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
try {
task.getResult(ApiException.class);
result.success(true);
} catch (ApiException ex) {
switch (ex.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
result.success(true);
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
ResolvableApiException resolvableApiException =
(ResolvableApiException) ex;
resolvableApiException
.startResolutionForResult(activity, LOCATION_ENABLE_REQUEST);
} catch (IntentSender.SendIntentException e) {
result.error("LOCATION_SERVICE_ERROR", e.getMessage(), null);
}
break;
default:
result.success(false);
}
}
}
});
}
}

View File

@ -2,10 +2,9 @@ package com.pkmnapps.nearby_connections;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.location.LocationManager;
import android.content.pm.PackageManager;
import android.provider.Settings;
import android.location.LocationManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
@ -32,31 +31,41 @@ import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
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 android.util.Log;
/**
* NearbyConnectionsPlugin
*/
public class NearbyConnectionsPlugin implements MethodCallHandler {
public class NearbyConnectionsPlugin implements MethodCallHandler, FlutterPlugin, ActivityAware {
private Activity activity;
private static final String SERVICE_ID = "com.pkmnapps.nearby_connections";
private static MethodChannel channel;
private static LocationEnabler locationEnabler;
private static ActivityPluginBinding activityBinding;
private static PluginRegistry.Registrar pluginRegistrar;
private NearbyConnectionsPlugin(Activity activity) {
this.activity = activity;
}
/**
* Plugin registration.
*/
public static void registerWith(Registrar registrar) {
pluginRegistrar = registrar;
locationEnabler = new LocationEnabler(registrar);
locationEnabler.setActivity(registrar.activity());
initiate();
channel = new MethodChannel(registrar.messenger(), "nearby_connections");
channel.setMethodCallHandler(new NearbyConnectionsPlugin(registrar.activity()));
}
@ -96,7 +105,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
result.success(gps_enabled || network_enabled);
break;
case "enableLocationServices":
activity.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
locationEnabler.requestLocationEnable(result);
break;
case "checkExternalStoragePermission":
if (ContextCompat.checkSelfPermission(activity,
@ -468,4 +477,58 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
return Strategy.P2P_CLUSTER;
}
}
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
locationEnabler = new LocationEnabler();
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
locationEnabler = null;
}
private static void attachToActivity(ActivityPluginBinding binding) {
activityBinding = binding;
try {
locationEnabler.setActivity(binding.getActivity());
initiate();
} catch (Exception e) {
e.printStackTrace();
}
}
private void detachActivity() {
activityBinding.removeActivityResultListener(locationEnabler);
activityBinding = null;
}
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
attachToActivity(binding);
}
@Override
public void onDetachedFromActivity() {
this.detachActivity();
}
@Override
public void onDetachedFromActivityForConfigChanges() {
this.detachActivity();
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
attachToActivity(binding);
}
private static void initiate() {
if (pluginRegistrar != null) {
pluginRegistrar.addActivityResultListener(locationEnabler);
} else {
activityBinding.addActivityResultListener(locationEnabler);
}
}
}

View File

@ -0,0 +1 @@
<resources></resources>

View File

@ -112,8 +112,14 @@ class _MyBodyState extends State<Body> {
),
RaisedButton(
child: Text("enableLocationServices"),
onPressed: () {
Nearby().enableLocationServices();
onPressed: () async {
if (await Nearby().enableLocationServices()) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text("Location Service Enabled :)")));
} else {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text("Enabling Location Service Failed :(")));
}
},
),
],

View File

@ -7,42 +7,42 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
version: "2.0.13"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.2"
version: "1.6.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
version: "2.4.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
version: "2.0.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
version: "1.1.3"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
version: "1.14.12"
convert:
dependency: transitive
description:
@ -56,7 +56,7 @@ packages:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.1.4"
cupertino_icons:
dependency: "direct main"
description:
@ -80,7 +80,7 @@ packages:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
version: "2.1.12"
image_picker:
dependency: "direct main"
description:
@ -108,7 +108,7 @@ packages:
path: ".."
relative: true
source: path
version: "1.1.1+1"
version: "2.0.0-dev"
path:
dependency: transitive
description:
@ -116,13 +116,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0+1"
petitparser:
dependency: transitive
description:
@ -136,7 +129,7 @@ packages:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "2.1.3"
sky_engine:
dependency: transitive
description: flutter
@ -148,7 +141,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.5"
version: "1.7.0"
stack_trace:
dependency: transitive
description:
@ -183,7 +176,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.11"
version: "0.2.15"
typed_data:
dependency: transitive
description:
@ -204,7 +197,7 @@ packages:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.5.0"
version: "3.6.1"
sdks:
dart: ">=2.4.0 <3.0.0"
dart: ">=2.6.0 <3.0.0"
flutter: ">=1.5.0 <2.0.0"

View File

@ -41,7 +41,7 @@ class PayloadTransferUpdate {
/// ConnectionInfo class
///
/// Its a parameter in [OnConnctionInitiated]
/// Its a parameter in [OnConnectionInitiated]
///
/// [endPointName] is userNickName of requester
///

View File

@ -17,7 +17,7 @@ enum PayloadType { NONE, BYTES, FILE, STREAM }
//
// Advertising lifecycle callbacks
//
typedef void OnConnctionInitiated(
typedef void OnConnectionInitiated(
String endpointId, ConnectionInfo connectionInfo);
typedef void OnConnectionResult(String endpointId, Status status);
typedef void OnDisconnected(String endpointId);

View File

@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:nearby_connections/src/defs.dart';
@ -15,6 +14,7 @@ import 'package:nearby_connections/src/classes.dart';
class Nearby {
//Singleton pattern for maintaining only 1 instance of this class
static Nearby _instance;
factory Nearby() {
if (_instance == null) {
_instance = Nearby._();
@ -130,7 +130,7 @@ class Nearby {
}
//for advertisers
OnConnctionInitiated _advertConnectionInitiated, _discoverConnectionInitiated;
OnConnectionInitiated _advertConnectionInitiated, _discoverConnectionInitiated;
OnConnectionResult _advertConnectionResult, _discoverConnectionResult;
OnDisconnected _advertDisconnected, _discoverDisconnected;
@ -145,27 +145,27 @@ class Nearby {
static const MethodChannel _channel =
const MethodChannel('nearby_connections');
/// Convinience method
/// convenience method
///
/// retruns true/false based on location permissions.
/// returns true/false based on location permissions.
/// Discovery cannot be started with insufficient permission
Future<bool> checkLocationPermission() async => await _channel.invokeMethod(
'checkLocationPermission',
);
/// Convinience method
/// convenience method
///
/// Asks location permission
void askLocationPermission() =>
_channel.invokeMethod('askLocationPermission');
/// Convinience method
/// convenience method
///
/// retruns true/false based on external storage permissions.
/// returns true/false based on external storage permissions.
Future<bool> checkExternalStoragePermission() async =>
await _channel.invokeMethod('checkExternalStoragePermission');
/// Convinience method
/// convenience method
///
/// Checks if Location/GPS is enabled
///
@ -174,19 +174,19 @@ class Nearby {
Future<bool> checkLocationEnabled() async =>
await _channel.invokeMethod('checkLocationEnabled');
/// Convinience method
/// convenience method
///
/// directs user to Location Settings, so they can turn on their Location/GPS
void enableLocationServices() =>
_channel.invokeMethod('enableLocationServices');
Future<bool> enableLocationServices() async =>
await _channel.invokeMethod('enableLocationServices');
/// Convinience method
/// convenience method
///
/// Asks external storage permission, required for file
void askExternalStoragePermission() =>
_channel.invokeMethod('askExternalStoragePermission');
/// Convinience method
/// convenience method
///
/// Use this instead of calling both [askLocationPermission()] and [askExternalStoragePermission()]
void askLocationAndExternalStoragePermission() =>
@ -199,7 +199,7 @@ class Nearby {
Future<bool> startAdvertising(
String userNickName,
Strategy strategy, {
@required OnConnctionInitiated onConnectionInitiated,
@required OnConnectionInitiated onConnectionInitiated,
@required OnConnectionResult onConnectionResult,
@required OnDisconnected onDisconnected,
String serviceId = "com.pkmnapps.nearby_connections",
@ -286,12 +286,12 @@ class Nearby {
/// Call this method when Discoverer calls the
/// [OnEndpointFound] method
///
/// This will call the [OnConnctionInitiated] method on
/// This will call the [OnConnectionInitiated] method on
/// both the endPoint and this
Future<bool> requestConnection(
String userNickName,
String endpointId, {
@required OnConnctionInitiated onConnectionInitiated,
@required OnConnectionInitiated onConnectionInitiated,
@required OnConnectionResult onConnectionResult,
@required OnDisconnected onDisconnected,
}) async {
@ -314,7 +314,7 @@ class Nearby {
/// Needs be called by both discoverer and advertiser
/// to connect
///
/// Call this in [OnConnctionInitiated]
/// Call this in [OnConnectionInitiated]
/// to accept an incoming connection
///
/// [OnConnectionResult] is called on both
@ -341,7 +341,7 @@ class Nearby {
///
/// To be called by both discoverer and advertiser
///
/// Call this in [OnConnctionInitiated]
/// Call this in [OnConnectionInitiated]
/// to reject an incoming connection
///
/// [OnConnectionResult] is called on both

View File

@ -7,42 +7,42 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
version: "2.0.13"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.2"
version: "1.6.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
version: "2.4.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
version: "2.0.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
version: "1.1.3"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
version: "1.14.12"
convert:
dependency: transitive
description:
@ -56,7 +56,7 @@ packages:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.1.4"
flutter:
dependency: "direct main"
description: flutter
@ -73,7 +73,7 @@ packages:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
version: "2.1.12"
matcher:
dependency: transitive
description:
@ -95,13 +95,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0+1"
petitparser:
dependency: transitive
description:
@ -115,7 +108,7 @@ packages:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "2.1.3"
sky_engine:
dependency: transitive
description: flutter
@ -127,7 +120,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.5"
version: "1.7.0"
stack_trace:
dependency: transitive
description:
@ -162,7 +155,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.11"
version: "0.2.15"
typed_data:
dependency: transitive
description:
@ -183,6 +176,6 @@ packages:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.5.0"
version: "3.6.1"
sdks:
dart: ">=2.4.0 <3.0.0"
dart: ">=2.6.0 <3.0.0"

View File

@ -1,6 +1,6 @@
name: nearby_connections
description: Plugin for the android NearbyConnections API. Bytes and Files Supported.
version: 1.1.1+1
version: 2.0.0-dev
homepage: https://github.com/mannprerak2/nearby_connections
environment: