Merge branch 'development' into Haroon

# Conflicts:
#	lib/uitl/translations_delegate_base.dart
merge-requests/335/head
Haroon Amjad 4 years ago
commit e13a13189c

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

@ -0,0 +1,12 @@
## 5.0.0+301
* Added the getNavigationContextState function.
* Added the enableLogger and disableLogger methods.
## 4.0.4+1/4.0.4+300
* Fix minor issues.
## 4.0.4
* Initial release.

@ -0,0 +1,53 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

File diff suppressed because it is too large Load Diff

@ -0,0 +1,45 @@
group 'com.huawei.hms.flutter.location'
version '1.0'
buildscript {
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.0'
}
}
rootProject.allprojects {
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
disable 'InvalidPackage'
}
}
dependencies {
implementation 'com.huawei.hms:location:5.0.0.301'
}

@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

@ -0,0 +1,183 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

@ -0,0 +1,103 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

@ -0,0 +1 @@
rootProject.name = 'huawei_location'

@ -0,0 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.huawei.hms.flutter.location">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

@ -0,0 +1,201 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location;
import android.app.Activity;
import android.content.Context;
import androidx.annotation.NonNull;
import com.huawei.hms.flutter.location.constants.Channel;
import com.huawei.hms.flutter.location.handlers.ActivityConversionStreamHandler;
import com.huawei.hms.flutter.location.handlers.ActivityIdentificationMethodHandler;
import com.huawei.hms.flutter.location.handlers.ActivityIdentificationStreamHandler;
import com.huawei.hms.flutter.location.handlers.FusedLocationMethodHandler;
import com.huawei.hms.flutter.location.handlers.FusedLocationStreamHandler;
import com.huawei.hms.flutter.location.handlers.GeofenceMethodHandler;
import com.huawei.hms.flutter.location.handlers.GeofenceStreamHandler;
import com.huawei.hms.flutter.location.handlers.HMSLoggerMethodHandler;
import com.huawei.hms.flutter.location.handlers.PermissionHandler;
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.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry.Registrar;
public class LocationPlugin implements FlutterPlugin, ActivityAware {
private MethodChannel permissionMethodChannel;
private MethodChannel fusedLocationMethodChannel;
private MethodChannel geofenceMethodChannel;
private MethodChannel activityIdentificationMethodChannel;
private MethodChannel locationEnhanceMethodChannel;
private MethodChannel hmsLoggerMethodChannel;
private EventChannel mFusedLocationEventChannel;
private EventChannel mGeofenceEventChannel;
private EventChannel mActivityIdentificationEventChannel;
private EventChannel mActivityConversionEventChannel;
private PermissionHandler permissionHandler;
private EventChannel.StreamHandler mFusedLocationStreamHandler;
private EventChannel.StreamHandler mGeofenceStreamHandler;
private EventChannel.StreamHandler mActivityIdentificationStreamHandler;
private EventChannel.StreamHandler mActivityConversionStreamHandler;
private FusedLocationMethodHandler fusedLocationMethodHandler;
private GeofenceMethodHandler geofenceMethodHandler;
private ActivityIdentificationMethodHandler activityIdentificationMethodHandler;
private HMSLoggerMethodHandler hmsLoggerMethodHandler;
public static void registerWith(final Registrar registrar) {
final LocationPlugin instance = new LocationPlugin();
final Activity activity = registrar.activity();
final Context context = activity.getApplicationContext();
final BinaryMessenger messenger = registrar.messenger();
instance.onAttachedToEngine(context, messenger);
instance.permissionHandler = new PermissionHandler(activity);
instance.permissionMethodChannel.setMethodCallHandler(instance.permissionHandler);
instance.fusedLocationMethodHandler = new FusedLocationMethodHandler(activity,
instance.fusedLocationMethodChannel);
instance.fusedLocationMethodChannel.setMethodCallHandler(instance.fusedLocationMethodHandler);
instance.geofenceMethodHandler = new GeofenceMethodHandler(activity);
instance.geofenceMethodChannel.setMethodCallHandler(instance.geofenceMethodHandler);
instance.activityIdentificationMethodHandler = new ActivityIdentificationMethodHandler(activity);
instance.activityIdentificationMethodChannel.setMethodCallHandler(instance.activityIdentificationMethodHandler);
instance.hmsLoggerMethodHandler = new HMSLoggerMethodHandler(context);
instance.hmsLoggerMethodChannel.setMethodCallHandler(instance.hmsLoggerMethodHandler);
registrar.addRequestPermissionsResultListener(instance.permissionHandler);
registrar.addActivityResultListener(instance.fusedLocationMethodHandler);
}
private void initChannels(final BinaryMessenger messenger) {
permissionMethodChannel = new MethodChannel(messenger, Channel.PERMISSON_METHOD.id());
fusedLocationMethodChannel = new MethodChannel(messenger, Channel.FUSED_LOCATION_METHOD.id());
geofenceMethodChannel = new MethodChannel(messenger, Channel.GEOFENCE_METHOD.id());
activityIdentificationMethodChannel = new MethodChannel(messenger, Channel.ACTIVITY_IDENTIFICATION_METHOD.id());
locationEnhanceMethodChannel = new MethodChannel(messenger, Channel.LOCATION_ENHANCE_METHOD.id());
hmsLoggerMethodChannel = new MethodChannel(messenger, Channel.HMSLOGGER_METHOD.id());
mFusedLocationEventChannel = new EventChannel(messenger, Channel.FUSED_LOCATION_EVENT.id());
mGeofenceEventChannel = new EventChannel(messenger, Channel.GEOFENCE_EVENT.id());
mActivityIdentificationEventChannel = new EventChannel(messenger, Channel.ACTIVITY_IDENTIFICATION_EVENT.id());
mActivityConversionEventChannel = new EventChannel(messenger, Channel.ACTIVITY_CONVERSION_EVENT.id());
}
private void initStreamHandlers(final Context context) {
mFusedLocationStreamHandler = new FusedLocationStreamHandler(context);
mGeofenceStreamHandler = new GeofenceStreamHandler(context);
mActivityIdentificationStreamHandler = new ActivityIdentificationStreamHandler(context);
mActivityConversionStreamHandler = new ActivityConversionStreamHandler(context);
}
private void setStreamHandlers() {
mFusedLocationEventChannel.setStreamHandler(mFusedLocationStreamHandler);
mGeofenceEventChannel.setStreamHandler(mGeofenceStreamHandler);
mActivityIdentificationEventChannel.setStreamHandler(mActivityIdentificationStreamHandler);
mActivityConversionEventChannel.setStreamHandler(mActivityConversionStreamHandler);
}
private void resetStreamHandlers() {
mFusedLocationEventChannel.setStreamHandler(null);
mGeofenceEventChannel.setStreamHandler(null);
mActivityIdentificationEventChannel.setStreamHandler(null);
mActivityConversionEventChannel.setStreamHandler(null);
}
private void removeStreamHandlers() {
mFusedLocationStreamHandler = null;
mGeofenceStreamHandler = null;
mActivityIdentificationStreamHandler = null;
mActivityConversionStreamHandler = null;
}
private void removeChannels() {
permissionMethodChannel = null;
fusedLocationMethodChannel = null;
geofenceMethodChannel = null;
activityIdentificationMethodChannel = null;
locationEnhanceMethodChannel = null;
hmsLoggerMethodChannel = null;
mFusedLocationEventChannel = null;
mGeofenceEventChannel = null;
mActivityIdentificationEventChannel = null;
mActivityConversionEventChannel = null;
}
private void onAttachedToEngine(final Context context, final BinaryMessenger messenger) {
initChannels(messenger);
initStreamHandlers(context);
setStreamHandlers();
}
@Override
public void onAttachedToEngine(@NonNull final FlutterPluginBinding binding) {
onAttachedToEngine(binding.getApplicationContext(), binding.getBinaryMessenger());
}
@Override
public void onDetachedFromEngine(@NonNull final FlutterPluginBinding binding) {
resetStreamHandlers();
removeStreamHandlers();
removeChannels();
}
@Override
public void onAttachedToActivity(@NonNull final ActivityPluginBinding binding) {
final Activity activity = binding.getActivity();
permissionHandler = new PermissionHandler(activity);
fusedLocationMethodHandler = new FusedLocationMethodHandler(activity, fusedLocationMethodChannel);
geofenceMethodHandler = new GeofenceMethodHandler(activity);
activityIdentificationMethodHandler = new ActivityIdentificationMethodHandler(activity);
hmsLoggerMethodHandler = new HMSLoggerMethodHandler(activity.getApplicationContext());
binding.addRequestPermissionsResultListener(permissionHandler);
binding.addActivityResultListener(fusedLocationMethodHandler);
permissionMethodChannel.setMethodCallHandler(permissionHandler);
fusedLocationMethodChannel.setMethodCallHandler(fusedLocationMethodHandler);
geofenceMethodChannel.setMethodCallHandler(geofenceMethodHandler);
activityIdentificationMethodChannel.setMethodCallHandler(activityIdentificationMethodHandler);
hmsLoggerMethodChannel.setMethodCallHandler(hmsLoggerMethodHandler);
}
@Override
public void onDetachedFromActivityForConfigChanges() {
onDetachedFromActivity();
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull final ActivityPluginBinding binding) {
onAttachedToActivity(binding);
}
@Override
public void onDetachedFromActivity() {
activityIdentificationMethodChannel.setMethodCallHandler(null);
geofenceMethodChannel.setMethodCallHandler(null);
fusedLocationMethodChannel.setMethodCallHandler(null);
locationEnhanceMethodChannel.setMethodCallHandler(null);
hmsLoggerMethodChannel.setMethodCallHandler(null);
activityIdentificationMethodHandler = null;
geofenceMethodHandler = null;
fusedLocationMethodHandler = null;
permissionHandler = null;
hmsLoggerMethodHandler = null;
}
}

@ -0,0 +1,24 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.constants;
public interface Action {
String PROCESS_LOCATION = "com.huawei.hms.flutter.location.ACTION_PROCESS_LOCATION";
String PROCESS_GEOFENCE = "com.huawei.hms.flutter.location.ACTION_PROCESS_GEOFENCE";
String PROCESS_CONVERSION = "com.huawei.hms.flutter.location.ACTION_PROCESS_CONVERSION";
String PROCESS_IDENTIFICATION = "com.huawei.hms.flutter.location.ACTION_PROCESS_IDENTIFICATION";
}

@ -0,0 +1,40 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.constants;
public enum Channel {
PERMISSON_METHOD("com.huawei.flutter.location/permission_methodchannel"),
FUSED_LOCATION_METHOD("com.huawei.flutter.location/fusedlocation_methodchannel"),
FUSED_LOCATION_EVENT("com.huawei.flutter.location/fusedlocation_eventchannel"),
GEOFENCE_METHOD("com.huawei.flutter.location/geofence_methodchannel"),
GEOFENCE_EVENT("com.huawei.flutter.location/geofence_eventchannel"),
ACTIVITY_IDENTIFICATION_METHOD("com.huawei.flutter.location/activityidentification_methodchannel"),
ACTIVITY_IDENTIFICATION_EVENT("com.huawei.flutter.location/activityidentification_eventchannel"),
ACTIVITY_CONVERSION_EVENT("com.huawei.flutter.location/activityconversion_eventchannel"),
LOCATION_ENHANCE_METHOD("com.huawei.flutter.location/locationenhance_methodchannel"),
HMSLOGGER_METHOD("com.huawei.flutter.location/hmslogger_methodchannel");
private final String id;
Channel(final String id) {
this.id = id;
}
public String id() {
return id;
}
}

@ -0,0 +1,33 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.constants;
public enum Error {
LOCATION_SETTINGS_NOT_AVAILABLE("Unable to get location settings"),
NON_EXISTING_REQUEST_ID("Request ID does not exists"),
SEND_INTENT_EXCEPTION("Unable to send intent");
private final String message;
Error(final String message) {
this.message = message;
}
public String message() {
return message;
}
}

@ -0,0 +1,53 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import com.huawei.hms.flutter.location.constants.Action;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.receivers.ActivityConversionBroadcastReceiver;
import io.flutter.plugin.common.EventChannel.EventSink;
import io.flutter.plugin.common.EventChannel.StreamHandler;
public class ActivityConversionStreamHandler implements StreamHandler {
private final Context context;
private BroadcastReceiver broadcastReceiver;
public ActivityConversionStreamHandler(final Context context) {
this.context = context;
}
@Override
public void onListen(final Object arguments, final EventSink events) {
broadcastReceiver = new ActivityConversionBroadcastReceiver(events);
context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_CONVERSION));
HMSLogger.getInstance(context).sendSingleEvent("ActivityConversionStreamHandler.onListen");
}
@Override
public void onCancel(final Object arguments) {
context.unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
HMSLogger.getInstance(context).sendSingleEvent("ActivityConversionStreamHandler.onCancel");
}
}

@ -0,0 +1,141 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.core.util.Pair;
import com.huawei.hms.flutter.location.constants.Action;
import com.huawei.hms.flutter.location.constants.Error;
import com.huawei.hms.flutter.location.listeners.DefaultFailureListener;
import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener;
import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener;
import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.ActivityUtils;
import com.huawei.hms.location.ActivityConversionRequest;
import com.huawei.hms.location.ActivityIdentification;
import com.huawei.hms.location.ActivityIdentificationService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
public class ActivityIdentificationMethodHandler implements MethodCallHandler {
private final Activity activity;
private final Map<Integer, PendingIntent> requests;
private final ActivityIdentificationService service;
private int requestCode = 0;
public ActivityIdentificationMethodHandler(final Activity activity) {
this.activity = activity;
service = ActivityIdentification.getService(activity);
requests = new HashMap<>();
}
private void createActivityIdentificationUpdates(final MethodCall call, final Result result) {
final Pair<Integer, PendingIntent> intentData = buildPendingIntent(Action.PROCESS_IDENTIFICATION);
service.createActivityIdentificationUpdates(call.<Integer>arguments(), intentData.second)
.addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first))
.addOnFailureListener(
new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests));
}
private void createActivityConversionUpdates(final MethodCall call, final Result result) {
final List<Map<String, Object>> args = call.arguments();
final Pair<Integer, PendingIntent> intentData = buildPendingIntent(Action.PROCESS_CONVERSION);
final ActivityConversionRequest request
= ActivityUtils.fromActivityConversionInfoListToActivityConversionRequest(args);
service.createActivityConversionUpdates(request, intentData.second)
.addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first))
.addOnFailureListener(
new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests));
}
private void deleteActivityIdentificationUpdates(final MethodCall call, final Result result) {
final int incomingRequestCode = call.<Integer>arguments();
if (!requests.containsKey(incomingRequestCode)) {
result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null);
} else {
service.deleteActivityIdentificationUpdates(requests.get(incomingRequestCode))
.addOnSuccessListener(
new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
}
private void deleteActivityConversionUpdates(final MethodCall call, final Result result) {
final int incomingRequestCode = call.<Integer>arguments();
if (!requests.containsKey(incomingRequestCode)) {
result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null);
} else {
service.deleteActivityConversionUpdates(requests.get(incomingRequestCode))
.addOnSuccessListener(
new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
}
private Pair<Integer, PendingIntent> buildPendingIntent(final String action) {
final Intent intent = new Intent();
intent.setPackage(activity.getPackageName());
intent.setAction(action);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
requests.put(requestCode, pendingIntent);
return Pair.create(requestCode, pendingIntent);
}
@Override
public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) {
HMSLogger.getInstance(activity).startMethodExecutionTimer(call.method);
switch (call.method) {
case "createActivityIdentificationUpdates":
createActivityIdentificationUpdates(call, result);
break;
case "createActivityConversionUpdates":
createActivityConversionUpdates(call, result);
break;
case "deleteActivityIdentificationUpdates":
deleteActivityIdentificationUpdates(call, result);
break;
case "deleteActivityConversionUpdates":
deleteActivityConversionUpdates(call, result);
break;
default:
result.notImplemented();
break;
}
}
}

@ -0,0 +1,53 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import com.huawei.hms.flutter.location.constants.Action;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.receivers.ActivityIdentificationBroadcastReceiver;
import io.flutter.plugin.common.EventChannel.EventSink;
import io.flutter.plugin.common.EventChannel.StreamHandler;
public class ActivityIdentificationStreamHandler implements StreamHandler {
private final Context context;
private BroadcastReceiver broadcastReceiver;
public ActivityIdentificationStreamHandler(final Context context) {
this.context = context;
}
@Override
public void onListen(final Object arguments, final EventSink events) {
broadcastReceiver = new ActivityIdentificationBroadcastReceiver(events);
context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_IDENTIFICATION));
HMSLogger.getInstance(context).sendSingleEvent("ActivityIdentificationStreamHandler.onListen");
}
@Override
public void onCancel(final Object arguments) {
context.unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
HMSLogger.getInstance(context).sendSingleEvent("ActivityIdentificationStreamHandler.onCancel");
}
}

@ -0,0 +1,265 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Looper;
import android.util.Pair;
import androidx.annotation.NonNull;
import com.huawei.hms.flutter.location.constants.Action;
import com.huawei.hms.flutter.location.constants.Error;
import com.huawei.hms.flutter.location.listeners.DefaultFailureListener;
import com.huawei.hms.flutter.location.listeners.DefaultSuccessListener;
import com.huawei.hms.flutter.location.listeners.LocationSettingsFailureListener;
import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener;
import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener;
import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.LocationUtils;
import com.huawei.hms.location.FusedLocationProviderClient;
import com.huawei.hms.location.LocationEnhanceService;
import com.huawei.hms.location.LocationRequest;
import com.huawei.hms.location.LocationServices;
import com.huawei.hms.location.LocationSettingsRequest;
import com.huawei.hms.location.LocationSettingsStates;
import com.huawei.hms.location.NavigationRequest;
import com.huawei.hms.location.SettingsClient;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry.ActivityResultListener;
public class FusedLocationMethodHandler implements MethodChannel.MethodCallHandler, ActivityResultListener {
private final Activity activity;
private final MethodChannel channel;
private final Map<Integer, LocationCallbackHandler> callbacks;
private final Map<Integer, PendingIntent> requests;
private final SettingsClient settingsClient;
private final FusedLocationProviderClient service;
private final LocationEnhanceService enhanceService;
private int requestCode = 0;
private MethodChannel.Result result;
public FusedLocationMethodHandler(final Activity activity, final MethodChannel channel) {
this.activity = activity;
this.channel = channel;
callbacks = new HashMap<>();
requests = new HashMap<>();
settingsClient = LocationServices.getSettingsClient(activity);
service = LocationServices.getFusedLocationProviderClient(activity);
enhanceService = LocationServices.getLocationEnhanceService(activity);
}
private void checkLocationSettings(final MethodCall call, final MethodChannel.Result result) {
final LocationSettingsRequest request = LocationUtils.fromMapToLocationSettingsRequest(call.arguments());
this.result = result;
settingsClient.checkLocationSettings(request)
.addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result))
.addOnFailureListener(new LocationSettingsFailureListener(result, activity));
}
private void getLastLocation(final MethodCall call, final MethodChannel.Result result) {
service.getLastLocation()
.addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
private void getLastLocationWithAddress(final MethodCall call, final MethodChannel.Result result) {
service.getLastLocationWithAddress(
LocationUtils.fromMapToLocationRequest(call.<Map<String, Object>>arguments()))
.addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
private void getLocationAvailability(final MethodCall call, final MethodChannel.Result result) {
service.getLocationAvailability()
.addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
private void setMockMode(final MethodCall call, final MethodChannel.Result result) {
service.setMockMode(call.<Boolean>arguments())
.addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
private void setMockLocation(final MethodCall call, final MethodChannel.Result result) {
service.setMockLocation(LocationUtils.fromMapToLocation(call.arguments()))
.addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
private void requestLocationUpdates(final MethodCall call, final MethodChannel.Result result) {
final Pair<Integer, PendingIntent> intentData = buildLocationIntent();
final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.<Map<String, Object>>arguments());
service.requestLocationUpdates(request, intentData.second)
.addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first))
.addOnFailureListener(
new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests));
}
private void requestLocationUpdatesCb(final MethodCall call, final MethodChannel.Result result) {
final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.<Map<String, Object>>arguments());
final Pair<Integer, LocationCallbackHandler> callbackData = buildCallback(call.method);
service.requestLocationUpdates(request, callbackData.second, Looper.getMainLooper())
.addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, callbackData.first))
.addOnFailureListener(
new RequestUpdatesFailureListener<>(call.method, activity, result, callbackData.first, callbacks));
}
private void requestLocationUpdatesExCb(final MethodCall call, final MethodChannel.Result result) {
final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.<Map<String, Object>>arguments());
final Pair<Integer, LocationCallbackHandler> callbackData = buildCallback(call.method);
service.requestLocationUpdatesEx(request, callbackData.second, Looper.getMainLooper())
.addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, callbackData.first))
.addOnFailureListener(
new RequestUpdatesFailureListener<>(call.method, activity, result, callbackData.first, callbacks));
}
private void removeLocationUpdates(final MethodCall call, final MethodChannel.Result result) {
final int incomingRequestCode = call.<Integer>arguments();
if (!requests.containsKey(incomingRequestCode)) {
result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null);
} else {
service.removeLocationUpdates(requests.get(incomingRequestCode))
.addOnSuccessListener(
new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
}
private void removeLocationUpdatesCb(final MethodCall call, final MethodChannel.Result result) {
final int callbackId = call.<Integer>arguments();
if (!callbacks.containsKey(callbackId)) {
result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null);
} else {
service.removeLocationUpdates(callbacks.get(callbackId))
.addOnSuccessListener(
new RemoveUpdatesSuccessListener<>(call.method, activity, result, callbackId, callbacks))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
}
private void getNavigationContextState(final MethodCall call, final MethodChannel.Result result) {
final NavigationRequest request = LocationUtils.fromMapToNavigationRequest(call.arguments());
enhanceService.getNavigationState(request)
.addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
private Pair<Integer, LocationCallbackHandler> buildCallback(final String methodName) {
final LocationCallbackHandler callBack = new LocationCallbackHandler(activity.getApplicationContext(),
methodName, ++requestCode, channel);
callbacks.put(requestCode, callBack);
return Pair.create(requestCode, callBack);
}
private Pair<Integer, PendingIntent> buildLocationIntent() {
final Intent intent = new Intent();
intent.setPackage(activity.getPackageName());
intent.setAction(Action.PROCESS_LOCATION);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
requests.put(requestCode, pendingIntent);
return Pair.create(requestCode, pendingIntent);
}
@Override
public void onMethodCall(@NonNull final MethodCall call, @NonNull final MethodChannel.Result result) {
HMSLogger.getInstance(activity.getApplicationContext()).startMethodExecutionTimer(call.method);
switch (call.method) {
case "checkLocationSettings":
checkLocationSettings(call, result);
break;
case "getLastLocation":
getLastLocation(call, result);
break;
case "getLastLocationWithAddress":
getLastLocationWithAddress(call, result);
break;
case "getLocationAvailability":
getLocationAvailability(call, result);
break;
case "setMockMode":
setMockMode(call, result);
break;
case "setMockLocation":
setMockLocation(call, result);
break;
case "requestLocationUpdates":
requestLocationUpdates(call, result);
break;
case "requestLocationUpdatesCb":
requestLocationUpdatesCb(call, result);
break;
case "requestLocationUpdatesExCb":
requestLocationUpdatesExCb(call, result);
break;
case "removeLocationUpdates":
removeLocationUpdates(call, result);
break;
case "removeLocationUpdatesCb":
removeLocationUpdatesCb(call, result);
break;
case "getNavigationContextState":
getNavigationContextState(call, result);
break;
default:
result.notImplemented();
break;
}
}
@Override
public boolean onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
final MethodChannel.Result incomingResult = result;
result = null;
if (incomingResult != null && requestCode == 0) {
if (resultCode == Activity.RESULT_OK) {
final LocationSettingsStates states = LocationSettingsStates.fromIntent(intent);
HMSLogger.getInstance(activity.getApplicationContext())
.sendSingleEvent("checkLocationSettings.onActivityResult");
incomingResult.success(LocationUtils.fromLocationSettingsStatesToMap(states));
} else {
HMSLogger.getInstance(activity.getApplicationContext())
.sendSingleEvent("checkLocationSettings" + ".onActivityResult", "-1");
incomingResult.error(Error.LOCATION_SETTINGS_NOT_AVAILABLE.name(),
Error.LOCATION_SETTINGS_NOT_AVAILABLE.message(), null);
}
}
return true;
}
}

@ -0,0 +1,51 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import com.huawei.hms.flutter.location.constants.Action;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.receivers.FusedLocationBroadcastReceiver;
import io.flutter.plugin.common.EventChannel.EventSink;
import io.flutter.plugin.common.EventChannel.StreamHandler;
public class FusedLocationStreamHandler implements StreamHandler {
private final Context context;
private BroadcastReceiver broadcastReceiver;
public FusedLocationStreamHandler(final Context context) {
this.context = context;
}
@Override
public void onListen(final Object arguments, final EventSink events) {
broadcastReceiver = new FusedLocationBroadcastReceiver(events);
context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_LOCATION));
HMSLogger.getInstance(context).sendSingleEvent("FusedLocationStreamHandler.onListen");
}
@Override
public void onCancel(final Object arguments) {
context.unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
HMSLogger.getInstance(context).sendSingleEvent("FusedLocationStreamHandler.onCancel");
}
}

@ -0,0 +1,119 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Pair;
import androidx.annotation.NonNull;
import com.huawei.hms.flutter.location.constants.Action;
import com.huawei.hms.flutter.location.constants.Error;
import com.huawei.hms.flutter.location.listeners.DefaultFailureListener;
import com.huawei.hms.flutter.location.listeners.DefaultSuccessListener;
import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener;
import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener;
import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.GeofenceUtils;
import com.huawei.hms.location.GeofenceRequest;
import com.huawei.hms.location.GeofenceService;
import com.huawei.hms.location.LocationServices;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
public class GeofenceMethodHandler implements MethodCallHandler {
private final Activity activity;
private final GeofenceService service;
private final Map<Integer, PendingIntent> requests;
private int requestCode = 0;
public GeofenceMethodHandler(final Activity activity) {
this.activity = activity;
service = LocationServices.getGeofenceService(activity);
requests = new HashMap<>();
}
private void createGeofenceList(@NonNull final MethodCall call, @NonNull final Result result) {
final GeofenceRequest geofenceRequest = GeofenceUtils.fromMapToGeofenceRequest(call.arguments());
final Pair<Integer, PendingIntent> intentData = buildGeofenceIntent();
service.createGeofenceList(geofenceRequest, intentData.second)
.addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first))
.addOnFailureListener(
new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests));
}
private void deleteGeofenceList(@NonNull final MethodCall call, @NonNull final Result result) {
final int incomingRequestCode = call.<Integer>arguments();
if (!requests.containsKey(incomingRequestCode)) {
result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null);
} else {
service.deleteGeofenceList(requests.get(incomingRequestCode))
.addOnSuccessListener(
new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
}
private void deleteGeofenceListWithIds(@NonNull final MethodCall call, @NonNull final Result result) {
service.deleteGeofenceList(call.<List<String>>arguments())
.addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result))
.addOnFailureListener(new DefaultFailureListener(call.method, activity, result));
}
private Pair<Integer, PendingIntent> buildGeofenceIntent() {
final Intent intent = new Intent();
intent.setPackage(activity.getPackageName());
intent.setAction(Action.PROCESS_GEOFENCE);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
requests.put(requestCode, pendingIntent);
return Pair.create(requestCode, pendingIntent);
}
@Override
public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) {
HMSLogger.getInstance(activity.getApplicationContext()).startMethodExecutionTimer(call.method);
switch (call.method) {
case "createGeofenceList":
createGeofenceList(call, result);
break;
case "deleteGeofenceList":
deleteGeofenceList(call, result);
break;
case "deleteGeofenceListWithIds":
deleteGeofenceListWithIds(call, result);
break;
default:
result.notImplemented();
break;
}
}
}

@ -0,0 +1,53 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import com.huawei.hms.flutter.location.constants.Action;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.receivers.GeofenceBroadcastReceiver;
import io.flutter.plugin.common.EventChannel.EventSink;
import io.flutter.plugin.common.EventChannel.StreamHandler;
public class GeofenceStreamHandler implements StreamHandler {
private final Context context;
private BroadcastReceiver broadcastReceiver;
public GeofenceStreamHandler(final Context context) {
this.context = context;
}
@Override
public void onListen(final Object arguments, final EventSink events) {
broadcastReceiver = new GeofenceBroadcastReceiver(events);
context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_GEOFENCE));
HMSLogger.getInstance(context).sendSingleEvent("GeofenceStreamHandler.onListen");
}
@Override
public void onCancel(final Object arguments) {
context.unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
HMSLogger.getInstance(context).sendSingleEvent("GeofenceStreamHandler.onCancel");
}
}

@ -0,0 +1,51 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.content.Context;
import androidx.annotation.NonNull;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
public class HMSLoggerMethodHandler implements MethodCallHandler {
private final Context context;
public HMSLoggerMethodHandler(final Context context) {
this.context = context;
}
@Override
public void onMethodCall(final MethodCall call, @NonNull final Result result) {
switch (call.method) {
case "enableLogger":
HMSLogger.getInstance(context).enableLogger();
result.success(null);
break;
case "disableLogger":
HMSLogger.getInstance(context).disableLogger();
result.success(null);
break;
default:
break;
}
}
}

@ -0,0 +1,71 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import android.content.Context;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.LocationUtils;
import com.huawei.hms.location.LocationAvailability;
import com.huawei.hms.location.LocationCallback;
import com.huawei.hms.location.LocationResult;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.MethodChannel;
public class LocationCallbackHandler extends LocationCallback {
private final Context context;
private final String methodName;
private final int callbackId;
private final MethodChannel channel;
LocationCallbackHandler(final Context context, final String methodName, final int callbackId,
final MethodChannel channel) {
this.context = context;
this.methodName = methodName;
this.callbackId = callbackId;
this.channel = channel;
}
@Override
public void onLocationResult(final LocationResult locationResult) {
if (locationResult != null) {
final Map<String, Object> map = new HashMap<>();
map.put("callbackId", callbackId);
map.put("locationResult", LocationUtils.fromLocationResultToMap(locationResult));
HMSLogger.getInstance(context).sendPeriodicEvent(methodName + ".onLocationResult");
channel.invokeMethod("onLocationResult", map);
}
}
@Override
public void onLocationAvailability(final LocationAvailability locationAvailability) {
if (locationAvailability != null) {
final Map<String, Object> map = new HashMap<>();
map.put("callbackId", callbackId);
map.put("locationAvailability", LocationUtils.fromLocationAvailabilityToMap(locationAvailability));
HMSLogger.getInstance(context).sendPeriodicEvent(methodName + ".onLocationAvailability");
channel.invokeMethod("onLocationAvailability", map);
}
}
}

@ -0,0 +1,192 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.handlers;
import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
import static androidx.core.content.PermissionChecker.checkSelfPermission;
import android.app.Activity;
import android.os.Build;
import androidx.annotation.NonNull;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener;
public class PermissionHandler implements MethodCallHandler, RequestPermissionsResultListener {
private static final String HUAWEI_ACTIVITY_RECOGNITION_PERMISSION = "android.permission.ACTIVITY_RECOGNITION";
private static final String[] BG_LOC_PERMISSION_OLD = {
android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION
};
private final Activity activity;
private final HMSLogger hmsLogger;
private Result result;
public PermissionHandler(final Activity activity) {
this.activity = activity;
hmsLogger = HMSLogger.getInstance(activity.getApplicationContext());
}
private boolean hasLocationPermission() {
hmsLogger.sendSingleEvent("hasLocationPermission");
return isCoarseLocGranted() && isFineLocGranted();
}
private boolean hasBackgroundLocationPermission() {
hmsLogger.sendSingleEvent("hasBackgroundLocationPermission");
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
return isFineLocGranted() && isBackgroundLocGranted();
}
return isCoarseLocGranted() || isFineLocGranted();
}
private boolean hasActivityRecognitionPermission() {
hmsLogger.sendSingleEvent("hasActivityRecognitionPermission");
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
return PERMISSION_GRANTED == checkSelfPermission(activity.getApplicationContext(),
android.Manifest.permission.ACTIVITY_RECOGNITION);
} else {
return PERMISSION_GRANTED == checkSelfPermission(activity.getApplicationContext(),
HUAWEI_ACTIVITY_RECOGNITION_PERMISSION);
}
}
private void requestLocationPermission() {
hmsLogger.sendSingleEvent("requestLocationPermission");
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
final String[] permissions = {
android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
};
activity.requestPermissions(permissions, 1);
} else {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
activity.requestPermissions(BG_LOC_PERMISSION_OLD, 2);
}
}
}
private void requestBackgroundLocationPermission() {
hmsLogger.sendSingleEvent("requestBackgroundLocationPermission");
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
final String[] permissions = {
android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
};
activity.requestPermissions(permissions, 3);
} else {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
activity.requestPermissions(BG_LOC_PERMISSION_OLD, 4);
}
}
}
private void requestActivityRecognitionPermission() {
hmsLogger.sendSingleEvent("requestActivityRecognitionPermission");
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
final String[] permissions = {android.Manifest.permission.ACTIVITY_RECOGNITION};
activity.requestPermissions(permissions, 5);
} else {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
final String[] permissions = {HUAWEI_ACTIVITY_RECOGNITION_PERMISSION};
activity.requestPermissions(permissions, 6);
}
}
}
private boolean isCoarseLocGranted() {
final int coarseLoc = checkSelfPermission(activity, android.Manifest.permission.ACCESS_COARSE_LOCATION);
return coarseLoc == PERMISSION_GRANTED;
}
private boolean isFineLocGranted() {
final int fineLoc = checkSelfPermission(activity, android.Manifest.permission.ACCESS_FINE_LOCATION);
return fineLoc == PERMISSION_GRANTED;
}
private boolean isBackgroundLocGranted() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
final int backgroundLoc = checkSelfPermission(activity,
android.Manifest.permission.ACCESS_BACKGROUND_LOCATION);
return backgroundLoc == PERMISSION_GRANTED;
}
return true;
}
private boolean checkGrantStatus(final int[] grantResults) {
for (final int i : grantResults) {
if (i != 0) {
return false;
}
}
return true;
}
@Override
public void onMethodCall(final MethodCall call, @NonNull final Result result) {
this.result = result;
hmsLogger.startMethodExecutionTimer(call.method);
switch (call.method) {
case "hasLocationPermission":
result.success(hasLocationPermission());
break;
case "hasBackgroundLocationPermission":
result.success(hasBackgroundLocationPermission());
break;
case "hasActivityRecognitionPermission":
result.success(hasActivityRecognitionPermission());
break;
case "requestLocationPermission":
requestLocationPermission();
break;
case "requestBackgroundLocationPermission":
requestBackgroundLocationPermission();
break;
case "requestActivityRecognitionPermission":
requestActivityRecognitionPermission();
break;
default:
break;
}
}
@Override
public boolean onRequestPermissionsResult(final int requestCode, final String[] permissions,
final int[] grantResults) {
final Result incomingResult = result;
result = null;
if (incomingResult != null) {
if (requestCode == 1) {
incomingResult.success(grantResults[0] == 0 || grantResults[1] == 0);
} else if (requestCode == 3) {
incomingResult.success((grantResults[0] == 0 || grantResults[1] == 0) && grantResults[2] == 0);
} else {
incomingResult.success(checkGrantStatus(grantResults));
}
}
return true;
}
}

@ -0,0 +1,47 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.listeners;
import android.content.Context;
import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hms.common.ApiException;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.ObjectUtils;
import io.flutter.plugin.common.MethodChannel.Result;
public class DefaultFailureListener implements OnFailureListener {
private final String methodName;
private final Context context;
private final Result result;
public DefaultFailureListener(final String methodName, final Context context, final Result result) {
this.methodName = methodName;
this.context = context;
this.result = result;
}
@Override
public void onFailure(final Exception e) {
final ApiException ex = ObjectUtils.cast(e, ApiException.class);
final String statusCodeString = Integer.toString(ex.getStatusCode());
HMSLogger.getInstance(context).sendSingleEvent(methodName, statusCodeString);
result.error(statusCodeString, ex.getMessage(), null);
}
}

@ -0,0 +1,79 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.listeners;
import android.content.Context;
import android.location.Location;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.LocationUtils;
import com.huawei.hms.flutter.location.utils.ObjectUtils;
import com.huawei.hms.location.HWLocation;
import com.huawei.hms.location.LocationAvailability;
import com.huawei.hms.location.LocationSettingsResponse;
import com.huawei.hms.location.LocationSettingsStates;
import com.huawei.hms.location.NavigationResult;
import io.flutter.plugin.common.MethodChannel.Result;
public class DefaultSuccessListener<T> implements OnSuccessListener<T> {
private final String methodName;
private final Context context;
private final Result result;
public DefaultSuccessListener(final String methodName, final Context context, final Result result) {
this.methodName = methodName;
this.context = context;
this.result = result;
}
@Override
public void onSuccess(final T o) {
HMSLogger.getInstance(context).sendSingleEvent(methodName);
if (o instanceof Void || o == null) {
result.success(null);
}
if (o instanceof Location) {
final Location location = ObjectUtils.cast(o, Location.class);
result.success(LocationUtils.fromLocationToMap(location));
}
if (o instanceof HWLocation) {
final HWLocation hwLocation = ObjectUtils.cast(o, HWLocation.class);
result.success(LocationUtils.fromHWLocationToMap(hwLocation));
}
if (o instanceof LocationAvailability) {
final LocationAvailability locationAvailability = ObjectUtils.cast(o, LocationAvailability.class);
result.success(LocationUtils.fromLocationAvailabilityToMap(locationAvailability));
}
if (o instanceof LocationSettingsResponse) {
final LocationSettingsResponse response = ObjectUtils.cast(o, LocationSettingsResponse.class);
final LocationSettingsStates locationSettingsStates = response.getLocationSettingsStates();
result.success(LocationUtils.fromLocationSettingsStatesToMap(locationSettingsStates));
}
if (o instanceof NavigationResult) {
final NavigationResult navigationResult = ObjectUtils.cast(o, NavigationResult.class);
result.success(LocationUtils.fromNavigationResultToMap(navigationResult));
}
}
}

@ -0,0 +1,62 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.listeners;
import static com.huawei.hms.location.LocationSettingsStatusCodes.RESOLUTION_REQUIRED;
import android.app.Activity;
import android.content.IntentSender.SendIntentException;
import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hms.common.ApiException;
import com.huawei.hms.common.ResolvableApiException;
import com.huawei.hms.flutter.location.constants.Error;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.ObjectUtils;
import io.flutter.plugin.common.MethodChannel.Result;
public class LocationSettingsFailureListener implements OnFailureListener {
private final Result result;
private final Activity activity;
public LocationSettingsFailureListener(final Result result, final Activity activity) {
this.result = result;
this.activity = activity;
}
@Override
public void onFailure(final Exception e) {
final ApiException apiException = ObjectUtils.cast(e, ApiException.class);
final int statusCode = apiException.getStatusCode();
final String statusCodeString = Integer.toString(statusCode);
if (statusCode == RESOLUTION_REQUIRED) {
try {
final ResolvableApiException resolvableApiException = ObjectUtils.cast(e, ResolvableApiException.class);
resolvableApiException.startResolutionForResult(activity, 0);
} catch (final SendIntentException ex) {
HMSLogger.getInstance(activity.getApplicationContext()).sendSingleEvent("checkLocationSettings", "-1");
result.error(Error.SEND_INTENT_EXCEPTION.name(), ex.getMessage(), null);
}
} else {
HMSLogger.getInstance(activity.getApplicationContext())
.sendSingleEvent("checkLocationSettings", statusCodeString);
result.error(statusCodeString, apiException.getMessage(), null);
}
}
}

@ -0,0 +1,50 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.listeners;
import android.content.Context;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import java.util.Map;
import io.flutter.plugin.common.MethodChannel.Result;
public class RemoveUpdatesSuccessListener<T> implements OnSuccessListener<Void> {
private final String methodName;
private final Context context;
private final Result result;
private final Integer id;
private final Map<Integer, T> map;
public RemoveUpdatesSuccessListener(final String methodName, final Context context, final Result result,
final Integer id, final Map<Integer, T> map) {
this.methodName = methodName;
this.context = context;
this.result = result;
this.id = id;
this.map = map;
}
@Override
public void onSuccess(final Void avoid) {
map.remove(id);
HMSLogger.getInstance(context).sendSingleEvent(methodName);
result.success(null);
}
}

@ -0,0 +1,55 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.listeners;
import android.content.Context;
import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hms.common.ApiException;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.ObjectUtils;
import java.util.Map;
import io.flutter.plugin.common.MethodChannel.Result;
public class RequestUpdatesFailureListener<T> implements OnFailureListener {
private final String methodName;
private final Context context;
private final Result result;
private final Integer id;
private final Map<Integer, T> map;
public RequestUpdatesFailureListener(final String methodName, final Context context, final Result result,
final Integer id, final Map<Integer, T> map) {
this.methodName = methodName;
this.context = context;
this.result = result;
this.id = id;
this.map = map;
}
@Override
public void onFailure(final Exception e) {
final ApiException ex = ObjectUtils.cast(e, ApiException.class);
final String statusCodeString = Integer.toString(ex.getStatusCode());
map.remove(id);
HMSLogger.getInstance(context).sendSingleEvent(methodName, statusCodeString);
result.error(statusCodeString, ex.getMessage(), null);
}
}

@ -0,0 +1,45 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.listeners;
import android.content.Context;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import io.flutter.plugin.common.MethodChannel.Result;
public class RequestUpdatesSuccessListener implements OnSuccessListener<Void> {
private final Result result;
private final Integer requestCode;
private final Context context;
private final String methodName;
public RequestUpdatesSuccessListener(final String methodName, final Context context, final Result result,
final Integer requestCode) {
this.methodName = methodName;
this.context = context;
this.result = result;
this.requestCode = requestCode;
}
@Override
public void onSuccess(final Void avoid) {
HMSLogger.getInstance(context).sendSingleEvent(methodName);
result.success(requestCode);
}
}

@ -0,0 +1,449 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.logger;
import static android.os.Build.DEVICE;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.util.Log;
import com.huawei.agconnect.config.AGConnectServicesConfig;
import com.huawei.hms.support.hianalytics.HiAnalyticsUtils;
import com.huawei.hms.utils.HMSBIInitializer;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public final class HMSLogger {
private static final String TAG = "HMSLogger";
private static final String VERSION = "5.0.0.301";
private static final String SERVICE = "FlutterLocation";
private static final String SUCCESS = "0";
private static final String UNKNOWN = "UNKNOWN";
private static final String NOT_AVAILABLE = "NOT_AVAILABLE";
private static final String SINGLE_EVENT_ID = "60000";
private static final String PERIODIC_EVENT_ID = "60001";
private static final String NETWORK_TYPE_WIFI = "WIFI";
private static volatile HMSLogger instance;
private final WeakReference<Context> weakContext;
private final HiAnalyticsUtils hiAnalyticsUtils;
private final Map<String, Object> singleEventMap = new HashMap<>();
private final Map<String, Object> periodicEventMap = new HashMap<>();
private final Map<String, Long> allCountMap = new HashMap<>();
private final Map<String, Long> failCountMap = new HashMap<>();
private final Map<String, Long> startTimeMap = new HashMap<>();
private final Map<String, Long> firstReceiveTimeMap = new HashMap<>();
private final Map<String, Long> lastReceiveTimeMap = new HashMap<>();
private final Map<String, Map<String, Long>> resultCodeCountMap = new HashMap<>();
private final Map<Integer, String> networkTypeMap = createNetworkTypeMap();
private boolean isEnabled = true;
/**
* Private constructor of this class
*
* @param context Application's context
*/
private HMSLogger(final Context context) {
weakContext = new WeakReference<>(context);
hiAnalyticsUtils = HiAnalyticsUtils.getInstance();
setupEventMap(singleEventMap);
setupEventMap(periodicEventMap);
initHMSBI(HMSBIInitializer.getInstance(context));
Log.d(TAG, "HMS Plugin Dotting is Enabled!");
}
/**
* Returns the instance of this class
*
* @param context Application's context
* @return HMSLogger instance
*/
public static synchronized HMSLogger getInstance(final Context context) {
if (instance == null) {
synchronized (HMSLogger.class) {
if (instance == null) {
instance = new HMSLogger(context);
}
}
}
return instance;
}
/**
* Returns actual context reference
*
* @return Actual context reference
*/
private Context getContext() {
return weakContext.get();
}
/**
* Enables HMSLogger
*/
public synchronized void enableLogger() {
isEnabled = true;
Log.d(TAG, "HMS Plugin Dotting is Enabled!");
}
/**
* Disables HMSLogger
*/
public synchronized void disableLogger() {
isEnabled = false;
Log.d(TAG, "HMS Plugin Dotting is Disabled!");
}
/**
* Sets method start time for given method name
*
* @param methodName Name of the method that will be logged
*/
public synchronized void startMethodExecutionTimer(final String methodName) {
startTimeMap.put(methodName, System.currentTimeMillis());
}
/**
* Sends successful single event
*
* @param methodName The name of the method called
*/
public synchronized void sendSingleEvent(final String methodName) {
sendEvent(SINGLE_EVENT_ID, methodName, SUCCESS);
}
/**
* Sends unsuccessful single event
*
* @param methodName The name of the method called
* @param errorCode API error code
*/
public synchronized void sendSingleEvent(final String methodName, final String errorCode) {
sendEvent(SINGLE_EVENT_ID, methodName, errorCode);
}
/**
* Sends successful periodic event
*
* @param methodName The name of the method called
*/
public synchronized void sendPeriodicEvent(final String methodName) {
sendEvent(PERIODIC_EVENT_ID, methodName, SUCCESS);
}
/**
* Sends unsuccessful periodic event
*
* @param methodName The name of the method called
* @param errorCode API error code
*/
public synchronized void sendPeriodicEvent(final String methodName, final String errorCode) {
sendEvent(PERIODIC_EVENT_ID, methodName, errorCode);
}
/**
* Calls initBI() method from HMSBIInitializer
*
* @param initializer HMSBIInitializer object
*/
private void initHMSBI(final HMSBIInitializer initializer) {
if (!initializer.isInit()) {
initializer.initBI();
}
}
/**
* Sends the event based on eventId, methodName, and resultCode
*
* @param eventId Constant id of the event
* @param methodName The name of the method called
* @param resultCode Code of the method's result. "0" for success, others for error
*/
private synchronized void sendEvent(final String eventId, final String methodName, final String resultCode) {
if (isEnabled) {
final long currentTime = System.currentTimeMillis();
if (eventId.equals(SINGLE_EVENT_ID)) {
putToSingleEventMap(methodName, resultCode, currentTime);
hiAnalyticsUtils.onNewEvent(getContext(), SINGLE_EVENT_ID, singleEventMap);
Log.d(TAG, "singleEventMap -> " + singleEventMap);
} else {
putToPeriodicEventMap(methodName, resultCode, currentTime);
hiAnalyticsUtils.onNewEvent(getContext(), PERIODIC_EVENT_ID, periodicEventMap);
Log.d(TAG, "periodicEventMap -> " + periodicEventMap);
}
}
}
/**
* Gets "client/app_id" value from agconnect-services.json file
*
* @return app_id value or NOT_AVAILABLE if not found
*/
private String getAppId() {
try {
return AGConnectServicesConfig.fromContext(getContext()).getString("client/app_id");
} catch (final NullPointerException e) {
Log.d(TAG, "AgConnect is not found. Setting appId value to " + NOT_AVAILABLE);
}
return NOT_AVAILABLE;
}
/**
* Gets app version name
*
* @param packageName Package name of the app
* @return App version name in String type
*/
private String getAppVersionName(final String packageName) {
try {
return getContext().getPackageManager().getPackageInfo(packageName, 0).versionName;
} catch (final PackageManager.NameNotFoundException e) {
Log.e(TAG, "getAppVersionName -> Could not get appVersionName!");
return NOT_AVAILABLE;
}
}
/**
* Detects current network type
*
* @return Human readable network type; such as WIFI, LTE
*/
private String getNetworkType() {
final ConnectivityManager cm = objectCast(getContext().getSystemService(Context.CONNECTIVITY_SERVICE),
ConnectivityManager.class);
if (cm != null) {
if (cm.getActiveNetworkInfo() == null || !cm.getActiveNetworkInfo().isConnected()) {
return NOT_AVAILABLE;
}
final int networkSubtype = Objects.requireNonNull(cm.getActiveNetworkInfo()).getSubtype();
final String networkSubtypeString = getOrDefault(networkTypeMap, networkSubtype, UNKNOWN);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
final NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return networkSubtypeString;
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return NETWORK_TYPE_WIFI;
} else {
return UNKNOWN;
}
} else {
return NOT_AVAILABLE;
}
} else {
final int networkType = Objects.requireNonNull(cm.getActiveNetworkInfo()).getType();
switch (networkType) {
case ConnectivityManager.TYPE_WIFI:
return NETWORK_TYPE_WIFI;
case ConnectivityManager.TYPE_MOBILE:
return networkSubtypeString;
default:
return UNKNOWN;
}
}
}
return NOT_AVAILABLE;
}
/**
* Sets default values to given map
*
* @param map HashMap to put default values
*/
private void setupEventMap(final Map<String, Object> map) {
map.put("version", VERSION);
map.put("service", SERVICE);
map.put("appid", getAppId());
map.put("package", getContext().getPackageName());
map.put("cpAppVersion", getAppVersionName(getContext().getPackageName()));
map.put("model", DEVICE);
}
/**
* Prepares sing-event map according to input parameters
*
* @param methodName The name of the method called
* @param resultCode Code of the method's result. "0" for success, others for error
* @param currentTime Current timestamp in millisecond
*/
private void putToSingleEventMap(final String methodName, final String resultCode, final long currentTime) {
final long startTime = getOrDefault(startTimeMap, methodName, currentTime);
final int costTime = (int) (currentTime - startTime);
singleEventMap.put("apiName", methodName);
singleEventMap.put("result", resultCode);
singleEventMap.put("callTime", currentTime);
singleEventMap.put("costTime", costTime);
singleEventMap.put("networkType", getNetworkType());
}
/**
* Prepares periodic-event map according to input parameters
*
* @param methodName The name of the method called
* @param resultCode Code of the method's result. "0" for success, others for error
* @param currentTime Current timestamp in millisecond
*/
private void putToPeriodicEventMap(final String methodName, final String resultCode, final long currentTime) {
increaseResultCodeCount(methodName, resultCode);
increaseMapValue(methodName, allCountMap);
if (!resultCode.equals(SUCCESS)) {
increaseMapValue(methodName, failCountMap);
}
final long firstReceiveTime = getOrDefault(firstReceiveTimeMap, methodName, currentTime);
periodicEventMap.put("callTime", firstReceiveTime);
final long lastReceiveTime = getOrDefault(lastReceiveTimeMap, methodName, currentTime);
final int costTime = (int) (currentTime - lastReceiveTime);
periodicEventMap.put("costTime", costTime);
periodicEventMap.put("apiName", methodName);
periodicEventMap.put("result", resultCodeCountMap.get(methodName));
final long allCount = getOrDefault(allCountMap, methodName, 0L);
periodicEventMap.put("allCnt", allCount);
final long failCount = getOrDefault(failCountMap, methodName, 0L);
periodicEventMap.put("failCnt", failCount);
periodicEventMap.put("lastCallTime", currentTime);
periodicEventMap.put("networkType", getNetworkType());
putIfAbsent(firstReceiveTimeMap, methodName, currentTime);
lastReceiveTimeMap.put(methodName, currentTime);
}
/**
* Prepares HashMap of network type id and its human-readable string pairs
*
* @return HashMap of human readable network type names
*/
private Map<Integer, String> createNetworkTypeMap() {
final Map<Integer, String> map = new HashMap<>();
map.put(0, UNKNOWN);
map.put(1, "2.5G");
map.put(2, "2.75G");
map.put(3, "3G");
map.put(4, "2G");
map.put(5, "3G");
map.put(6, "3G");
map.put(7, "2G");
map.put(8, "3G");
map.put(9, "3G");
map.put(10, "3G");
map.put(11, "2G");
map.put(12, "3G");
map.put(13, "4G");
map.put(14, "3G");
map.put(15, "3G");
map.put(16, "2G");
map.put(17, "3G");
map.put(18, "4G");
map.put(19, "4G");
map.put(20, "5G");
return Collections.unmodifiableMap(map);
}
/**
* Increases count of the given result code
*
* @param methodName Name of the calling method
* @param resultCode Code of the method's result. "0" for success, others for error
*/
private void increaseResultCodeCount(final String methodName, final String resultCode) {
final Map<String, Long> map = getOrDefault(resultCodeCountMap, methodName, new HashMap<>());
increaseMapValue(resultCode, map);
resultCodeCountMap.put(methodName, map);
}
/**
* Increases the value of the corresponding key which in the map
*
* @param key Key for map lookup
* @param map The Map that contains the key and its corresponding value
*/
private void increaseMapValue(final String key, final Map<String, Long> map) {
map.put(key, getOrDefault(map, key, 0L) + 1);
}
/**
* Get the corresponding value of the key. If the key does not exist in the map then the default value is returned.
*
* @param map The Map
* @param key Lookup key
* @param defaultValue The default value will be returned if the key is absent
* @param <K> Generic type of the key
* @param <V> Generic type of the value
* @return Corresponding value or default value
*/
private <K, V> V getOrDefault(final Map<K, V> map, final K key, final V defaultValue) {
return map.containsKey(key) ? map.get(key) : defaultValue;
}
/**
* Put key-value pair to map if the key is absent
*
* @param map The Map
* @param key Lookup key
* @param value The value will be put to the map if the key is absent
* @param <K> Generic type of the key
* @param <V> Generic type of the value
*/
private <K, V> void putIfAbsent(final Map<K, V> map, final K key, final V value) {
if (!map.containsKey(key)) {
map.put(key, value);
}
}
/**
* Utility method that castes given object to given class type
*
* @param source Source object to be casted
* @param clazz Class that object will be casted to its type
* @param <S> Source object's type
* @param <D> Destination type
* @return Object that casted to D type
*/
private <S, D> D objectCast(final S source, final Class<D> clazz) {
return clazz.cast(source);
}
}

@ -0,0 +1,45 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.ActivityUtils;
import com.huawei.hms.location.ActivityConversionResponse;
import io.flutter.plugin.common.EventChannel.EventSink;
public class ActivityConversionBroadcastReceiver extends BroadcastReceiver {
private final EventSink eventSink;
public ActivityConversionBroadcastReceiver(final EventSink eventSink) {
this.eventSink = eventSink;
}
@Override
public void onReceive(final Context context, final Intent intent) {
if (ActivityConversionResponse.containDataFromIntent(intent)) {
final ActivityConversionResponse response = ActivityConversionResponse.getDataFromIntent(intent);
HMSLogger.getInstance(context).sendPeriodicEvent("ActivityConversionUpdates");
eventSink.success(ActivityUtils.activityConversionResponseToMap(response));
}
}
}

@ -0,0 +1,45 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.ActivityUtils;
import com.huawei.hms.location.ActivityIdentificationResponse;
import io.flutter.plugin.common.EventChannel.EventSink;
public class ActivityIdentificationBroadcastReceiver extends BroadcastReceiver {
private final EventSink eventSink;
public ActivityIdentificationBroadcastReceiver(final EventSink eventSink) {
this.eventSink = eventSink;
}
@Override
public void onReceive(final Context context, final Intent intent) {
if (ActivityIdentificationResponse.containDataFromIntent(intent)) {
final ActivityIdentificationResponse response = ActivityIdentificationResponse.getDataFromIntent(intent);
HMSLogger.getInstance(context).sendPeriodicEvent("ActivityIdentificationUpdates");
eventSink.success(ActivityUtils.activityIdentificationResponseToMap(response));
}
}
}

@ -0,0 +1,46 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.LocationUtils;
import com.huawei.hms.location.LocationResult;
import io.flutter.plugin.common.EventChannel.EventSink;
public class FusedLocationBroadcastReceiver extends BroadcastReceiver {
private final EventSink eventSink;
public FusedLocationBroadcastReceiver(final EventSink eventSink) {
this.eventSink = eventSink;
}
@Override
public void onReceive(final Context context, final Intent intent) {
if (LocationResult.hasResult(intent)) {
HMSLogger.getInstance(context).sendPeriodicEvent("LocationUpdates");
for (final Location location : LocationResult.extractResult(intent).getLocations()) {
eventSink.success(LocationUtils.fromLocationToMap(location));
}
}
}
}

@ -0,0 +1,44 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.huawei.hms.flutter.location.logger.HMSLogger;
import com.huawei.hms.flutter.location.utils.GeofenceUtils;
import com.huawei.hms.location.GeofenceData;
import io.flutter.plugin.common.EventChannel.EventSink;
public class GeofenceBroadcastReceiver extends BroadcastReceiver {
private final EventSink eventSink;
public GeofenceBroadcastReceiver(final EventSink eventSink) {
this.eventSink = eventSink;
}
@Override
public void onReceive(final Context context, final Intent intent) {
if (intent != null) {
final GeofenceData geofenceData = GeofenceData.getDataFromIntent(intent);
HMSLogger.getInstance(context).sendPeriodicEvent("GeofenceUpdates");
eventSink.success(GeofenceUtils.fromGeofenceDataToMap(geofenceData));
}
}
}

@ -0,0 +1,140 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.utils;
import com.huawei.hms.location.ActivityConversionData;
import com.huawei.hms.location.ActivityConversionInfo;
import com.huawei.hms.location.ActivityConversionRequest;
import com.huawei.hms.location.ActivityConversionResponse;
import com.huawei.hms.location.ActivityIdentificationData;
import com.huawei.hms.location.ActivityIdentificationResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public interface ActivityUtils {
/**
* Utility method
* @param list List of the ActivityConversionInfo
* @return ActivityConversionRequest object
*/
static ActivityConversionRequest fromActivityConversionInfoListToActivityConversionRequest(
final List<Map<String, Object>> list) {
final List<ActivityConversionInfo> activityConversionInfos = new ArrayList<>();
for (final Map<String, Object> map : list) {
activityConversionInfos.add(fromMapToActivityConversionInfo(map));
}
return new ActivityConversionRequest(activityConversionInfos);
}
/**
* Utility method
* @param map HashMap representation of the ActivityConversionInfo object
* @return ActivityConversionInfo object
*/
static ActivityConversionInfo fromMapToActivityConversionInfo(final Map<String, Object> map) {
return new ActivityConversionInfo(ValueGetter.getInt("activityType", map),
ValueGetter.getInt("conversionType", map));
}
/**
* Utility method
* @param data ActivityIdentificationData object
* @return HashMap representation of ActivityIdentificationData object
*/
static Map<String, Object> activityIdentificationDataToMap(final ActivityIdentificationData data) {
final Map<String, Object> map = new HashMap<>();
if (data == null) {
return map;
}
map.put("identificationActivity", data.getIdentificationActivity());
map.put("possibility", data.getPossibility());
return map;
}
/**
* Utility method
* @param response ActivityIdentificationResponse object
* @return HashMap representation of ActivityIdentificationResponse object
*/
static Map<String, Object> activityIdentificationResponseToMap(final ActivityIdentificationResponse response) {
final Map<String, Object> map = new HashMap<>();
if (response == null) {
return map;
}
map.put("time", response.getTime());
map.put("elapsedTimeFromReboot", response.getElapsedTimeFromReboot());
final List<Map<String, Object>> activityIdentificationDatas = new ArrayList<>();
for (final ActivityIdentificationData data : response.getActivityIdentificationDatas()) {
activityIdentificationDatas.add(activityIdentificationDataToMap(data));
}
map.put("activityIdentificationDatas", activityIdentificationDatas);
return map;
}
/**
* Utility method
* @param data ActivityConversionData object
* @return HashMap representation of the ActivityConversionData object
*/
static Map<String, Object> activityConversionDataToMap(final ActivityConversionData data) {
final Map<String, Object> map = new HashMap<>();
if (data == null) {
return map;
}
map.put("activityType", data.getActivityType());
map.put("conversionType", data.getConversionType());
map.put("elapsedTimeFromReboot", data.getElapsedTimeFromReboot());
return map;
}
/**
* Utility method
* @param response ActivityConversionResponse object
* @return HashMap representation of the ActivityConversionResponse object
*/
static Map<String, Object> activityConversionResponseToMap(final ActivityConversionResponse response) {
final Map<String, Object> map = new HashMap<>();
if (response == null) {
return map;
}
final List<Map<String, Object>> activityConversionDatas = new ArrayList<>();
for (final ActivityConversionData data : response.getActivityConversionDatas()) {
activityConversionDatas.add(ActivityUtils.activityConversionDataToMap(data));
}
map.put("activityConversionDatas", activityConversionDatas);
return map;
}
}

@ -0,0 +1,98 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.utils;
import com.huawei.hms.location.Geofence;
import com.huawei.hms.location.GeofenceData;
import com.huawei.hms.location.GeofenceRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public interface GeofenceUtils {
/**
* Utility method
* @param geofenceData GeofenceData object
* @return HashMap representation of the GeofenceData object
*/
static Map<String, Object> fromGeofenceDataToMap(final GeofenceData geofenceData) {
if (geofenceData == null) {
return Collections.emptyMap();
}
final Map<String, Object> map = new HashMap<>();
final List<String> convertingGeofenceIdList = new ArrayList<>();
for (final Geofence geofence : geofenceData.getConvertingGeofenceList()) {
convertingGeofenceIdList.add(geofence.getUniqueId());
}
map.put("errorCode", geofenceData.getErrorCode());
map.put("conversion", geofenceData.getConversion());
map.put("convertingGeofenceIdList", convertingGeofenceIdList);
map.put("convertingLocation", LocationUtils.fromLocationToMap(geofenceData.getConvertingLocation()));
return map;
}
/**
* Utility method
* @param map HashMap representation of the Geofence object
* @return Geofence object
*/
static Geofence fromMapToGeofence(final Map map) {
final Geofence.Builder builder = new Geofence.Builder();
final double lat = ValueGetter.getDouble("latitude", map);
final double lng = ValueGetter.getDouble("longitude", map);
final float rad = ValueGetter.getFloat("radius", map);
builder.setRoundArea(lat, lng, rad);
builder.setUniqueId(ValueGetter.getString("uniqueId", map));
builder.setConversions(ValueGetter.getInt("conversions", map));
builder.setDwellDelayTime(ValueGetter.getInt("dwellDelayTime", map));
builder.setValidContinueTime(ValueGetter.getLong("validDuration", map));
builder.setNotificationInterval(ValueGetter.getInt("notificationInterval", map));
return builder.build();
}
/**
* Utility method
* @param map HashMap representation of the GeofenceRequest object
* @return GeofenceRequest object
*/
static GeofenceRequest fromMapToGeofenceRequest(final Map<String, Object> map) {
final GeofenceRequest.Builder builder = new GeofenceRequest.Builder();
final List geofenceMapList = ObjectUtils.cast(map.get("geofenceList"), List.class);
if (geofenceMapList != null) {
for (final Object geofence : geofenceMapList) {
final Map geofenceMap = ObjectUtils.cast(geofence, Map.class);
builder.createGeofence(fromMapToGeofence(geofenceMap));
}
}
builder.setCoordinateType(ValueGetter.getInt("coordinateType", map));
builder.setInitConversions(ValueGetter.getInt("initConversions", map));
return builder.build();
}
}

@ -0,0 +1,309 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.utils;
import android.location.Location;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import com.huawei.hms.location.HWLocation;
import com.huawei.hms.location.LocationAvailability;
import com.huawei.hms.location.LocationRequest;
import com.huawei.hms.location.LocationResult;
import com.huawei.hms.location.LocationSettingsRequest;
import com.huawei.hms.location.LocationSettingsStates;
import com.huawei.hms.location.NavigationRequest;
import com.huawei.hms.location.NavigationResult;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface LocationUtils {
/**
* Utility method
* @param location ActivityIdentificationData object
* @return HashMap representation of Location object
*/
static Map<String, Object> fromLocationToMap(final Location location) {
if (location == null) {
return Collections.emptyMap();
}
final Map<String, Object> map = new HashMap<>();
map.put("provider", location.getProvider());
map.put("latitude", location.getLatitude());
map.put("longitude", location.getLongitude());
map.put("altitude", location.getAltitude());
map.put("speed", location.getSpeed());
map.put("bearing", location.getBearing());
map.put("horizontalAccuracyMeters", location.getAccuracy());
map.put("time", location.getTime());
map.put("elapsedRealtimeNanos", location.getElapsedRealtimeNanos());
map.put("isFromMockProvider", location.isFromMockProvider());
if (VERSION.SDK_INT >= VERSION_CODES.O) {
map.put("verticalAccuracyMeters", location.getVerticalAccuracyMeters());
map.put("speedAccuracyMetersPerSecond", location.getSpeedAccuracyMetersPerSecond());
map.put("bearingAccuracyDegrees", location.getBearingAccuracyDegrees());
} else {
map.put("verticalAccuracyMeters", 0.0);
map.put("speedAccuracyMetersPerSecond", 0.0);
map.put("bearingAccuracyDegrees", 0.0);
}
return map;
}
/**
* Utility method
* @param hwLocation HWLocation object
* @return HashMap representation of HWLocation object
*/
static Map<String, Object> fromHWLocationToMap(final HWLocation hwLocation) {
if (hwLocation == null) {
return Collections.emptyMap();
}
final Map<String, Object> map = new HashMap<>();
map.put("provider", hwLocation.getProvider());
map.put("latitude", hwLocation.getLatitude());
map.put("longitude", hwLocation.getLongitude());
map.put("altitude", hwLocation.getAltitude());
map.put("speed", hwLocation.getSpeed());
map.put("bearing", hwLocation.getBearing());
map.put("horizontalAccuracyMeters", hwLocation.getAccuracy());
map.put("verticalAccuracyMeters", hwLocation.getVerticalAccuracyMeters());
map.put("speedAccuracyMetersPerSecond", hwLocation.getSpeedAccuracyMetersPerSecond());
map.put("bearingAccuracyDegrees", hwLocation.getBearingAccuracyDegrees());
map.put("time", hwLocation.getTime());
map.put("elapsedRealtimeNanos", hwLocation.getElapsedRealtimeNanos());
map.put("countryCode", hwLocation.getCountryCode());
map.put("countryName", hwLocation.getCountryName());
map.put("state", hwLocation.getState());
map.put("city", hwLocation.getCity());
map.put("county", hwLocation.getCounty());
map.put("street", hwLocation.getStreet());
map.put("featureName", hwLocation.getFeatureName());
map.put("postalCode", hwLocation.getPostalCode());
map.put("phone", hwLocation.getPhone());
map.put("url", hwLocation.getUrl());
map.put("extraInfo", hwLocation.getExtraInfo());
return map;
}
/**
* Utility method
* @param locationAvailability LocationAvailability object
* @return HashMap representation of LocationAvailability object
*/
static Map<String, Object> fromLocationAvailabilityToMap(final LocationAvailability locationAvailability) {
if (locationAvailability == null) {
return Collections.emptyMap();
}
final Map<String, Object> map = new HashMap<>();
map.put("cellStatus", locationAvailability.getCellStatus());
map.put("wifiStatus", locationAvailability.getWifiStatus());
map.put("elapsedRealtimeNs", locationAvailability.getElapsedRealtimeNs());
map.put("locationStatus", locationAvailability.getLocationStatus());
return map;
}
/**
* Utility method
* @param locationResult LocationResult object
* @return HashMap representation of LocationResult object
*/
static Map<String, Object> fromLocationResultToMap(final LocationResult locationResult) {
if (locationResult == null) {
return Collections.emptyMap();
}
final Map<String, Object> map = new HashMap<>();
final List<Map<String, Object>> locationMaps = new ArrayList<>();
final List<Map<String, Object>> hwLocationMaps = new ArrayList<>();
for (final Location location : locationResult.getLocations()) {
locationMaps.add(fromLocationToMap(location));
}
for (final HWLocation hwLocation : locationResult.getHWLocationList()) {
hwLocationMaps.add(fromHWLocationToMap(hwLocation));
}
map.put("locations", locationMaps);
map.put("hwLocations", hwLocationMaps);
map.put("lastLocation", fromLocationToMap(locationResult.getLastLocation()));
map.put("lastHWLocation", fromHWLocationToMap(locationResult.getLastHWLocation()));
return map;
}
/**
* Utility method
* @param states LocationSettingsStates object
* @return HashMap representation of LocationSettingsStates object
*/
static Map<String, Object> fromLocationSettingsStatesToMap(final LocationSettingsStates states) {
if (states == null) {
return Collections.emptyMap();
}
final Map<String, Object> map = new HashMap<>();
map.put("blePresent", states.isBlePresent());
map.put("bleUsable", states.isBleUsable());
map.put("gpsPresent", states.isGpsPresent());
map.put("gpsUsable", states.isGpsUsable());
map.put("locationPresent", states.isLocationPresent());
map.put("locationUsable", states.isLocationUsable());
map.put("networkLocationPresent", states.isNetworkLocationPresent());
map.put("networkLocationUsable", states.isNetworkLocationUsable());
return map;
}
/**
* Utility method
* @param result NavigationResult object
* @return HashMap representation of NavigationResult object
*/
static Map<String, Object> fromNavigationResultToMap(final NavigationResult result) {
if (result == null) {
return Collections.emptyMap();
}
final Map<String, Object> map = new HashMap<>();
map.put("state", result.getState());
map.put("possibility", result.getPossibility());
return map;
}
/**
* Utility method
* @param map HashMap representation of the LocationRequest object
* @return LocationRequest object
*/
static LocationRequest fromMapToLocationRequest(final Map map) {
final boolean isFastestIntervalExplicitlySet = ValueGetter.getBoolean("isFastestIntervalExplicitlySet", map);
final LocationRequest result = LocationRequest.create();
if (isFastestIntervalExplicitlySet) {
result.setFastestInterval(ValueGetter.getLong("fastestInterval", map));
}
result.setPriority(ValueGetter.getInt("priority", map));
result.setInterval(ValueGetter.getLong("interval", map));
result.setExpirationTime(ValueGetter.getLong("expirationTime", map));
result.setNumUpdates(ValueGetter.getInt("numUpdates", map));
result.setSmallestDisplacement(ValueGetter.getFloat("smallestDisplacement", map));
result.setMaxWaitTime(ValueGetter.getLong("maxWaitTime", map));
result.setNeedAddress(ValueGetter.getBoolean("needAddress", map));
result.setLanguage(ValueGetter.getString("language", map));
result.setCountryCode(ValueGetter.getString("countryCode", map));
final Map extras = ObjectUtils.cast(map.get("extras"), Map.class);
if (extras != null) {
final Set entries = extras.entrySet();
for (final Object entry : entries) {
final Map.Entry mapEntry = ObjectUtils.cast(entry, Map.Entry.class);
final String key = ObjectUtils.cast(mapEntry.getKey(), String.class);
final String value = ObjectUtils.cast(mapEntry.getValue(), String.class);
result.putExtras(key, value);
}
}
return result;
}
/**
* Utility method
* @param map HashMap representation of the NavigationRequest object
* @return NavigationRequest object
*/
static NavigationRequest fromMapToNavigationRequest(final Map<String, Object> map) {
final int type = ValueGetter.getInt("type", map);
final Map extras = ObjectUtils.cast(map.get("extras"), Map.class);
final NavigationRequest request = new NavigationRequest(type);
request.setExtras(extras);
return request;
}
/**
* Utility method
* @param map HashMap representation of the Location object
* @return Location object
*/
static Location fromMapToLocation(final Map<String, Object> map) {
final String provider = ValueGetter.getString("provider", map);
final Location location = new Location(provider);
location.setLatitude(ValueGetter.getDouble("latitude", map));
location.setLongitude(ValueGetter.getDouble("longitude", map));
location.setAltitude(ValueGetter.getDouble("altitude", map));
location.setSpeed(ValueGetter.getFloat("speed", map));
location.setBearing(ValueGetter.getFloat("bearing", map));
location.setAccuracy(ValueGetter.getFloat("horizontalAccuracyMeters", map));
location.setTime(ValueGetter.getLong("time", map));
location.setElapsedRealtimeNanos(ValueGetter.getLong("elapsedRealtimeNanos", map));
if (VERSION.SDK_INT >= VERSION_CODES.O) {
location.setVerticalAccuracyMeters(ValueGetter.getFloat("verticalAccuracyMeters", map));
location.setSpeedAccuracyMetersPerSecond(ValueGetter.getFloat("speedAccuracyMetersPerSecond", map));
location.setBearingAccuracyDegrees(ValueGetter.getFloat("bearingAccuracyDegrees", map));
}
return location;
}
/**
* Utility method
* @param map HashMap representation of the LocationSettingsRequest object
* @return LocationSettingsRequest object
*/
static LocationSettingsRequest fromMapToLocationSettingsRequest(final Map<String, Object> map) {
final LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
final List requests = ObjectUtils.cast(map.get("requests"), List.class);
if (requests != null) {
for (final Object request : requests) {
final Map requestMap = ObjectUtils.cast(request, Map.class);
builder.addLocationRequest(fromMapToLocationRequest(requestMap));
}
}
builder.setAlwaysShow(ValueGetter.getBoolean("alwaysShow", map));
builder.setNeedBle(ValueGetter.getBoolean("needBle", map));
return builder.build();
}
}

@ -0,0 +1,31 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.utils;
public interface ObjectUtils {
/**
* Utility method that castes given object to given class type
* @param source Source object to be casted
* @param clazz Class that object will be casted to its type
* @param <S> Source object's type
* @param <D> Destination type
* @return Object that casted to D type
*/
static <S, D> D cast(final S source, final Class<D> clazz) {
return clazz.cast(source);
}
}

@ -0,0 +1,112 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.huawei.hms.flutter.location.utils;
import java.util.Map;
import java.util.Objects;
public interface ValueGetter {
/**
* Utility method
* @param key Lookup key for the map
* @param map Map that contains argument keys and values
* @return The "int" value for the corresponding key.
*/
static int getInt(final String key, final Map map) {
final Object value = Objects.requireNonNull(map.get(key));
if (value instanceof Number) {
return ((Number) value).intValue();
} else {
throw new IllegalArgumentException();
}
}
/**
* Utility method
* @param key Lookup key for the map
* @param map Map that contains argument keys and values
* @return The "long" value for the corresponding key.
*/
static long getLong(final String key, final Map map) {
final Object value = Objects.requireNonNull(map.get(key));
if (value instanceof Number) {
return ((Number) value).longValue();
} else {
throw new IllegalArgumentException();
}
}
/**
* Utility method
* @param key Lookup key for the map
* @param map Map that contains argument keys and values
* @return The "float" value for the corresponding key.
*/
static float getFloat(final String key, final Map map) {
final Object value = Objects.requireNonNull(map.get(key));
if (value instanceof Number) {
return ((Number) value).floatValue();
} else {
throw new IllegalArgumentException();
}
}
/**
* Utility method
* @param key Lookup key for the map
* @param map Map that contains argument keys and values
* @return The "double" value for the corresponding key.
*/
static double getDouble(final String key, final Map map) {
final Object value = Objects.requireNonNull(map.get(key));
if (value instanceof Number) {
return ((Number) value).doubleValue();
} else {
throw new IllegalArgumentException();
}
}
/**
* Utility method
* @param key Lookup key for the map
* @param map Map that contains argument keys and values
* @return The "boolean" value for the corresponding key.
*/
static boolean getBoolean(final String key, final Map map) {
final Object value = Objects.requireNonNull(map.get(key));
if (value instanceof Boolean) {
return (boolean) value;
} else {
throw new IllegalArgumentException();
}
}
/**
* Utility method
* @param key Lookup key for the map
* @param map Map that contains argument keys and values
* @return The "String" value for the corresponding key.
*/
static String getString(final String key, final Map map) {
final Object value = Objects.requireNonNull(map.get(key));
if (value instanceof String) {
return (String) value;
} else {
throw new IllegalArgumentException();
}
}
}

@ -0,0 +1,4 @@
#import <Flutter/Flutter.h>
@interface LocationPlugin : NSObject<FlutterPlugin>
@end

@ -0,0 +1,20 @@
#import "LocationPlugin.h"
@implementation LocationPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"location"
binaryMessenger:[registrar messenger]];
LocationPlugin* instance = [[LocationPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"getPlatformVersion" isEqualToString:call.method]) {
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
} else {
result(FlutterMethodNotImplemented);
}
}
@end

@ -0,0 +1,23 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint location.podspec' to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'huawei_location'
s.version = '5.0.0+301'
s.summary = 'HUAWEI Flutter Location Kit plugin.'
s.description = <<-DESC
HUAWEI Flutter Location Kit plugin combines the GPS, Wi-Fi and base station locations to help you quickly obtain precise user locations & build up global positioning capabilities.
DESC
s.homepage = 'https://www.huawei.com'
s.license = { :type => 'Apache 2.0', :file => '../LICENSE' }
s.author = { 'Huawei Technologies' => 'huaweideveloper1@gmail.com' }
s.source = { :git => 'https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-location' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.platform = :ios, '8.0'
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
end

@ -0,0 +1,76 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
class ActivityConversionData {
int activityType;
int conversionType;
int elapsedTimeFromReboot;
ActivityConversionData({
this.activityType,
this.conversionType,
this.elapsedTimeFromReboot,
});
Map<String, dynamic> toMap() {
return {
'activityType': activityType,
'conversionType': conversionType,
'elapsedTimeFromReboot': elapsedTimeFromReboot,
};
}
factory ActivityConversionData.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return ActivityConversionData(
activityType: map['activityType'],
conversionType: map['conversionType'],
elapsedTimeFromReboot: map['elapsedTimeFromReboot'],
);
}
String toJson() => json.encode(toMap());
factory ActivityConversionData.fromJson(String source) =>
ActivityConversionData.fromMap(json.decode(source));
@override
String toString() =>
'ActivityConversionData(activityType: $activityType, conversionType: $conversionType, elapsedTimeFromReboot: $elapsedTimeFromReboot)';
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is ActivityConversionData &&
o.activityType == activityType &&
o.conversionType == conversionType &&
o.elapsedTimeFromReboot == elapsedTimeFromReboot;
}
@override
int get hashCode {
return hashList([
activityType,
conversionType,
elapsedTimeFromReboot,
]);
}
}

@ -0,0 +1,73 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
class ActivityConversionInfo {
static const int ENTER_ACTIVITY_CONVERSION = 0;
static const int EXIT_ACTIVITY_CONVERSION = 1;
int activityType;
int conversionType;
ActivityConversionInfo({
this.activityType,
this.conversionType,
});
Map<String, dynamic> toMap() {
return {
'activityType': activityType,
'conversionType': conversionType,
};
}
factory ActivityConversionInfo.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return ActivityConversionInfo(
activityType: map['activityType'],
conversionType: map['conversionType'],
);
}
String toJson() => json.encode(toMap());
factory ActivityConversionInfo.fromJson(String source) =>
ActivityConversionInfo.fromMap(json.decode(source));
@override
String toString() =>
'ActivityConversionInfo(activityType: $activityType, conversionType: $conversionType)';
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is ActivityConversionInfo &&
o.activityType == activityType &&
o.conversionType == conversionType;
}
@override
int get hashCode {
return hashList([
activityType,
conversionType,
]);
}
}

@ -0,0 +1,71 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'activity_conversion_data.dart';
class ActivityConversionResponse {
List<ActivityConversionData> activityConversionDatas;
ActivityConversionResponse({
this.activityConversionDatas,
});
Map<String, dynamic> toMap() {
return {
'activityConversionDatas':
activityConversionDatas?.map((x) => x?.toMap())?.toList(),
};
}
factory ActivityConversionResponse.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return ActivityConversionResponse(
activityConversionDatas: List<ActivityConversionData>.from(
map['activityConversionDatas']
?.map((x) => ActivityConversionData.fromMap(x))),
);
}
String toJson() => json.encode(toMap());
factory ActivityConversionResponse.fromJson(String source) =>
ActivityConversionResponse.fromMap(json.decode(source));
@override
String toString() =>
'ActivityConversionResponse(activityConversionDatas: $activityConversionDatas)';
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is ActivityConversionResponse &&
listEquals(o.activityConversionDatas, activityConversionDatas);
}
@override
int get hashCode {
return hashList([
activityConversionDatas,
]);
}
}

@ -0,0 +1,94 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
class ActivityIdentificationData {
static const int VEHICLE = 100;
static const int BIKE = 101;
static const int FOOT = 102;
static const int STILL = 103;
static const int OTHERS = 104;
static const int TILTING = 105;
static const int WALKING = 107;
static const int RUNNING = 108;
static const List<int> _validTypes = <int>[
VEHICLE,
BIKE,
FOOT,
STILL,
OTHERS,
TILTING,
WALKING,
RUNNING
];
int identificationActivity;
int possibility;
ActivityIdentificationData({
this.identificationActivity,
this.possibility,
});
static bool isValidType(int type) {
return _validTypes.contains(type) ? true : false;
}
Map<String, dynamic> toMap() {
return {
'identificationActivity': identificationActivity,
'possibility': possibility,
};
}
factory ActivityIdentificationData.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return ActivityIdentificationData(
identificationActivity: map['identificationActivity'],
possibility: map['possibility'],
);
}
String toJson() => json.encode(toMap());
factory ActivityIdentificationData.fromJson(String source) =>
ActivityIdentificationData.fromMap(json.decode(source));
@override
String toString() =>
'ActivityIdentificationData(identificationActivity: $identificationActivity, possibility: $possibility)';
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is ActivityIdentificationData &&
o.identificationActivity == identificationActivity &&
o.possibility == possibility;
}
@override
int get hashCode {
return hashList([
identificationActivity,
possibility,
]);
}
}

@ -0,0 +1,106 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'activity_identification_data.dart';
class ActivityIdentificationResponse {
int time;
int elapsedTimeFromReboot;
List<ActivityIdentificationData> activityIdentificationDatas;
ActivityIdentificationResponse({
this.activityIdentificationDatas,
this.time,
this.elapsedTimeFromReboot,
});
ActivityIdentificationData get mostActivityIdentification {
return activityIdentificationDatas != null &&
activityIdentificationDatas.length > 0
? activityIdentificationDatas[0]
: null;
}
int getActivityPossibility(int activityType) {
if (activityIdentificationDatas != null &&
activityIdentificationDatas.length > 0) {
Iterator iterator = activityIdentificationDatas.iterator;
while (iterator.moveNext()) {
ActivityIdentificationData currentData = iterator.current;
if (currentData.identificationActivity == activityType) {
return currentData.possibility;
}
}
}
return 0;
}
Map<String, dynamic> toMap() {
return {
'time': time,
'elapsedTimeFromReboot': elapsedTimeFromReboot,
'activityIdentificationDatas':
activityIdentificationDatas?.map((x) => x?.toMap())?.toList(),
};
}
factory ActivityIdentificationResponse.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return ActivityIdentificationResponse(
time: map['time'],
elapsedTimeFromReboot: map['elapsedTimeFromReboot'],
activityIdentificationDatas: List<ActivityIdentificationData>.from(
map['activityIdentificationDatas']
?.map((x) => ActivityIdentificationData.fromMap(x))),
);
}
String toJson() => json.encode(toMap());
factory ActivityIdentificationResponse.fromJson(String source) =>
ActivityIdentificationResponse.fromMap(json.decode(source));
@override
String toString() =>
'ActivityIdentificationResponse(time: $time, elapsedTimeFromReboot: $elapsedTimeFromReboot, activityIdentificationDatas: $activityIdentificationDatas)';
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is ActivityIdentificationResponse &&
o.time == time &&
o.elapsedTimeFromReboot == elapsedTimeFromReboot &&
listEquals(o.activityIdentificationDatas, activityIdentificationDatas);
}
@override
int get hashCode {
return hashList([
time,
elapsedTimeFromReboot,
activityIdentificationDatas,
]);
}
}

@ -0,0 +1,98 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'package:flutter/services.dart';
import 'activity_conversion_info.dart';
import 'activity_conversion_response.dart';
import 'activity_identification_response.dart';
class ActivityIdentificationService {
static ActivityIdentificationService _instance;
final MethodChannel _methodChannel;
final EventChannel _activityIdentificationEventChannel;
final EventChannel _activityConversionEventChannel;
Stream<ActivityIdentificationResponse> _onActivityIdentification;
Stream<ActivityConversionResponse> _onActivityConversion;
ActivityIdentificationService._create(
this._methodChannel,
this._activityIdentificationEventChannel,
this._activityConversionEventChannel,
);
factory ActivityIdentificationService() {
if (_instance == null) {
final MethodChannel methodChannel = const MethodChannel(
'com.huawei.flutter.location/activityidentification_methodchannel');
final EventChannel activityIdentificationEventChannel = const EventChannel(
'com.huawei.flutter.location/activityidentification_eventchannel');
final EventChannel activityConversionEventChannel = const EventChannel(
'com.huawei.flutter.location/activityconversion_eventchannel');
_instance = ActivityIdentificationService._create(
methodChannel,
activityIdentificationEventChannel,
activityConversionEventChannel,
);
}
return _instance;
}
Future<int> createActivityIdentificationUpdates(
int detectionIntervalMillis) async {
return _methodChannel.invokeMethod<int>(
'createActivityIdentificationUpdates', detectionIntervalMillis);
}
Future<int> createActivityConversionUpdates(
List<ActivityConversionInfo> activityConversions) async {
return _methodChannel.invokeMethod<int>('createActivityConversionUpdates',
activityConversions?.map((x) => x?.toMap())?.toList());
}
Future<void> deleteActivityIdentificationUpdates(int requestCode) async {
return _methodChannel.invokeMethod<void>(
'deleteActivityIdentificationUpdates', requestCode);
}
Future<void> deleteActivityConversionUpdates(int requestCode) async {
return _methodChannel.invokeMethod<void>(
'deleteActivityConversionUpdates', requestCode);
}
Stream<ActivityIdentificationResponse> get onActivityIdentification {
if (_onActivityIdentification == null) {
_onActivityIdentification = _activityIdentificationEventChannel
.receiveBroadcastStream()
.map((event) => ActivityIdentificationResponse.fromMap(event));
}
return _onActivityIdentification;
}
Stream<ActivityConversionResponse> get onActivityConversion {
if (_onActivityConversion == null) {
_onActivityConversion = _activityConversionEventChannel
.receiveBroadcastStream()
.map((event) => ActivityConversionResponse.fromMap(event));
}
return _onActivityConversion;
}
}

@ -0,0 +1,113 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:core';
import 'dart:ui';
class Geofence {
static const int ENTER_GEOFENCE_CONVERSION = 1;
static const int EXIT_GEOFENCE_CONVERSION = 2;
static const int DWELL_GEOFENCE_CONVERSION = 4;
static const int GEOFENCE_NEVER_EXPIRE = -1;
String uniqueId;
int conversions;
int validDuration;
double latitude;
double longitude;
double radius;
int notificationInterval;
int dwellDelayTime;
Geofence({
this.uniqueId,
this.conversions,
this.validDuration,
this.latitude,
this.longitude,
this.radius,
this.notificationInterval = 0,
this.dwellDelayTime = 0,
});
Map<String, dynamic> toMap() {
return {
'uniqueId': uniqueId,
'conversions': conversions,
'validDuration': validDuration,
'latitude': latitude,
'longitude': longitude,
'radius': radius,
'notificationInterval': notificationInterval,
'dwellDelayTime': dwellDelayTime,
};
}
factory Geofence.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return Geofence(
uniqueId: map['uniqueId'],
conversions: map['conversions'],
validDuration: map['validDuration'],
latitude: map['latitude'],
longitude: map['longitude'],
radius: map['radius'],
notificationInterval: map['notificationInterval'],
dwellDelayTime: map['dwellDelayTime'],
);
}
String toJson() => json.encode(toMap());
factory Geofence.fromJson(String source) =>
Geofence.fromMap(json.decode(source));
@override
String toString() {
return 'Geofence(uniqueId: $uniqueId, conversions: $conversions, validDuration: $validDuration, latitude: $latitude, longitude: $longitude, radius: $radius, notificationInterval: $notificationInterval, dwellDelayTime: $dwellDelayTime)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is Geofence &&
o.uniqueId == uniqueId &&
o.conversions == conversions &&
o.validDuration == validDuration &&
o.latitude == latitude &&
o.longitude == longitude &&
o.radius == radius &&
o.notificationInterval == notificationInterval &&
o.dwellDelayTime == dwellDelayTime;
}
@override
int get hashCode {
return hashList([
uniqueId,
conversions,
validDuration,
latitude,
longitude,
radius,
notificationInterval,
dwellDelayTime,
]);
}
}

@ -0,0 +1,88 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import '../location/location.dart';
class GeofenceData {
int errorCode;
int conversion;
List<String> convertingGeofenceIdList;
Location convertingLocation;
GeofenceData({
this.errorCode,
this.conversion,
this.convertingGeofenceIdList,
this.convertingLocation,
});
Map<String, dynamic> toMap() {
return {
'errorCode': errorCode,
'conversion': conversion,
'convertingGeofenceIdList': convertingGeofenceIdList,
'convertingLocation': convertingLocation?.toMap(),
};
}
factory GeofenceData.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return GeofenceData(
errorCode: map['errorCode'],
conversion: map['conversion'],
convertingGeofenceIdList:
List<String>.from(map['convertingGeofenceIdList']),
convertingLocation: Location.fromMap(map['convertingLocation']),
);
}
String toJson() => json.encode(toMap());
factory GeofenceData.fromJson(String source) =>
GeofenceData.fromMap(json.decode(source));
@override
String toString() {
return 'GeofenceData(errorCode: $errorCode, conversion: $conversion, convertingGeofenceIdList: $convertingGeofenceIdList, convertingLocation: $convertingLocation)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is GeofenceData &&
o.errorCode == errorCode &&
o.conversion == conversion &&
listEquals(o.convertingGeofenceIdList, convertingGeofenceIdList) &&
o.convertingLocation == convertingLocation;
}
@override
int get hashCode {
return hashList([
errorCode,
conversion,
convertingGeofenceIdList,
convertingLocation,
]);
}
}

@ -0,0 +1,91 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'geofence.dart';
class GeofenceRequest {
static const int ENTER_INIT_CONVERSION = 1;
static const int EXIT_INIT_CONVERSION = 2;
static const int DWELL_INIT_CONVERSION = 4;
static const int COORDINATE_TYPE_WGS_84 = 1;
static const int COORDINATE_TYPE_GCJ_02 = 0;
List<Geofence> geofenceList;
int initConversions;
int coordinateType;
GeofenceRequest({
this.geofenceList,
this.initConversions = ENTER_INIT_CONVERSION | DWELL_INIT_CONVERSION,
this.coordinateType = COORDINATE_TYPE_WGS_84,
}) {
if (this.geofenceList == null) {
this.geofenceList = <Geofence>[];
}
}
Map<String, dynamic> toMap() {
return {
'geofenceList': geofenceList?.map((x) => x?.toMap())?.toList(),
'initConversions': initConversions,
'coordinateType': coordinateType,
};
}
factory GeofenceRequest.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return GeofenceRequest(
geofenceList: List<Geofence>.from(
map['geofenceList']?.map((x) => Geofence.fromMap(x))),
initConversions: map['initConversions'],
coordinateType: map['coordinateType'],
);
}
String toJson() => json.encode(toMap());
factory GeofenceRequest.fromJson(String source) =>
GeofenceRequest.fromMap(json.decode(source));
@override
String toString() =>
'GeofenceRequest(geofenceList: $geofenceList, initConversions: $initConversions, coordinateType: $coordinateType)';
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is GeofenceRequest &&
listEquals(o.geofenceList, geofenceList) &&
o.initConversions == initConversions &&
o.coordinateType == coordinateType;
}
@override
int get hashCode {
return hashList([
geofenceList,
initConversions,
coordinateType,
]);
}
}

@ -0,0 +1,72 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'package:flutter/services.dart';
import 'geofence_data.dart' show GeofenceData;
import 'geofence_request.dart' show GeofenceRequest;
class GeofenceService {
static GeofenceService _instance;
final MethodChannel _methodChannel;
final EventChannel _eventChannel;
Stream<GeofenceData> _onGeofenceData;
GeofenceService._create(
this._methodChannel,
this._eventChannel,
);
factory GeofenceService() {
if (_instance == null) {
final MethodChannel methodChannel = const MethodChannel(
'com.huawei.flutter.location/geofence_methodchannel');
final EventChannel eventChannel = const EventChannel(
'com.huawei.flutter.location/geofence_eventchannel');
_instance = GeofenceService._create(
methodChannel,
eventChannel,
);
}
return _instance;
}
Future<int> createGeofenceList(GeofenceRequest geofenceRequest) async {
return _methodChannel.invokeMethod<int>(
'createGeofenceList', geofenceRequest.toMap());
}
Future<void> deleteGeofenceList(int requestCode) async {
return _methodChannel.invokeMethod<void>('deleteGeofenceList', requestCode);
}
Future<void> deleteGeofenceListWithIds(List<String> geofenceIds) async {
return _methodChannel.invokeMethod<void>(
'deleteGeofenceListWithIds', geofenceIds);
}
Stream<GeofenceData> get onGeofenceData {
if (_onGeofenceData == null) {
_onGeofenceData = _eventChannel
.receiveBroadcastStream()
.map((event) => GeofenceData.fromMap(event));
}
return _onGeofenceData;
}
}

@ -0,0 +1,158 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'package:flutter/services.dart';
import 'hwlocation.dart';
import 'location.dart';
import 'location_availability.dart';
import 'location_callback.dart';
import 'location_request.dart';
import 'location_result.dart';
import 'location_settings_request.dart';
import 'location_settings_states.dart';
import 'navigation_request.dart';
import 'navigation_result.dart';
class FusedLocationProviderClient {
static FusedLocationProviderClient _instance;
final MethodChannel _methodChannel;
final EventChannel _eventChannel;
final Map<int, LocationCallback> _callbacks;
Stream<Location> _onLocationData;
FusedLocationProviderClient._create(
this._methodChannel,
this._eventChannel,
this._callbacks,
) {
_methodChannel.setMethodCallHandler(_methodCallHandler);
}
factory FusedLocationProviderClient() {
if (_instance == null) {
_instance = FusedLocationProviderClient._create(
const MethodChannel(
'com.huawei.flutter.location/fusedlocation_methodchannel'),
const EventChannel(
'com.huawei.flutter.location/fusedlocation_eventchannel'),
<int, LocationCallback>{},
);
}
return _instance;
}
Future<void> _methodCallHandler(MethodCall methodCall) async {
switch (methodCall.method) {
case 'onLocationResult':
_callbacks[methodCall.arguments['callbackId']].onLocationResult(
LocationResult.fromMap(methodCall.arguments['locationResult']));
break;
case 'onLocationAvailability':
_callbacks[methodCall.arguments['callbackId']].onLocationAvailability(
LocationAvailability.fromMap(
methodCall.arguments['locationAvailability']));
break;
default:
break;
}
}
Future<LocationSettingsStates> checkLocationSettings(
LocationSettingsRequest locationSettingsRequest) async {
return LocationSettingsStates.fromMap(
await _methodChannel.invokeMapMethod<String, dynamic>(
'checkLocationSettings', locationSettingsRequest.toMap()));
}
Future<Location> getLastLocation() async {
return Location.fromMap(await _methodChannel
.invokeMapMethod<String, dynamic>('getLastLocation'));
}
Future<HWLocation> getLastLocationWithAddress(
LocationRequest locationRequest) async {
return HWLocation.fromMap(
await _methodChannel.invokeMapMethod<String, dynamic>(
'getLastLocationWithAddress', locationRequest.toMap()));
}
Future<LocationAvailability> getLocationAvailability() async {
return LocationAvailability.fromMap(await _methodChannel
.invokeMapMethod<String, dynamic>('getLocationAvailability'));
}
Future<void> setMockMode(bool mockMode) async {
return _methodChannel.invokeMethod<void>('setMockMode', mockMode);
}
Future<void> setMockLocation(Location location) async {
return _methodChannel.invokeMethod<void>(
'setMockLocation', location.toMap());
}
Future<int> requestLocationUpdates(LocationRequest locationRequest) async {
return _methodChannel.invokeMethod<int>(
'requestLocationUpdates', locationRequest.toMap());
}
Future<int> requestLocationUpdatesCb(LocationRequest locationRequest,
LocationCallback locationCallback) async {
int callbackId = await _methodChannel.invokeMethod<int>(
'requestLocationUpdatesCb', locationRequest.toMap());
_callbacks.putIfAbsent(callbackId, () => locationCallback);
return callbackId;
}
Future<int> requestLocationUpdatesExCb(LocationRequest locationRequest,
LocationCallback locationCallback) async {
int callbackId = await _methodChannel.invokeMethod<int>(
'requestLocationUpdatesExCb',
(locationRequest..priority = LocationRequest.PRIORITY_HD_ACCURACY)
.toMap());
_callbacks.putIfAbsent(callbackId, () => locationCallback);
return callbackId;
}
Future<void> removeLocationUpdates(int requestCode) async {
return _methodChannel.invokeMethod<void>(
'removeLocationUpdates', requestCode);
}
Future<void> removeLocationUpdatesCb(int callbackId) async {
await _methodChannel.invokeMethod<void>(
'removeLocationUpdatesCb', callbackId);
_callbacks.remove(callbackId);
}
Future<NavigationResult> getNavigationContextState(
NavigationRequest navigationRequest) async {
return NavigationResult.fromMap(
await _methodChannel.invokeMapMethod<String, dynamic>(
'getNavigationContextState', navigationRequest.toMap()));
}
Stream<Location> get onLocationData {
if (_onLocationData == null) {
_onLocationData = _eventChannel
.receiveBroadcastStream()
.map((event) => Location.fromMap(event));
}
return _onLocationData;
}
}

@ -0,0 +1,207 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
class HWLocation {
String provider;
double latitude;
double longitude;
double altitude;
double speed;
double bearing;
double horizontalAccuracyMeters;
double verticalAccuracyMeters;
double speedAccuracyMetersPerSecond;
double bearingAccuracyDegrees;
int time;
int elapsedRealtimeNanos;
String countryCode;
String countryName;
String state;
String city;
String county;
String street;
String featureName;
String postalCode;
String phone;
String url;
Map<String, dynamic> extraInfo;
HWLocation({
this.provider,
this.latitude,
this.longitude,
this.altitude,
this.speed,
this.bearing,
this.horizontalAccuracyMeters,
this.verticalAccuracyMeters,
this.speedAccuracyMetersPerSecond,
this.bearingAccuracyDegrees,
this.time,
this.elapsedRealtimeNanos,
this.countryCode,
this.countryName,
this.state,
this.city,
this.county,
this.street,
this.featureName,
this.postalCode,
this.phone,
this.url,
this.extraInfo,
});
Map<String, dynamic> toMap() {
return {
'provider': provider,
'latitude': latitude,
'longitude': longitude,
'altitude': altitude,
'speed': speed,
'bearing': bearing,
'horizontalAccuracyMeters': horizontalAccuracyMeters,
'verticalAccuracyMeters': verticalAccuracyMeters,
'speedAccuracyMetersPerSecond': speedAccuracyMetersPerSecond,
'bearingAccuracyDegrees': bearingAccuracyDegrees,
'time': time,
'elapsedRealtimeNanos': elapsedRealtimeNanos,
'countryCode': countryCode,
'countryName': countryName,
'state': state,
'city': city,
'county': county,
'street': street,
'featureName': featureName,
'postalCode': postalCode,
'phone': phone,
'url': url,
'extraInfo': extraInfo,
};
}
factory HWLocation.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return HWLocation(
provider: map["provider"] == null ? null : map["provider"],
latitude: map["latitude"] == null ? null : map["latitude"],
longitude: map["longitude"] == null ? null : map["longitude"],
altitude: map["altitude"] == null ? null : map["altitude"],
speed: map["speed"] == null ? null : map["speed"],
bearing: map["bearing"] == null ? null : map["bearing"],
horizontalAccuracyMeters: map["horizontalAccuracyMeters"],
verticalAccuracyMeters: map["verticalAccuracyMeters"] == null
? null
: map["verticalAccuracyMeters"],
speedAccuracyMetersPerSecond:
map["speedAccuracyMetersPerSecond"] == null
? null
: map["speedAccuracyMetersPerSecond"],
bearingAccuracyDegrees: map["bearingAccuracyDegrees"] == null
? null
: map["bearingAccuracyDegrees"],
time: map["time"] == null ? null : map["time"],
elapsedRealtimeNanos: map["elapsedRealtimeNanos"] == null
? null
: map["elapsedRealtimeNanos"],
countryCode: map["countryCode"] == null ? null : map["countryCode"],
countryName: map["countryName"] == null ? null : map["countryName"],
state: map["state"] == null ? null : map["state"],
city: map["city"] == null ? null : map["city"],
county: map["county"] == null ? null : map["county"],
street: map["street"] == null ? null : map["street"],
featureName: map["featureName"] == null ? null : map["featureName"],
postalCode: map["postalCode"] == null ? null : map["postalCode"],
phone: map["phone"] == null ? null : map["phone"],
url: map["url"] == null ? null : map["url"],
extraInfo:
map["extraInfo"] == null ? null : Map.from(map["extraInfo"]));
}
String toJson() => json.encode(toMap());
factory HWLocation.fromJson(String source) =>
HWLocation.fromMap(json.decode(source));
@override
String toString() {
return 'HWLocation(provider: $provider, latitude: $latitude, longitude: $longitude, altitude: $altitude, speed: $speed, bearing: $bearing, horizontalAccuracyMeters: $horizontalAccuracyMeters, verticalAccuracyMeters: $verticalAccuracyMeters, speedAccuracyMetersPerSecond: $speedAccuracyMetersPerSecond, bearingAccuracyDegrees: $bearingAccuracyDegrees, time: $time, elapsedRealtimeNanos: $elapsedRealtimeNanos, countryCode: $countryCode, countryName: $countryName, state: $state, city: $city, county: $county, street: $street, featureName: $featureName, postalCode: $postalCode, phone: $phone, url: $url, extraInfo: $extraInfo)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is HWLocation &&
o.provider == provider &&
o.latitude == latitude &&
o.longitude == longitude &&
o.altitude == altitude &&
o.speed == speed &&
o.bearing == bearing &&
o.horizontalAccuracyMeters == horizontalAccuracyMeters &&
o.verticalAccuracyMeters == verticalAccuracyMeters &&
o.speedAccuracyMetersPerSecond == speedAccuracyMetersPerSecond &&
o.bearingAccuracyDegrees == bearingAccuracyDegrees &&
o.time == time &&
o.elapsedRealtimeNanos == elapsedRealtimeNanos &&
o.countryCode == countryCode &&
o.countryName == countryName &&
o.state == state &&
o.city == city &&
o.county == county &&
o.street == street &&
o.featureName == featureName &&
o.postalCode == postalCode &&
o.phone == phone &&
o.url == url &&
mapEquals(o.extraInfo, extraInfo);
}
@override
int get hashCode {
return hashList([
provider,
latitude,
longitude,
altitude,
speed,
bearing,
horizontalAccuracyMeters,
verticalAccuracyMeters,
speedAccuracyMetersPerSecond,
bearingAccuracyDegrees,
time,
elapsedRealtimeNanos,
countryCode,
countryName,
state,
city,
county,
street,
featureName,
postalCode,
phone,
url,
extraInfo,
]);
}
}

@ -0,0 +1,141 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
class Location {
String provider;
double latitude;
double longitude;
double altitude;
double speed;
double bearing;
double horizontalAccuracyMeters;
double verticalAccuracyMeters;
double speedAccuracyMetersPerSecond;
double bearingAccuracyDegrees;
int time;
int elapsedRealtimeNanos;
Location({
this.provider = 'HMS Mock Location',
this.latitude = 0.0,
this.longitude = 0.0,
this.altitude = 0.0,
this.speed = 0.0,
this.bearing = 0.0,
this.horizontalAccuracyMeters = 0.0,
this.verticalAccuracyMeters = 0.0,
this.speedAccuracyMetersPerSecond = 0.0,
this.bearingAccuracyDegrees = 0.0,
this.time = 0,
this.elapsedRealtimeNanos = 0,
});
Map<String, dynamic> toMap() {
return {
'provider': provider,
'latitude': latitude,
'longitude': longitude,
'altitude': altitude,
'speed': speed,
'bearing': bearing,
'horizontalAccuracyMeters': horizontalAccuracyMeters,
'verticalAccuracyMeters': verticalAccuracyMeters,
'speedAccuracyMetersPerSecond': speedAccuracyMetersPerSecond,
'bearingAccuracyDegrees': bearingAccuracyDegrees,
'time': time,
'elapsedRealtimeNanos': elapsedRealtimeNanos,
};
}
factory Location.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return Location(
provider: map["provider"] == null ? null : map["provider"],
latitude: map["latitude"] == null ? null : map["latitude"],
longitude: map["longitude"] == null ? null : map["longitude"],
altitude: map["altitude"] == null ? null : map["altitude"],
speed: map["speed"] == null ? null : map["speed"],
bearing: map["bearing"] == null ? null : map["bearing"],
horizontalAccuracyMeters: map["horizontalAccuracyMeters"] == null
? null
: map["horizontalAccuracyMeters"],
verticalAccuracyMeters: map["verticalAccuracyMeters"] == null
? null
: map["verticalAccuracyMeters"],
speedAccuracyMetersPerSecond: map["speedAccuracyMetersPerSecond"] == null
? null
: map["speedAccuracyMetersPerSecond"],
bearingAccuracyDegrees: map["bearingAccuracyDegrees"] == null
? null
: map["bearingAccuracyDegrees"],
time: map["time"] == null ? null : map["time"],
elapsedRealtimeNanos: map["elapsedRealtimeNanos"] == null
? null
: map["elapsedRealtimeNanos"],
);
}
String toJson() => json.encode(toMap());
factory Location.fromJson(String source) =>
Location.fromMap(json.decode(source));
@override
String toString() {
return 'Location(provider: $provider, latitude: $latitude, longitude: $longitude, altitude: $altitude, speed: $speed, bearing: $bearing, horizontalAccuracyMeters: $horizontalAccuracyMeters, verticalAccuracyMeters: $verticalAccuracyMeters, speedAccuracyMetersPerSecond: $speedAccuracyMetersPerSecond, bearingAccuracyDegrees: $bearingAccuracyDegrees, time: $time, elapsedRealtimeNanos: $elapsedRealtimeNanos)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is Location &&
o.provider == provider &&
o.latitude == latitude &&
o.longitude == longitude &&
o.altitude == altitude &&
o.speed == speed &&
o.bearing == bearing &&
o.horizontalAccuracyMeters == horizontalAccuracyMeters &&
o.verticalAccuracyMeters == verticalAccuracyMeters &&
o.speedAccuracyMetersPerSecond == speedAccuracyMetersPerSecond &&
o.bearingAccuracyDegrees == bearingAccuracyDegrees &&
o.time == time &&
o.elapsedRealtimeNanos == elapsedRealtimeNanos;
}
@override
int get hashCode {
return hashList([
provider,
latitude,
longitude,
altitude,
speed,
bearing,
horizontalAccuracyMeters,
verticalAccuracyMeters,
speedAccuracyMetersPerSecond,
bearingAccuracyDegrees,
time,
elapsedRealtimeNanos,
]);
}
}

@ -0,0 +1,85 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
class LocationAvailability {
int cellStatus;
int wifiStatus;
int elapsedRealtimeNs;
int locationStatus;
LocationAvailability({
this.cellStatus,
this.wifiStatus,
this.elapsedRealtimeNs,
this.locationStatus,
});
bool get isLocationAvailable => locationStatus < 1000;
Map<String, dynamic> toMap() {
return {
'cellStatus': cellStatus,
'wifiStatus': wifiStatus,
'elapsedRealtimeNs': elapsedRealtimeNs,
'locationStatus': locationStatus,
};
}
factory LocationAvailability.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return LocationAvailability(
cellStatus: map['cellStatus'],
wifiStatus: map['wifiStatus'],
elapsedRealtimeNs: map['elapsedRealtimeNs'],
locationStatus: map['locationStatus'],
);
}
String toJson() => json.encode(toMap());
factory LocationAvailability.fromJson(String source) =>
LocationAvailability.fromMap(json.decode(source));
@override
String toString() {
return 'LocationAvailability(cellStatus: $cellStatus, wifiStatus: $wifiStatus, elapsedRealtimeNs: $elapsedRealtimeNs, locationStatus: $locationStatus)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is LocationAvailability &&
o.cellStatus == cellStatus &&
o.wifiStatus == wifiStatus &&
o.elapsedRealtimeNs == elapsedRealtimeNs &&
o.locationStatus == locationStatus;
}
@override
int get hashCode {
return hashList([
cellStatus,
wifiStatus,
elapsedRealtimeNs,
locationStatus,
]);
}
}

@ -0,0 +1,31 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'location_availability.dart';
import 'location_result.dart';
typedef void OnLocationResult(LocationResult locationResult);
typedef void OnLocationAvailability(LocationAvailability locationAvailability);
class LocationCallback {
OnLocationResult onLocationResult;
OnLocationAvailability onLocationAvailability;
LocationCallback({
this.onLocationResult,
this.onLocationAvailability,
});
}

@ -0,0 +1,231 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
class LocationRequest {
static const int PRIORITY_HIGH_ACCURACY = 100;
static const int PRIORITY_BALANCED_POWER_ACCURACY = 102;
static const int PRIORITY_LOW_POWER = 104;
static const int PRIORITY_NO_POWER = 105;
static const int PRIORITY_HD_ACCURACY = 200;
static const double _FASTEST_INTERVAL_FACTOR = 6.0;
int _priority;
int _interval;
int _fastestInterval;
bool _isFastestIntervalExplicitlySet;
int _expirationTime;
int _numUpdates;
double _smallestDisplacement;
int _maxWaitTime;
bool needAddress;
String language;
String countryCode;
Map<String, String> extras;
LocationRequest._create(
this._priority,
this._interval,
this._fastestInterval,
this._isFastestIntervalExplicitlySet,
this._expirationTime,
this._numUpdates,
this._smallestDisplacement,
this._maxWaitTime,
this.needAddress,
this.language,
this.countryCode,
this.extras,
);
LocationRequest() {
_priority = PRIORITY_BALANCED_POWER_ACCURACY;
_interval = 3600000;
_fastestInterval = (_interval ~/ _FASTEST_INTERVAL_FACTOR);
_isFastestIntervalExplicitlySet = false;
_expirationTime = 9223372036854775807;
_numUpdates = 2147483647;
_smallestDisplacement = 0.0;
_maxWaitTime = 0;
needAddress = false;
language = '';
countryCode = '';
}
int get priority => _priority;
set priority(int value) {
if (value == PRIORITY_HIGH_ACCURACY ||
value == PRIORITY_BALANCED_POWER_ACCURACY ||
value == PRIORITY_LOW_POWER ||
value == PRIORITY_NO_POWER ||
value == PRIORITY_HD_ACCURACY) {
_priority = value;
} else {
throw ArgumentError('Priority is not a known constant');
}
}
int get interval => _interval;
set interval(int value) {
if (value.isNegative) {
throw ArgumentError('Interval is invalid');
} else {
_interval = value;
_fastestInterval = _isFastestIntervalExplicitlySet
? _fastestInterval
: (_interval ~/ _FASTEST_INTERVAL_FACTOR);
}
}
int get fastestInterval => _fastestInterval;
set fastestInterval(int value) {
if (value.isNegative) {
throw ArgumentError('FastestInterval is invalid');
} else {
_isFastestIntervalExplicitlySet = true;
_fastestInterval = value;
}
}
bool get isFastestIntervalExplicitlySet => _isFastestIntervalExplicitlySet;
int get expirationTime => _expirationTime;
set expirationTime(int value) {
_expirationTime = value.isNegative ? 0 : value;
}
int get numUpdates => _numUpdates;
set numUpdates(int value) {
if (value <= 0) {
throw ArgumentError('numUpdates is invalid');
} else {
_numUpdates = value;
}
}
double get smallestDisplacement => _smallestDisplacement;
set smallestDisplacement(double value) {
if (value.isNegative) {
throw ArgumentError('smallestDisplacement param invalid');
} else {
_smallestDisplacement = value;
}
}
int get maxWaitTime => _maxWaitTime < _interval ? _interval : _maxWaitTime;
set maxWaitTime(int value) => _maxWaitTime = value;
void putExtras(String key, String value) {
if (extras == null) {
extras = Map<String, String>();
}
extras.putIfAbsent(key, () => value);
}
Map<String, dynamic> toMap() {
return {
'priority': _priority,
'interval': _interval,
'fastestInterval': _fastestInterval,
'isFastestIntervalExplicitlySet': _isFastestIntervalExplicitlySet,
'expirationTime': _expirationTime,
'numUpdates': _numUpdates,
'smallestDisplacement': _smallestDisplacement,
'maxWaitTime': _maxWaitTime,
'needAddress': needAddress,
'language': language,
'countryCode': countryCode,
'extras': extras,
};
}
factory LocationRequest.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return LocationRequest._create(
map['priority'],
map['interval'],
map['fastestInterval'],
map['isFastestIntervalExplicitlySet'],
map['expirationTime'],
map['numUpdates'],
map['smallestDisplacement'],
map['maxWaitTime'],
map['needAddress'],
map['language'],
map['countryCode'],
Map<String, String>.from(map['extras']),
);
}
String toJson() => json.encode(toMap());
factory LocationRequest.fromJson(String source) =>
LocationRequest.fromMap(json.decode(source));
@override
String toString() {
return 'LocationRequest(_priority: $_priority, _interval: $_interval, _fastestInterval: $_fastestInterval, _isFastestIntervalExplicitlySet: $_isFastestIntervalExplicitlySet, _expirationTime: $_expirationTime, _numUpdates: $_numUpdates, _smallestDisplacement: $_smallestDisplacement, _maxWaitTime: $_maxWaitTime, _needAddress: $needAddress, _language: $language, _countryCode: $countryCode, _extras: $extras)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is LocationRequest &&
o._priority == _priority &&
o._interval == _interval &&
o._fastestInterval == _fastestInterval &&
o._isFastestIntervalExplicitlySet == _isFastestIntervalExplicitlySet &&
o._expirationTime == _expirationTime &&
o._numUpdates == _numUpdates &&
o._smallestDisplacement == _smallestDisplacement &&
o._maxWaitTime == _maxWaitTime &&
o.needAddress == needAddress &&
o.language == language &&
o.countryCode == countryCode &&
mapEquals(o.extras, extras);
}
@override
int get hashCode {
return hashList([
_priority,
_interval,
_fastestInterval,
_isFastestIntervalExplicitlySet,
_expirationTime,
_numUpdates,
_smallestDisplacement,
_maxWaitTime,
needAddress,
language,
countryCode,
extras,
]);
}
}

@ -0,0 +1,98 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'hwlocation.dart' show HWLocation;
import 'location.dart' show Location;
class LocationResult {
List<Location> locations;
List<HWLocation> hwLocations;
Location lastLocation;
HWLocation lastHWLocation;
LocationResult({
this.locations,
this.hwLocations,
this.lastLocation,
this.lastHWLocation,
});
Map<String, dynamic> toMap() {
return {
'locations': locations?.map((x) => x?.toMap())?.toList(),
'hwLocations': hwLocations?.map((x) => x?.toMap())?.toList(),
'lastLocation': lastLocation?.toMap(),
'lastHWLocation': lastHWLocation?.toMap(),
};
}
factory LocationResult.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return LocationResult(
locations: map["locations"] == null
? null
: List<Location>.from(
map["locations"].map((x) => Location.fromMap(x))),
hwLocations: map["hwLocations"] == null
? null
: List<HWLocation>.from(
map["hwLocations"].map((x) => HWLocation.fromMap(x))),
lastLocation: map["lastLocation"] == null
? null
: Location.fromMap(map["lastLocation"]),
lastHWLocation: map["lastHWLocation"] == null
? null
: HWLocation.fromMap(map["lastHWLocation"]),
);
}
String toJson() => json.encode(toMap());
factory LocationResult.fromJson(String source) =>
LocationResult.fromMap(json.decode(source));
@override
String toString() {
return 'LocationResult(locations: $locations, hwLocations: $hwLocations, lastLocation: $lastLocation, lastHWLocation: $lastHWLocation)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is LocationResult &&
listEquals(o.locations, locations) &&
listEquals(o.hwLocations, hwLocations) &&
o.lastLocation == lastLocation &&
o.lastHWLocation == lastHWLocation;
}
@override
int get hashCode {
return hashList([
locations,
hwLocations,
lastLocation,
lastHWLocation,
]);
}
}

@ -0,0 +1,81 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'location_request.dart';
class LocationSettingsRequest {
List<LocationRequest> requests;
bool alwaysShow;
bool needBle;
LocationSettingsRequest({
this.requests = const <LocationRequest>[],
this.alwaysShow = false,
this.needBle = false,
});
Map<String, dynamic> toMap() {
return {
'requests': requests?.map((x) => x?.toMap())?.toList(),
'alwaysShow': alwaysShow,
'needBle': needBle,
};
}
factory LocationSettingsRequest.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return LocationSettingsRequest(
requests: List<LocationRequest>.from(
map['requests']?.map((x) => LocationRequest.fromMap(x))),
alwaysShow: map['alwaysShow'],
needBle: map['needBle'],
);
}
String toJson() => json.encode(toMap());
factory LocationSettingsRequest.fromJson(String source) =>
LocationSettingsRequest.fromMap(json.decode(source));
@override
String toString() =>
'LocationSettingsRequest(requests: $requests, alwaysShow: $alwaysShow, needBle: $needBle)';
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is LocationSettingsRequest &&
listEquals(o.requests, requests) &&
o.alwaysShow == alwaysShow &&
o.needBle == needBle;
}
@override
int get hashCode {
return hashList([
requests,
alwaysShow,
needBle,
]);
}
}

@ -0,0 +1,107 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
class LocationSettingsStates {
bool blePresent;
bool bleUsable;
bool gpsPresent;
bool gpsUsable;
bool locationPresent;
bool locationUsable;
bool networkLocationPresent;
bool networkLocationUsable;
LocationSettingsStates({
this.blePresent,
this.bleUsable,
this.gpsPresent,
this.gpsUsable,
this.locationPresent,
this.locationUsable,
this.networkLocationPresent,
this.networkLocationUsable,
});
Map<String, dynamic> toMap() {
return {
'blePresent': blePresent,
'bleUsable': bleUsable,
'gpsPresent': gpsPresent,
'gpsUsable': gpsUsable,
'locationPresent': locationPresent,
'locationUsable': locationUsable,
'networkLocationPresent': networkLocationPresent,
'networkLocationUsable': networkLocationUsable,
};
}
factory LocationSettingsStates.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return LocationSettingsStates(
blePresent: map['blePresent'],
bleUsable: map['bleUsable'],
gpsPresent: map['gpsPresent'],
gpsUsable: map['gpsUsable'],
locationPresent: map['locationPresent'],
locationUsable: map['locationUsable'],
networkLocationPresent: map['networkLocationPresent'],
networkLocationUsable: map['networkLocationUsable'],
);
}
String toJson() => json.encode(toMap());
factory LocationSettingsStates.fromJson(String source) =>
LocationSettingsStates.fromMap(json.decode(source));
@override
String toString() {
return 'LocationSettingsStates(blePresent: $blePresent, bleUsable: $bleUsable, gpsPresent: $gpsPresent, gpsUsable: $gpsUsable, locationPresent: $locationPresent, locationUsable: $locationUsable, networkLocationPresent: $networkLocationPresent, networkLocationUsable: $networkLocationUsable)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is LocationSettingsStates &&
o.blePresent == blePresent &&
o.bleUsable == bleUsable &&
o.gpsPresent == gpsPresent &&
o.gpsUsable == gpsUsable &&
o.locationPresent == locationPresent &&
o.locationUsable == locationUsable &&
o.networkLocationPresent == networkLocationPresent &&
o.networkLocationUsable == networkLocationUsable;
}
@override
int get hashCode {
return hashList([
blePresent,
bleUsable,
gpsPresent,
gpsUsable,
locationPresent,
locationUsable,
networkLocationPresent,
networkLocationUsable,
]);
}
}

@ -0,0 +1,82 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/foundation.dart';
class NavigationRequest {
static const int OVERPASS = 1;
static const int IS_SUPPORT_EX = 2;
int type;
Map<String, String> extras;
NavigationRequest({
this.type,
this.extras,
});
void putExtras(String key, String value) {
if (extras == null) {
extras = Map<String, String>();
}
extras.putIfAbsent(key, () => value);
}
Map<String, dynamic> toMap() {
return {
'type': type,
'extras': extras,
};
}
factory NavigationRequest.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return NavigationRequest(
type: map['type'],
extras: Map<String, String>.from(map['extras']),
);
}
String toJson() => json.encode(toMap());
factory NavigationRequest.fromJson(String source) =>
NavigationRequest.fromMap(json.decode(source));
@override
String toString() {
return 'NavigationRequest(type: $type, extras: $extras)';
}
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is NavigationRequest &&
o.type == type &&
mapEquals(o.extras, extras);
}
@override
int get hashCode {
return hashList([
type,
extras,
]);
}
}

@ -0,0 +1,53 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'dart:convert';
class NavigationResult {
int possibility;
int state;
NavigationResult({
this.possibility,
this.state,
});
Map<String, dynamic> toMap() {
return {
'state': state,
'possibility': possibility,
};
}
factory NavigationResult.fromMap(Map<dynamic, dynamic> map) {
if (map == null) return null;
return NavigationResult(
state: map["state"] == null ? null : map["state"],
possibility: map["possibility"] == null ? null : map["possibility"],
);
}
String toJson() => json.encode(toMap());
factory NavigationResult.fromJson(String source) =>
NavigationResult.fromMap(json.decode(source));
@override
String toString() {
return 'State: $state, Possibility: $possibility';
}
}

@ -0,0 +1,30 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'package:flutter/services.dart';
class HMSLogger {
static const MethodChannel _methodChannel =
MethodChannel("com.huawei.flutter.location/hmslogger_methodchannel");
static Future<void> enableLogger() async {
return _methodChannel.invokeMethod<void>('enableLogger');
}
static Future<void> disableLogger() async {
return _methodChannel.invokeMethod<void>('disableLogger');
}
}

@ -0,0 +1,63 @@
/*
Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import 'package:flutter/services.dart';
class PermissionHandler {
static PermissionHandler _instance;
final MethodChannel _methodChannel;
PermissionHandler._create(
this._methodChannel,
);
factory PermissionHandler() {
if (_instance == null) {
final MethodChannel methodChannel = const MethodChannel(
'com.huawei.flutter.location/permission_methodchannel');
_instance = PermissionHandler._create(methodChannel);
}
return _instance;
}
Future<bool> hasLocationPermission() async {
return _methodChannel.invokeMethod<bool>('hasLocationPermission');
}
Future<bool> hasBackgroundLocationPermission() async {
return _methodChannel.invokeMethod<bool>('hasBackgroundLocationPermission');
}
Future<bool> hasActivityRecognitionPermission() async {
return _methodChannel
.invokeMethod<bool>('hasActivityRecognitionPermission');
}
Future<bool> requestLocationPermission() async {
return _methodChannel.invokeMethod<bool>('requestLocationPermission');
}
Future<bool> requestBackgroundLocationPermission() async {
return _methodChannel
.invokeMethod<bool>('requestBackgroundLocationPermission');
}
Future<bool> requestActivityRecognitionPermission() async {
return _methodChannel
.invokeMethod<bool>('requestActivityRecognitionPermission');
}
}

@ -0,0 +1,24 @@
name: huawei_location
description: HUAWEI Flutter Location Kit plugin combines the GPS, Wi-Fi and base station locations to help you quickly obtain precise user locations & build up global positioning capabilities.
version: 5.0.0+301
homepage: https://www.huawei.com
repository: https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-location
environment:
sdk: ">=2.1.0 <3.0.0"
flutter: ">=1.12.13+hotfix.6 <2.0.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
plugin:
platforms:
android:
package: com.huawei.hms.flutter.location
pluginClass: LocationPlugin

@ -1 +1 @@
45a7d43b55124e1b314759554f9a14d3
269226e53e3ba1b1460fd3df51f89f77

@ -1,24 +1,826 @@
PODS:
- abseil/algorithm (0.20200225.0):
- abseil/algorithm/algorithm (= 0.20200225.0)
- abseil/algorithm/container (= 0.20200225.0)
- abseil/algorithm/algorithm (0.20200225.0):
- abseil/base/config
- abseil/algorithm/container (0.20200225.0):
- abseil/algorithm/algorithm
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/base (0.20200225.0):
- abseil/base/atomic_hook (= 0.20200225.0)
- abseil/base/base (= 0.20200225.0)
- abseil/base/base_internal (= 0.20200225.0)
- abseil/base/bits (= 0.20200225.0)
- abseil/base/config (= 0.20200225.0)
- abseil/base/core_headers (= 0.20200225.0)
- abseil/base/dynamic_annotations (= 0.20200225.0)
- abseil/base/endian (= 0.20200225.0)
- abseil/base/errno_saver (= 0.20200225.0)
- abseil/base/exponential_biased (= 0.20200225.0)
- abseil/base/log_severity (= 0.20200225.0)
- abseil/base/malloc_internal (= 0.20200225.0)
- abseil/base/periodic_sampler (= 0.20200225.0)
- abseil/base/pretty_function (= 0.20200225.0)
- abseil/base/raw_logging_internal (= 0.20200225.0)
- abseil/base/spinlock_wait (= 0.20200225.0)
- abseil/base/throw_delegate (= 0.20200225.0)
- abseil/base/atomic_hook (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/base (0.20200225.0):
- abseil/base/atomic_hook
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/log_severity
- abseil/base/raw_logging_internal
- abseil/base/spinlock_wait
- abseil/meta/type_traits
- abseil/base/base_internal (0.20200225.0):
- abseil/base/config
- abseil/meta/type_traits
- abseil/base/bits (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/config (0.20200225.0)
- abseil/base/core_headers (0.20200225.0):
- abseil/base/config
- abseil/base/dynamic_annotations (0.20200225.0)
- abseil/base/endian (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/errno_saver (0.20200225.0):
- abseil/base/config
- abseil/base/exponential_biased (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/log_severity (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/malloc_internal (0.20200225.0):
- abseil/base/base
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/raw_logging_internal
- abseil/base/periodic_sampler (0.20200225.0):
- abseil/base/core_headers
- abseil/base/exponential_biased
- abseil/base/pretty_function (0.20200225.0)
- abseil/base/raw_logging_internal (0.20200225.0):
- abseil/base/atomic_hook
- abseil/base/config
- abseil/base/core_headers
- abseil/base/log_severity
- abseil/base/spinlock_wait (0.20200225.0):
- abseil/base/base_internal
- abseil/base/core_headers
- abseil/base/errno_saver
- abseil/base/throw_delegate (0.20200225.0):
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/container/compressed_tuple (0.20200225.0):
- abseil/utility/utility
- abseil/container/inlined_vector (0.20200225.0):
- abseil/algorithm/algorithm
- abseil/base/core_headers
- abseil/base/throw_delegate
- abseil/container/inlined_vector_internal
- abseil/memory/memory
- abseil/container/inlined_vector_internal (0.20200225.0):
- abseil/base/core_headers
- abseil/container/compressed_tuple
- abseil/memory/memory
- abseil/meta/type_traits
- abseil/types/span
- abseil/memory (0.20200225.0):
- abseil/memory/memory (= 0.20200225.0)
- abseil/memory/memory (0.20200225.0):
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/meta (0.20200225.0):
- abseil/meta/type_traits (= 0.20200225.0)
- abseil/meta/type_traits (0.20200225.0):
- abseil/base/config
- abseil/numeric/int128 (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/strings/internal (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/base/raw_logging_internal
- abseil/meta/type_traits
- abseil/strings/str_format (0.20200225.0):
- abseil/strings/str_format_internal
- abseil/strings/str_format_internal (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/numeric/int128
- abseil/strings/strings
- abseil/types/span
- abseil/strings/strings (0.20200225.0):
- abseil/base/base
- abseil/base/bits
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/base/raw_logging_internal
- abseil/base/throw_delegate
- abseil/memory/memory
- abseil/meta/type_traits
- abseil/numeric/int128
- abseil/strings/internal
- abseil/time (0.20200225.0):
- abseil/time/internal (= 0.20200225.0)
- abseil/time/time (= 0.20200225.0)
- abseil/time/internal (0.20200225.0):
- abseil/time/internal/cctz (= 0.20200225.0)
- abseil/time/internal/cctz (0.20200225.0):
- abseil/time/internal/cctz/civil_time (= 0.20200225.0)
- abseil/time/internal/cctz/time_zone (= 0.20200225.0)
- abseil/time/internal/cctz/civil_time (0.20200225.0):
- abseil/base/config
- abseil/time/internal/cctz/time_zone (0.20200225.0):
- abseil/base/config
- abseil/time/internal/cctz/civil_time
- abseil/time/time (0.20200225.0):
- abseil/base/base
- abseil/base/core_headers
- abseil/base/raw_logging_internal
- abseil/numeric/int128
- abseil/strings/strings
- abseil/time/internal/cctz/civil_time
- abseil/time/internal/cctz/time_zone
- abseil/types (0.20200225.0):
- abseil/types/any (= 0.20200225.0)
- abseil/types/bad_any_cast (= 0.20200225.0)
- abseil/types/bad_any_cast_impl (= 0.20200225.0)
- abseil/types/bad_optional_access (= 0.20200225.0)
- abseil/types/bad_variant_access (= 0.20200225.0)
- abseil/types/compare (= 0.20200225.0)
- abseil/types/optional (= 0.20200225.0)
- abseil/types/span (= 0.20200225.0)
- abseil/types/variant (= 0.20200225.0)
- abseil/types/any (0.20200225.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/types/bad_any_cast
- abseil/utility/utility
- abseil/types/bad_any_cast (0.20200225.0):
- abseil/base/config
- abseil/types/bad_any_cast_impl
- abseil/types/bad_any_cast_impl (0.20200225.0):
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/types/bad_optional_access (0.20200225.0):
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/types/bad_variant_access (0.20200225.0):
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/types/compare (0.20200225.0):
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/types/optional (0.20200225.0):
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/memory/memory
- abseil/meta/type_traits
- abseil/types/bad_optional_access
- abseil/utility/utility
- abseil/types/span (0.20200225.0):
- abseil/algorithm/algorithm
- abseil/base/core_headers
- abseil/base/throw_delegate
- abseil/meta/type_traits
- abseil/types/variant (0.20200225.0):
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/types/bad_variant_access
- abseil/utility/utility
- abseil/utility/utility (0.20200225.0):
- abseil/base/base_internal
- abseil/base/config
- abseil/meta/type_traits
- android_intent (0.0.1):
- Flutter
- barcode_scan_fix (0.0.1):
- Flutter
- MTBBarcodeScanner
- BoringSSL-GRPC (0.0.7):
- BoringSSL-GRPC/Implementation (= 0.0.7)
- BoringSSL-GRPC/Interface (= 0.0.7)
- BoringSSL-GRPC/Implementation (0.0.7):
- BoringSSL-GRPC/Interface (= 0.0.7)
- BoringSSL-GRPC/Interface (0.0.7)
- cloud_firestore (0.14.4):
- Firebase/CoreOnly (~> 6.33.0)
- Firebase/Firestore (~> 6.33.0)
- firebase_core
- Flutter
- cloud_firestore_web (0.1.0):
- Flutter
- connectivity (0.0.1):
- Flutter
- Reachability
- connectivity_for_web (0.1.0):
- Flutter
- connectivity_macos (0.0.1):
- Flutter
- device_calendar (0.0.1):
- Flutter
- device_info (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.2):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.2)
- DKImagePickerController/PhotoGallery (4.3.2):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.2)
- DKPhotoGallery (0.0.17):
- DKPhotoGallery/Core (= 0.0.17)
- DKPhotoGallery/Model (= 0.0.17)
- DKPhotoGallery/Preview (= 0.0.17)
- DKPhotoGallery/Resource (= 0.0.17)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.17):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.17):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.17):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.17):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- file_picker_web (0.0.1):
- Flutter
- Firebase/CoreOnly (6.33.0):
- FirebaseCore (= 6.10.3)
- Firebase/Firestore (6.33.0):
- Firebase/CoreOnly
- FirebaseFirestore (~> 1.18.0)
- Firebase/Messaging (6.33.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 4.7.0)
- firebase_core (0.5.3):
- Firebase/CoreOnly (~> 6.33.0)
- Flutter
- firebase_core_web (0.1.0):
- Flutter
- firebase_messaging (7.0.3):
- Firebase/CoreOnly (~> 6.33.0)
- Firebase/Messaging (~> 6.33.0)
- firebase_core
- Flutter
- FirebaseCore (6.10.3):
- FirebaseCoreDiagnostics (~> 1.6)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- FirebaseCoreDiagnostics (1.7.0):
- GoogleDataTransport (~> 7.4)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- nanopb (~> 1.30906.0)
- FirebaseFirestore (1.18.0):
- abseil/algorithm (= 0.20200225.0)
- abseil/base (= 0.20200225.0)
- abseil/memory (= 0.20200225.0)
- abseil/meta (= 0.20200225.0)
- abseil/strings/strings (= 0.20200225.0)
- abseil/time (= 0.20200225.0)
- abseil/types (= 0.20200225.0)
- FirebaseCore (~> 6.10)
- "gRPC-C++ (~> 1.28.0)"
- leveldb-library (~> 1.22)
- nanopb (~> 1.30906.0)
- FirebaseInstallations (1.7.0):
- FirebaseCore (~> 6.10)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- PromisesObjC (~> 1.2)
- FirebaseInstanceID (4.8.0):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (~> 1.6)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- FirebaseMessaging (4.7.1):
- FirebaseCore (~> 6.10)
- FirebaseInstanceID (~> 4.7)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Reachability (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- Protobuf (>= 3.9.2, ~> 3.9)
- Flutter (1.0.0)
- flutter_email_sender (0.0.1):
- Flutter
- flutter_flexible_toast (0.0.1):
- Flutter
- flutter_hms_gms_availability (0.0.1):
- Flutter
- flutter_inappwebview (0.0.1):
- Flutter
- flutter_local_notifications (0.0.1):
- Flutter
- flutter_plugin_android_lifecycle (0.0.1):
- Flutter
- flutter_tts (0.0.1):
- Flutter
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- geolocator (6.1.9):
- Flutter
- google_maps_flutter (0.0.1):
- Flutter
- GoogleMaps (< 3.10)
- GoogleDataTransport (7.5.1):
- nanopb (~> 1.30906.0)
- GoogleMaps (3.9.0):
- GoogleMaps/Maps (= 3.9.0)
- GoogleMaps/Base (3.9.0)
- GoogleMaps/Maps (3.9.0):
- GoogleMaps/Base
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (6.7.2):
- PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/Network (6.7.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (6.7.2)"
- GoogleUtilities/Reachability (6.7.2):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (6.7.2):
- GoogleUtilities/Logger
- "gRPC-C++ (1.28.2)":
- "gRPC-C++/Implementation (= 1.28.2)"
- "gRPC-C++/Interface (= 1.28.2)"
- "gRPC-C++/Implementation (1.28.2)":
- abseil/container/inlined_vector (= 0.20200225.0)
- abseil/memory/memory (= 0.20200225.0)
- abseil/strings/str_format (= 0.20200225.0)
- abseil/strings/strings (= 0.20200225.0)
- abseil/types/optional (= 0.20200225.0)
- "gRPC-C++/Interface (= 1.28.2)"
- gRPC-Core (= 1.28.2)
- "gRPC-C++/Interface (1.28.2)"
- gRPC-Core (1.28.2):
- gRPC-Core/Implementation (= 1.28.2)
- gRPC-Core/Interface (= 1.28.2)
- gRPC-Core/Implementation (1.28.2):
- abseil/container/inlined_vector (= 0.20200225.0)
- abseil/memory/memory (= 0.20200225.0)
- abseil/strings/str_format (= 0.20200225.0)
- abseil/strings/strings (= 0.20200225.0)
- abseil/types/optional (= 0.20200225.0)
- BoringSSL-GRPC (= 0.0.7)
- gRPC-Core/Interface (= 1.28.2)
- gRPC-Core/Interface (1.28.2)
- hexcolor (0.0.1):
- Flutter
- "huawei_location (5.0.0+301)":
- Flutter
- image_cropper (0.0.3):
- Flutter
- TOCropViewController (~> 2.5.4)
- image_picker (0.0.1):
- Flutter
- just_audio (0.0.1):
- Flutter
- leveldb-library (1.22)
- local_auth (0.0.1):
- Flutter
- location (0.0.1):
- Flutter
- manage_calendar_events (0.0.1):
- Flutter
- map_launcher (0.0.1):
- Flutter
- maps_launcher (0.0.1):
- Flutter
- MTBBarcodeScanner (5.0.11)
- nanopb (1.30906.0):
- nanopb/decode (= 1.30906.0)
- nanopb/encode (= 1.30906.0)
- nanopb/decode (1.30906.0)
- nanopb/encode (1.30906.0)
- native_device_orientation (0.0.1):
- Flutter
- NVActivityIndicatorView (5.1.1):
- NVActivityIndicatorView/Base (= 5.1.1)
- NVActivityIndicatorView/Base (5.1.1)
- path_provider (0.0.1):
- Flutter
- path_provider_linux (0.0.1):
- Flutter
- path_provider_macos (0.0.1):
- Flutter
- path_provider_windows (0.0.1):
- Flutter
- "permission_handler (5.0.1+1)":
- Flutter
- PromisesObjC (1.2.11)
- Protobuf (3.13.0)
- Reachability (3.2)
- screen (0.0.1):
- Flutter
- SDWebImage (5.10.4):
- SDWebImage/Core (= 5.10.4)
- SDWebImage/Core (5.10.4)
- shared_preferences (0.0.1):
- Flutter
- shared_preferences_linux (0.0.1):
- Flutter
- shared_preferences_macos (0.0.1):
- Flutter
- shared_preferences_web (0.0.1):
- Flutter
- shared_preferences_windows (0.0.1):
- Flutter
- sms_otp_auto_verify (0.0.1):
- Flutter
- speech_to_text (0.0.1):
- Flutter
- Try
- sqflite (0.0.2):
- Flutter
- FMDB (>= 2.7.5)
- SwiftyGif (5.4.0)
- TOCropViewController (2.5.5)
- Try (2.1.1)
- "twilio_programmable_video (0.5.0+4)":
- Flutter
- TwilioVideo (~> 3.4)
- TwilioVideo (3.8.0)
- url_launcher (0.0.1):
- Flutter
- url_launcher_linux (0.0.1):
- Flutter
- url_launcher_macos (0.0.1):
- Flutter
- url_launcher_web (0.0.1):
- Flutter
- url_launcher_windows (0.0.1):
- Flutter
- vibration (1.7.3):
- Flutter
- vibration_web (1.6.2):
- Flutter
- video_player (0.0.1):
- Flutter
- video_player_web (0.0.1):
- Flutter
- wakelock (0.0.1):
- Flutter
- webview_flutter (0.0.1):
- Flutter
- wifi (0.0.1):
- Flutter
DEPENDENCIES:
- android_intent (from `.symlinks/plugins/android_intent/ios`)
- barcode_scan_fix (from `.symlinks/plugins/barcode_scan_fix/ios`)
- cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`)
- cloud_firestore_web (from `.symlinks/plugins/cloud_firestore_web/ios`)
- connectivity (from `.symlinks/plugins/connectivity/ios`)
- connectivity_for_web (from `.symlinks/plugins/connectivity_for_web/ios`)
- connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`)
- device_calendar (from `.symlinks/plugins/device_calendar/ios`)
- device_info (from `.symlinks/plugins/device_info/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- file_picker_web (from `.symlinks/plugins/file_picker_web/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_core_web (from `.symlinks/plugins/firebase_core_web/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
- flutter_email_sender (from `.symlinks/plugins/flutter_email_sender/ios`)
- flutter_flexible_toast (from `.symlinks/plugins/flutter_flexible_toast/ios`)
- flutter_hms_gms_availability (from `.symlinks/plugins/flutter_hms_gms_availability/ios`)
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`)
- flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
- geolocator (from `.symlinks/plugins/geolocator/ios`)
- google_maps_flutter (from `.symlinks/plugins/google_maps_flutter/ios`)
- hexcolor (from `.symlinks/plugins/hexcolor/ios`)
- huawei_location (from `.symlinks/plugins/huawei_location/ios`)
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
- image_picker (from `.symlinks/plugins/image_picker/ios`)
- just_audio (from `.symlinks/plugins/just_audio/ios`)
- local_auth (from `.symlinks/plugins/local_auth/ios`)
- location (from `.symlinks/plugins/location/ios`)
- manage_calendar_events (from `.symlinks/plugins/manage_calendar_events/ios`)
- map_launcher (from `.symlinks/plugins/map_launcher/ios`)
- maps_launcher (from `.symlinks/plugins/maps_launcher/ios`)
- native_device_orientation (from `.symlinks/plugins/native_device_orientation/ios`)
- NVActivityIndicatorView
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`)
- path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
- path_provider_windows (from `.symlinks/plugins/path_provider_windows/ios`)
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
- screen (from `.symlinks/plugins/screen/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
- shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`)
- shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
- shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`)
- shared_preferences_windows (from `.symlinks/plugins/shared_preferences_windows/ios`)
- sms_otp_auto_verify (from `.symlinks/plugins/sms_otp_auto_verify/ios`)
- speech_to_text (from `.symlinks/plugins/speech_to_text/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
- twilio_programmable_video (from `.symlinks/plugins/twilio_programmable_video/ios`)
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
- url_launcher_linux (from `.symlinks/plugins/url_launcher_linux/ios`)
- url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`)
- url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
- url_launcher_windows (from `.symlinks/plugins/url_launcher_windows/ios`)
- vibration (from `.symlinks/plugins/vibration/ios`)
- vibration_web (from `.symlinks/plugins/vibration_web/ios`)
- video_player (from `.symlinks/plugins/video_player/ios`)
- video_player_web (from `.symlinks/plugins/video_player_web/ios`)
- wakelock (from `.symlinks/plugins/wakelock/ios`)
- webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
- wifi (from `.symlinks/plugins/wifi/ios`)
SPEC REPOS:
trunk:
- abseil
- BoringSSL-GRPC
- DKImagePickerController
- DKPhotoGallery
- Firebase
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseFirestore
- FirebaseInstallations
- FirebaseInstanceID
- FirebaseMessaging
- FMDB
- GoogleDataTransport
- GoogleMaps
- GoogleUtilities
- "gRPC-C++"
- gRPC-Core
- leveldb-library
- MTBBarcodeScanner
- nanopb
- NVActivityIndicatorView
- PromisesObjC
- Protobuf
- Reachability
- SDWebImage
- SwiftyGif
- TOCropViewController
- Try
- TwilioVideo
EXTERNAL SOURCES:
android_intent:
:path: ".symlinks/plugins/android_intent/ios"
barcode_scan_fix:
:path: ".symlinks/plugins/barcode_scan_fix/ios"
cloud_firestore:
:path: ".symlinks/plugins/cloud_firestore/ios"
cloud_firestore_web:
:path: ".symlinks/plugins/cloud_firestore_web/ios"
connectivity:
:path: ".symlinks/plugins/connectivity/ios"
connectivity_for_web:
:path: ".symlinks/plugins/connectivity_for_web/ios"
connectivity_macos:
:path: ".symlinks/plugins/connectivity_macos/ios"
device_calendar:
:path: ".symlinks/plugins/device_calendar/ios"
device_info:
:path: ".symlinks/plugins/device_info/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
file_picker_web:
:path: ".symlinks/plugins/file_picker_web/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_core_web:
:path: ".symlinks/plugins/firebase_core_web/ios"
firebase_messaging:
:path: ".symlinks/plugins/firebase_messaging/ios"
Flutter:
:path: Flutter
flutter_email_sender:
:path: ".symlinks/plugins/flutter_email_sender/ios"
flutter_flexible_toast:
:path: ".symlinks/plugins/flutter_flexible_toast/ios"
flutter_hms_gms_availability:
:path: ".symlinks/plugins/flutter_hms_gms_availability/ios"
flutter_inappwebview:
:path: ".symlinks/plugins/flutter_inappwebview/ios"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_plugin_android_lifecycle:
:path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios"
flutter_tts:
:path: ".symlinks/plugins/flutter_tts/ios"
geolocator:
:path: ".symlinks/plugins/geolocator/ios"
google_maps_flutter:
:path: ".symlinks/plugins/google_maps_flutter/ios"
hexcolor:
:path: ".symlinks/plugins/hexcolor/ios"
huawei_location:
:path: ".symlinks/plugins/huawei_location/ios"
image_cropper:
:path: ".symlinks/plugins/image_cropper/ios"
image_picker:
:path: ".symlinks/plugins/image_picker/ios"
just_audio:
:path: ".symlinks/plugins/just_audio/ios"
local_auth:
:path: ".symlinks/plugins/local_auth/ios"
location:
:path: ".symlinks/plugins/location/ios"
manage_calendar_events:
:path: ".symlinks/plugins/manage_calendar_events/ios"
map_launcher:
:path: ".symlinks/plugins/map_launcher/ios"
maps_launcher:
:path: ".symlinks/plugins/maps_launcher/ios"
native_device_orientation:
:path: ".symlinks/plugins/native_device_orientation/ios"
path_provider:
:path: ".symlinks/plugins/path_provider/ios"
path_provider_linux:
:path: ".symlinks/plugins/path_provider_linux/ios"
path_provider_macos:
:path: ".symlinks/plugins/path_provider_macos/ios"
path_provider_windows:
:path: ".symlinks/plugins/path_provider_windows/ios"
permission_handler:
:path: ".symlinks/plugins/permission_handler/ios"
screen:
:path: ".symlinks/plugins/screen/ios"
shared_preferences:
:path: ".symlinks/plugins/shared_preferences/ios"
shared_preferences_linux:
:path: ".symlinks/plugins/shared_preferences_linux/ios"
shared_preferences_macos:
:path: ".symlinks/plugins/shared_preferences_macos/ios"
shared_preferences_web:
:path: ".symlinks/plugins/shared_preferences_web/ios"
shared_preferences_windows:
:path: ".symlinks/plugins/shared_preferences_windows/ios"
sms_otp_auto_verify:
:path: ".symlinks/plugins/sms_otp_auto_verify/ios"
speech_to_text:
:path: ".symlinks/plugins/speech_to_text/ios"
sqflite:
:path: ".symlinks/plugins/sqflite/ios"
twilio_programmable_video:
:path: ".symlinks/plugins/twilio_programmable_video/ios"
url_launcher:
:path: ".symlinks/plugins/url_launcher/ios"
url_launcher_linux:
:path: ".symlinks/plugins/url_launcher_linux/ios"
url_launcher_macos:
:path: ".symlinks/plugins/url_launcher_macos/ios"
url_launcher_web:
:path: ".symlinks/plugins/url_launcher_web/ios"
url_launcher_windows:
:path: ".symlinks/plugins/url_launcher_windows/ios"
vibration:
:path: ".symlinks/plugins/vibration/ios"
vibration_web:
:path: ".symlinks/plugins/vibration_web/ios"
video_player:
:path: ".symlinks/plugins/video_player/ios"
video_player_web:
:path: ".symlinks/plugins/video_player_web/ios"
wakelock:
:path: ".symlinks/plugins/wakelock/ios"
webview_flutter:
:path: ".symlinks/plugins/webview_flutter/ios"
wifi:
:path: ".symlinks/plugins/wifi/ios"
SPEC CHECKSUMS:
abseil: 6c8eb7892aefa08d929b39f9bb108e5367e3228f
android_intent: 367df2f1277a74e4a90e14a8ab3df3112d087052
barcode_scan_fix: 80dd65de55f27eec6591dd077c8b85f2b79e31f1
BoringSSL-GRPC: 8edf627ee524575e2f8d19d56f068b448eea3879
cloud_firestore: b8c0e15fa49dfff87c2817d288b577e5dca2df13
cloud_firestore_web: 9ec3dc7f5f98de5129339802d491c1204462bfec
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
connectivity_for_web: 2b8584556930d4bd490d82b836bcf45067ce345b
connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191
device_calendar: 23b28a5f1ab3bf77e34542fb1167e1b8b29a98f5
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1
file_picker_web: 37b10786e88885124fac99dc899866e78a132ef3
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659
firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1
firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
FirebaseFirestore: adff4877869ca91a11250cc0989a6cd56bad163f
FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2
FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1
FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_email_sender: f787522d0e82f50e5766c1213dbffff22fdcf009
flutter_flexible_toast: 0547e740cae0c33bb7c51bcd931233f4584e1143
flutter_hms_gms_availability: babc50b18670e99780270bc18d9b17d0a07cd77e
flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189
flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186
flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35
flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
geolocator: 057a0c63a43e9c5296d8ad845a3ac8e6df23d899
google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
"gRPC-C++": 13d8ccef97d5c3c441b7e3c529ef28ebee86fad2
gRPC-Core: 4afa11bfbedf7cdecd04de535a9e046893404ed5
hexcolor: fdfb9c4258ad96e949c2dbcdf790a62194b8aa89
huawei_location: a1c3d2a029138b3d0b9a72ce910ffae3ff23c1aa
image_cropper: c8f9b4157933c7bb965a66d1c5e6c8fd408c6eb4
image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
leveldb-library: 55d93ee664b4007aac644a782d11da33fba316f7
local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd
location: 3a2eed4dd2fab25e7b7baf2a9efefe82b512d740
manage_calendar_events: 0338d505ea26cdfd20cd883279bc28afa11eca34
map_launcher: e325db1261d029ff33e08e03baccffe09593ffea
maps_launcher: eae38ee13a9c3f210fa04e04bb4c073fa4c6ed92
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
native_device_orientation: e24d00be281de72996640885d80e706142707660
NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
path_provider_windows: a2b81600c677ac1959367280991971cb9a1edb3b
permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6
PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
screen: abd91ca7bf3426e1cc3646d27e9b2358d6bf07b0
SDWebImage: c666b97e1fa9c64b4909816a903322018f0a9c84
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78
shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087
shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9
shared_preferences_windows: 36b76d6f54e76ead957e60b49e2f124b4cd3e6ae
sms_otp_auto_verify: 201803ac25e13feedaae96eda8b70b10c55b3338
speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
SwiftyGif: 5d4af95df24caf1c570dbbcb32a3b8a0763bc6d7
TOCropViewController: da59f531f8ac8a94ef6d6c0fc34009350f9e8bfe
Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96
twilio_programmable_video: 6a41593640f3d86af60b22541fd457b22deaae7f
TwilioVideo: c13a51ceca375e91620eb7578d2573c90cf53b46
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0
url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
url_launcher_windows: 683d7c283894db8d1914d3ab2223b20cc1ad95d5
vibration: b5a33e764c3f609a975b9dca73dce20fdde627dc
vibration_web: 0ba303d92469ba34d71c612a228b315908d7fcd9
video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e
video_player_web: da8cadb8274ed4f8dbee8d7171b420dedd437ce7
wakelock: 0d4a70faf8950410735e3f61fb15d517c8a6efc4
webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96
wifi: d7d77c94109e36c4175d845f0a5964eadba71060
PODFILE CHECKSUM: ac5efa1ac3c9555d0008dc18004313c84746da62

@ -220,6 +220,7 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */,
835BB6C21DD911F74065B670 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -319,6 +320,23 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
835BB6C21DD911F74065B670 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;

@ -14,7 +14,7 @@ const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items';
const PACKAGES_ORDERS = '/api/orders';
const BASE_URL = 'https://uat.hmgwebservices.com/';
// const BASE_URL = 'https://hmgwebservices.com/';
//const BASE_URL = 'https://hmgwebservices.com/';
// Pharmacy UAT URLs
const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/';
@ -33,7 +33,8 @@ const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints';
const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo';
// Delivery Driver
const DRIVER_LOCATION = 'Services/Patients.svc/REST/PatientER_GetDriverLocation';
const DRIVER_LOCATION =
'Services/Patients.svc/REST/PatientER_GetDriverLocation';
//weather
const WEATHER_INDICATOR = 'Services/Weather.svc/REST/GetCityInfo';
@ -220,9 +221,11 @@ const GET_PATIENT_SHARE =
const GET_PATIENT_APPOINTMENT_HISTORY =
"Services/Doctors.svc/REST/PateintHasAppoimentHistory";
const SEND_REPORT_EYE_EMAIL = "Services/Notifications.svc/REST/SendGlassesPrescriptionEmail";
const SEND_REPORT_EYE_EMAIL =
"Services/Notifications.svc/REST/SendGlassesPrescriptionEmail";
const SEND_CONTACT_LENS_PRESCRIPTION_EMAIL = "Services/Notifications.svc/REST/SendContactLensPrescriptionEmail";
const SEND_CONTACT_LENS_PRESCRIPTION_EMAIL =
"Services/Notifications.svc/REST/SendContactLensPrescriptionEmail";
//URL to get patient appointment curfew history
const GET_PATIENT_APPOINTMENT_CURFEW_HISTORY =
@ -509,7 +512,7 @@ const LAKUM_GET_USER_TERMS_AND_CONDITIONS =
"Services/ERP.svc/REST/GetUserTermsAndConditionsForEPharmcy";
const PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList';
const GET_RECOMMENDED_PRODUCT = 'alsoProduct/';
const GET_MOST_VIEWED_PRODUCTS ="mostview?";
const GET_MOST_VIEWED_PRODUCTS = "mostview?";
const GET_NEW_PRODUCTS = "newproducts?";
// Home Health Care

@ -186,10 +186,7 @@ const Map localizedValues = {
"fileNo": {"en": "File Number", "ar": "رقم الملف"},
"fileno": {"en": "File No", "ar": "رقم الملف"},
"forgotFileNo": {"en": "Forgot file Number?", "ar": "نسيت رقم الملف الطبي؟"},
"forgotFileNoTitle": {
"en": "Forgot medical file Number",
"ar": "نسيت رقم الملف"
},
"forgotFileNoTitle": {"en": "Forgot medical file", "ar": "نسيت رقم الملف"},
"enter-national-id": {
"en": "Please enter mobile number and identification number",
@ -780,6 +777,7 @@ const Map localizedValues = {
"orderDate": {"en": "Date", "ar": "التاريخ:"},
"itemsNo": {"en": "items(s)", "ar": "عناصر"},
"noOrder": {"en": "You Don't have any orders.", "ar": "ليس لديك طلبات"},
"noResult": {"en": "No Result.", "ar": "لايوجد نتئج"},
"TermsService": {"en": "Terms of Service", "ar": "شروط الخدمه"},
"Beforeusing": {
@ -874,6 +872,7 @@ const Map localizedValues = {
"wishList": {"en": "WishList", "ar": "الرغبات"},
"myAccount": {"en": "My Account", "ar": "حسابي"},
"cart": {"en": "Cart", "ar": "التسوق"},
"Alhabibapp": {"en": "Al habib app", "ar": "تطبيق الحبيب"},
"searchProductHere": {
"en": "Search Product here",
"ar": "ابحث في الطلب الخاص بك"
@ -1997,5 +1996,29 @@ const Map localizedValues = {
"enter-file": {
"en": "Please enter the mobile number and the medical file number",
"ar": "الرجاء إدخال رقم الجوال ورقم الملف الطبي"
},
"referralRequesterInformation": {
"en": "Referral requester information",
"ar": "معلومات طالب الإحالة"
},
"enterReferralRequesterName": {
"en": "Enter Referral Requester Name*",
"ar": "أدخل اسم مقدم طلب الإحالة *"
},
"selectRelationship": {
"en": "Select Relationship",
"ar": "حدد العلاقة"
},
"requesterRelationship": {
"en": "Requester Relationship",
"ar": "علاقة الطالب"
},
"newReferral": {
"en": "New Referral",
"ar": "إحالة جديدة"
},
"searchForReferrals": {
"en": "Search For Referrals",
"ar": "ابحث عن الإحالات"
}
};

@ -87,7 +87,7 @@ class BaseAppClient {
: IS_DENTAL_ALLOWED_BACKEND;
}
body['DeviceTypeID'] = Platform.isAndroid ? 1: 2;
body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2;
if (!body.containsKey('IsPublicRequest')) {
body['PatientType'] = body.containsKey('PatientType')
@ -117,7 +117,8 @@ class BaseAppClient {
'Accept': 'application/json',
'Authorization': pharmacyToken,
'Mobilenumber': user != null
? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString())
? Utils.getPhoneNumberWithoutZero(
user['MobileNumber'].toString())
: "",
'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
'Username': user['PatientID'].toString(),
@ -278,8 +279,7 @@ class BaseAppClient {
: IS_DENTAL_ALLOWED_BACKEND;
}
body['DeviceTypeID'] = Platform.isAndroid ? 1: 2;
body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2;
if (!body.containsKey('IsPublicRequest')) {
body['PatientType'] = body.containsKey('PatientType')
@ -507,10 +507,12 @@ class BaseAppClient {
}
}
simplePost(String fullUrl,
{ Map<String, dynamic> body,
Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure,}) async {
simplePost(
String fullUrl, {
Map<String, dynamic> body,
Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure,
}) async {
String url = fullUrl;
print("URL Query String: $url");
@ -539,9 +541,8 @@ class BaseAppClient {
simpleGet(String fullUrl,
{Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure,
Map<String, String> queryParams}) async {
Function(String error, int statusCode) onFailure,
Map<String, String> queryParams}) async {
String url = fullUrl;
print("URL Query String: $url");
@ -574,12 +575,10 @@ class BaseAppClient {
}
}
simplePut(String fullUrl,
{ Map<String, dynamic> body,
Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure}) async {
{Map<String, dynamic> body,
Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure}) async {
String url = fullUrl;
print("URL Query String: $url");
@ -608,9 +607,8 @@ class BaseAppClient {
simpleDelete(String fullUrl,
{Function(dynamic response, int statusCode) onSuccess,
Function(String error, int statusCode) onFailure,
Map<String, String> queryParams}) async {
Function(String error, int statusCode) onFailure,
Map<String, String> queryParams}) async {
String url = fullUrl;
print("URL Query String: $url");
@ -733,7 +731,7 @@ class BaseAppClient {
: IS_DENTAL_ALLOWED_BACKEND;
}
body['DeviceTypeID'] = Platform.isAndroid ? 1: 2;
body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2;
if (!body.containsKey('IsPublicRequest')) {
body['PatientType'] = body.containsKey('PatientType')

@ -34,7 +34,7 @@ class PharmacyModuleViewModel extends BaseViewModel {
_pharmacyService.lastVisitedProducts;
List<Products> get recommendedProductList =>
List<PharmacyProduct> get recommendedProductList =>
_recommendedProductService.recommendedList;
List<Prescriptions> get prescriptionsList =>

File diff suppressed because it is too large Load Diff

@ -4,11 +4,12 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/
import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/EReferral/send_activation_code_for_e_referral_request_model.dart';
import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart';
import 'package:diplomaticquarterapp/core/viewModels/all_habib_medical_services/e_referral_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/dialogs/select_relation_type_dialog.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_confirm_sms_dialog.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
@ -18,6 +19,7 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class NewEReferralStepOnePage extends StatefulWidget {
@ -38,6 +40,7 @@ class _NewEReferralStepOnePageState extends State<NewEReferralStepOnePage> {
AuthenticatedUser authenticatedUser;
GetAllSharedRecordsByStatusList selectedPatientFamily;
AdvanceModel advanceModel = AdvanceModel();
ProjectViewModel projectViewModel;
// todo create a model for Country
// todo use country from the json
@ -59,6 +62,7 @@ class _NewEReferralStepOnePageState extends State<NewEReferralStepOnePage> {
@override
Widget build(BuildContext context) {
projectViewModel = Provider.of(context);
void showSMSDialog() {
showDialog(
context: context,
@ -104,8 +108,8 @@ class _NewEReferralStepOnePageState extends State<NewEReferralStepOnePage> {
),
Center(
child: Texts(
// TranslationBase.of(context).advancePaymentLabel,
"Referral requester information",
TranslationBase.of(context)
.referralRequesterInformation,
textAlign: TextAlign.center,
),
),
@ -113,7 +117,9 @@ class _NewEReferralStepOnePageState extends State<NewEReferralStepOnePage> {
height: 12,
),
NewTextFields(
hintText: "Enter Referral Requester Name*",
hintText: TranslationBase
.of(context)
.enterReferralRequesterName,
controller: _nameTextController,
),
SizedBox(
@ -151,8 +157,7 @@ class _NewEReferralStepOnePageState extends State<NewEReferralStepOnePage> {
),
Center(
child: Texts(
// TranslationBase.of(context).advancePaymentLabel,
"Requester Relationship",
TranslationBase.of(context).requesterRelationship,
textAlign: TextAlign.center,
),
),
@ -246,15 +251,25 @@ class _NewEReferralStepOnePageState extends State<NewEReferralStepOnePage> {
}
String getRelationName() {
if (_selectedRelation != null)
return _selectedRelation.text;
if (_selectedRelation != null) {
if(projectViewModel.isArabic) {
return _selectedRelation.textAr;
}
return _selectedRelation.textEn;
}
else
return "Select Relationship" /*TranslationBase.of(context).selectHospital*/;
return TranslationBase.of(context).selectRelationship;
}
String getCountryName() {
if (_selectedCountry != null)
if (_selectedCountry != null) {
if(projectViewModel.isArabic) {
return _selectedCountry["name_ar"];
}
return _selectedCountry["name"];
}
else
return "Country";
}

@ -97,13 +97,13 @@ class _EReferralPageState extends State<EReferralPage>
Container(
width: MediaQuery.of(context).size.width * 0.37,
child: Center(
child: Texts("New Referral"),
child: Texts(TranslationBase.of(context).newReferral, textAlign: TextAlign.center,),
),
),
Container(
width: MediaQuery.of(context).size.width * 0.37,
child: Center(
child: Texts("Search for Referrals"),
child: Texts(TranslationBase.of(context).searchForReferrals , textAlign: TextAlign.center,),
),
),
],

@ -511,10 +511,10 @@ class _BMICalculatorState extends State<BMICalculator> {
context,
FadePage(
page: ResultPage(
finalResult: bmiResult,
textResult: textResult,
msg: msg,
)),
finalResult: bmiResult,
textResult: textResult,
msg: msg,
)),
);
}
})

@ -125,6 +125,16 @@ class _BmrCalculatorState extends State<BmrCalculator> {
isShowAppBar: true,
isShowDecPage: false,
appBarTitle: 'Bmr Calculator',
showHomeAppBarIcon: false,
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.white,
),
)
],
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0),
child: SingleChildScrollView(
@ -704,9 +714,9 @@ class _BmrCalculatorState extends State<BmrCalculator> {
context,
FadePage(
page: BmrResultPage(
bmrResult: bmrResult,
calories: calories,
)),
bmrResult: bmrResult,
calories: calories,
)),
);
}
});

@ -210,6 +210,16 @@ class _BodyFatState extends State<BodyFat> {
return AppScaffold(
isShowAppBar: true,
appBarTitle: 'Body Fat',
showHomeAppBarIcon: false,
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.white,
),
)
],
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0),
child: SingleChildScrollView(
@ -1004,10 +1014,10 @@ class _BodyFatState extends State<BodyFat> {
context,
FadePage(
page: FatResult(
bodyFat: bodyFat,
fat: fat,
textResult: textResult,
)),
bodyFat: bodyFat,
fat: fat,
textResult: textResult,
)),
);
}
});

@ -108,6 +108,16 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
isShowDecPage: false,
appBarTitle:
"${TranslationBase.of(context).calories} ${TranslationBase.of(context).calcHealth}",
showHomeAppBarIcon: false,
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.white,
),
)
],
body: Column(
children: [
Expanded(
@ -417,7 +427,9 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 0.0, horizontal: 18.0),
child: Center(child: Texts(TranslationBase.of(context).cm)),
child: Center(
child:
Texts(TranslationBase.of(context).cm)),
),
),
),
@ -446,11 +458,13 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
],
),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0),
child: Center(child: Texts(TranslationBase.of(context).feet))),
),
padding: const EdgeInsets.symmetric(
horizontal: 16.0),
child: Center(
child: Texts(
TranslationBase.of(context).feet))),
),
),
),
],
),
@ -465,7 +479,7 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
),
Container(
margin:
EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0),
EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0),
decoration: BoxDecoration(
color: Colors.white,
),
@ -514,8 +528,7 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
),
onTap: () {
setState(() {
if (weight < 250)
weight++;
if (weight < 250) weight++;
});
},
),
@ -589,7 +602,9 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 0.0, horizontal: 18.0),
child: Center(child: Texts(TranslationBase.of(context).kg)),
child: Center(
child:
Texts(TranslationBase.of(context).kg)),
),
),
),
@ -618,9 +633,11 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
],
),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0),
child: Center(child: Texts(TranslationBase.of(context).pound)),
padding: const EdgeInsets.symmetric(
horizontal: 16.0),
child: Center(
child: Texts(
TranslationBase.of(context).pound)),
),
),
),
@ -681,8 +698,8 @@ class _CalorieCalculatorState extends State<CalorieCalculator> {
context,
FadePage(
page: CalorieResultPage(
calorie: calories,
)),
calorie: calories,
)),
);
}
});

@ -82,6 +82,16 @@ class _CarbsState extends State<Carbs> {
return AppScaffold(
isShowAppBar: true,
appBarTitle: 'Carb Protein Fat',
showHomeAppBarIcon: false,
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.white,
),
)
],
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0),
child: SingleChildScrollView(
@ -201,7 +211,7 @@ class _CarbsState extends State<Carbs> {
),
Button(
backgroundColor: Color(0xffC5272D),
label: 'NOT SURE? CLICK HERE ',
label: 'NOT SURE? CLICK HERE',
onTap: () {
setState(() {
{
@ -341,16 +351,16 @@ class _CarbsState extends State<Carbs> {
context,
FadePage(
page: CarbsResult(
cCal: cCal,
pCal: pCal,
fCal: fCal,
pCalGram: pCalGram,
pCalMeal: pCalMeal,
fCalGram: fCalGram,
fCalMeal: fCalMeal,
cCalGram: cCalGram,
cCalMeal: cCalMeal,
)),
cCal: cCal,
pCal: pCal,
fCal: fCal,
pCalGram: pCalGram,
pCalMeal: pCalMeal,
fCalGram: fCalGram,
fCalMeal: fCalMeal,
cCalGram: cCalGram,
cCalMeal: cCalMeal,
)),
);
}
});

@ -102,6 +102,16 @@ class _IdealBodyState extends State<IdealBody> {
return AppScaffold(
isShowAppBar: true,
appBarTitle: 'Ideal Body Weight',
showHomeAppBarIcon: false,
appBarIcons: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Icon(
Icons.info_outline,
color: Colors.white,
),
)
],
body: Padding(
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 25.0),
child: SingleChildScrollView(
@ -518,7 +528,7 @@ class _IdealBodyState extends State<IdealBody> {
height: 30.0,
),
Container(
height: 100.0,
height: 50.0,
width: 350.0,
child: SecondaryButton(
label: 'CALCULATE',
@ -535,12 +545,12 @@ class _IdealBodyState extends State<IdealBody> {
context,
FadePage(
page: IdealBodyResult(
idealBodyWeight: idealWeight,
minRange: minRange,
mixRange: maxRange,
overWeightBy: overWeightBy,
textResult: textResult,
)),
idealBodyWeight: idealWeight,
minRange: minRange,
mixRange: maxRange,
overWeightBy: overWeightBy,
textResult: textResult,
)),
);
}
});

@ -254,7 +254,7 @@ class _BloodSugarState extends State<BloodSugar> {
),
Flexible(
child: Container(
height: 60.0,
height: 50.0,
width: 150.0,
child: SecondaryButton(
label: TranslationBase.of(context).calculate,

@ -64,12 +64,12 @@ class _PhamaciesLiveChatPageState extends State<PhamaciesLiveChatPage> {
),
),
bottomSheet: Container(
height: MediaQuery.of(context).size.height * 0.10,
height: MediaQuery.of(context).size.height * 0.11,
width: double.infinity,
padding: EdgeInsets.all(8.0),
child: Center(
child: Container(
height: MediaQuery.of(context).size.height * 0.87,
height: MediaQuery.of(context).size.height * 0.7,
width: MediaQuery.of(context).size.width * 0.8,
child: Button(
label: TranslationBase.of(context).start,

@ -47,80 +47,81 @@ class _AmbulanceRequestIndexPageState extends State<AmbulanceRequestIndexPage> {
Widget build(BuildContext context) {
return AppScaffold(
body: widget.amRequestViewModel.pickUpRequestPresOrder != null
? Column(
children: [
SizedBox(
height: 80,
),
Container(
margin: EdgeInsets.only(left: 18, right: 18),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2),
? SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 80,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
OrderLogItem(
title: TranslationBase.of(context).reqId,
value: widget.amRequestViewModel.pickUpRequestPresOrder
.presOrderID
.toString(),
),
OrderLogItem(
title: TranslationBase.of(context).status,
value: widget.amRequestViewModel.pickUpRequestPresOrder
.ambulateDescription,
),
OrderLogItem(
title: TranslationBase.of(context).pickupDate,
value: DateUtil.getDayMonthYearDateFormatted(
DateUtil.convertStringToDate(widget
.amRequestViewModel
.pickUpRequestPresOrder
.lastEditDate)),
),
OrderLogItem(
title: TranslationBase.of(context).pickupLocation,
value: widget.amRequestViewModel.pickUpRequestPresOrder
.pickupLocationName,
),
OrderLogItem(
title: TranslationBase.of(context).dropoffLocation,
value: widget.amRequestViewModel.pickUpRequestPresOrder
.dropoffLocationName,
),
OrderLogItem(
title: TranslationBase.of(context).transportMethod,
value: widget
.amRequestViewModel.pickUpRequestPresOrder.title,
),
Container(
padding: EdgeInsets.all(10),
width: double.maxFinite,
margin: EdgeInsets.only(bottom: 4, left: 4, right: 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(12),
bottomLeft: Radius.circular(12),
),
color: Colors.white),
child: SecondaryButton(
color: Colors.red[900],
textColor: Colors.white,
label: TranslationBase.of(context).cancel,
onTap: () {
widget.amRequestViewModel.updatePressOrder(
presOrderID: widget.amRequestViewModel
.pickUpRequestPresOrder.presOrderID);
},
Container(
margin: EdgeInsets.only(left: 18, right: 18),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
OrderLogItem(
title: TranslationBase.of(context).reqId,
value: widget.amRequestViewModel.pickUpRequestPresOrder
.presOrderID
.toString(),
),
)
],
OrderLogItem(
title: TranslationBase.of(context).status,
value: widget.amRequestViewModel.pickUpRequestPresOrder.status ==0?TranslationBase.of(context).pending:'',
),
OrderLogItem(
title: TranslationBase.of(context).pickupDate,
value: DateUtil.getDayMonthYearDateFormatted(
DateUtil.convertStringToDate(widget
.amRequestViewModel
.pickUpRequestPresOrder
.lastEditDate)),
),
OrderLogItem(
title: TranslationBase.of(context).pickupLocation,
value: widget.amRequestViewModel.pickUpRequestPresOrder
.pickupLocationName,
),
OrderLogItem(
title: TranslationBase.of(context).dropoffLocation,
value: widget.amRequestViewModel.pickUpRequestPresOrder
.dropoffLocationName,
),
OrderLogItem(
title: TranslationBase.of(context).transportMethod,
value: widget
.amRequestViewModel.pickUpRequestPresOrder.title,
),
Container(
padding: EdgeInsets.all(10),
width: double.maxFinite,
margin: EdgeInsets.only(bottom: 4, left: 4, right: 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(12),
bottomLeft: Radius.circular(12),
),
color: Colors.white),
child: SecondaryButton(
color: Colors.red[900],
textColor: Colors.white,
label: TranslationBase.of(context).cancel,
onTap: () {
widget.amRequestViewModel.updatePressOrder(
presOrderID: widget.amRequestViewModel
.pickUpRequestPresOrder.presOrderID);
},
),
)
],
),
),
),
],
)
],
),
)
: Column(
children: [
SizedBox(

@ -393,13 +393,14 @@ class _PickupLocationState extends State<PickupLocation> {
setState(() {
widget.patientER.pickupSpot = _isInsideHome ? 1 : 0;
if (widget.patientER.direction == 0) {
widget.patientER.pickupLocationLattitude =
widget.patientER.dropoffLocationLattitude =
_result.geometry.location.lat.toString();
widget.patientER.pickupLocationLongitude =
widget.patientER.dropoffLocationLongitude =
_result.geometry.location.lng.toString();
widget.patientER.dropoffLocationLattitude =
widget.patientER.pickupLocationLattitude =
_selectedHospital.latitude;
widget.patientER.dropoffLocationLongitude =
widget.patientER.pickupLocationLongitude =
_selectedHospital.longitude;
} else {
widget.patientER.pickupLocationLattitude =
@ -416,7 +417,7 @@ class _PickupLocationState extends State<PickupLocation> {
widget.patientER.pickupLocationLattitude;
widget.patientER.longitude =
widget.patientER.pickupLocationLongitude;
widget.patientER.dropoffLocationName = _selectedHospital.name;
widget.patientER.dropoffLocationName = widget.patientER.direction == 0?_result.formattedAddress:_selectedHospital.name;
widget.patientER.createdBy =
widget.amRequestViewModel.user.patientID;
widget.patientER.isOutPatient =
@ -425,7 +426,7 @@ class _PickupLocationState extends State<PickupLocation> {
widget.amRequestViewModel.user.patientIdentificationNo;
widget.patientER.pickupDateTime =
DateUtil.convertDateToStringLocation(DateTime.now());
widget.patientER.pickupLocationName = _result.formattedAddress;
widget.patientER.pickupLocationName = widget.patientER.direction == 0?_selectedHospital.name:_result.formattedAddress;
widget.patientER.projectID =
widget.amRequestViewModel.user.projectID;
widget.patientER.requesterFileNo =

@ -1,3 +1,4 @@
import 'package:diplomaticquarterapp/config/size_config.dart';
import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart';
import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart';
import 'package:diplomaticquarterapp/core/model/radiology/final_radiology.dart';
@ -25,6 +26,7 @@ import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart';
import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
@ -84,62 +86,62 @@ class _AppointmentActionsState extends State<AppointmentActions> {
onTap: () {
_handleButtonClicks(e);
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
// height: 100.0,
margin: EdgeInsets.all(7.0),
padding: EdgeInsets.only(bottom: 4.0),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey[400],
blurRadius: 2.0,
spreadRadius: 0.0)
child: Container(
margin: EdgeInsets.all(8.0),
padding: EdgeInsets.only(bottom: 4.0),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey[400],
blurRadius: 2.0,
spreadRadius: 0.0)
],
borderRadius: BorderRadius.circular(10),
color: Colors.white),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
margin:
EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
child: Texts(
e.title,
color: Color(0xffB8382C),
variant: "overline",
fontSize: SizeConfig.textMultiplier * 2.1,
),
),
Container(
margin:
EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0),
child: Texts(
e.subtitle,
color: Colors.black,
variant: "overline",
fontSize: SizeConfig.textMultiplier * 1.9,
),
),
],
borderRadius: BorderRadius.circular(10),
color: Colors.white),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
margin:
EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 0.0),
child: Text(e.title,
overflow: TextOverflow.clip,
style: TextStyle(
color: new Color(0xffB8382C),
letterSpacing: 1.0,
fontSize: 18.0)),
),
Container(
margin:
EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0),
child: Text(e.subtitle,
overflow: TextOverflow.clip,
style: TextStyle(
color: Colors.black,
letterSpacing: 1.0,
fontSize: 15.0)),
),
Container(
alignment: projectViewModel.isArabic
? Alignment.bottomLeft
: Alignment.bottomRight,
margin: projectViewModel.isArabic
? EdgeInsets.fromLTRB(
10.0, 7.0, 0.0, 8.0)
: EdgeInsets.fromLTRB(
0.0, 7.0, 10.0, 8.0),
child: Image.asset(e.icon,
width: 45.0, height: 45.0),
),
],
),
),
),
],
Container(
alignment: projectViewModel.isArabic
? Alignment.bottomLeft
: Alignment.bottomRight,
margin: projectViewModel.isArabic
? EdgeInsets.fromLTRB(
10.0, 7.0, 0.0, 8.0)
: EdgeInsets.fromLTRB(
0.0, 7.0, 10.0, 8.0),
child: Image.asset(e.icon,
width: 40.0, height: 40.0),
),
],
),
),
))
.toList(),

@ -0,0 +1,41 @@
import 'package:diplomaticquarterapp/uitl/location_util.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
import 'package:flutter/cupertino.dart';
class TestPage extends StatefulWidget{
@override
State<StatefulWidget> createState() => TestPageState();
}
class TestPageState extends State<TestPage>{
bool isGMS = false;
bool isHMS = false;
@override
void initState() {
super.initState();
// openStore();
location();
}
openStore() async{
openAppStore(androidPackageName: "com.ejada.hmg", iOSAppID: "733503978");
}
void location(){
LocationUtils().getCurrentLocation(callBack: (latLng){
debugPrint(latLng.toString());
});
}
@override
Widget build(BuildContext context) {
return Container(
);
}
}

@ -1,6 +1,8 @@
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/core/enum/viewstate.dart';
import 'package:diplomaticquarterapp/core/viewModels/feedback/feedback_view_model.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
@ -13,12 +15,15 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/input/text_field.dart';
import 'package:diplomaticquarterapp/widgets/others/StarRating.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/others/floating_button_search.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:speech_to_text/speech_recognition_error.dart';
import 'dart:convert';
import 'dart:io';
import 'appointment_history.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;
class SendFeedbackPage extends StatefulWidget {
@override
@ -35,8 +40,10 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
String message;
final formKey = GlobalKey<FormState>();
MessageType messageType = MessageType.NON;
var _currentLocaleId;
stt.SpeechToText speech = stt.SpeechToText();
var reconizedWord;
var event = RobotProvider();
String getSelected(BuildContext context) {
switch (messageType) {
case MessageType.ComplaintOnAnAppointment:
@ -61,13 +68,10 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
return TranslationBase.of(context).notClassified;
}
setMessageType(MessageType messageType) {
setState(() {
this.messageType = messageType;
});
setState(() {
this.messageType = messageType;
});
}
@override
@ -116,7 +120,7 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
getSelected(context),
variant: 'bodyText',
),
margin: EdgeInsets.only(left: 10,right: 10),
margin: EdgeInsets.only(left: 10, right: 10),
),
Icon(
Icons.arrow_drop_down,
@ -127,8 +131,8 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
),
),
),
if (appointHistory != null && messageType ==
MessageType.ComplaintOnAnAppointment)
if (appointHistory != null &&
messageType == MessageType.ComplaintOnAnAppointment)
InkWell(
onTap: () {
setState(() {
@ -203,10 +207,13 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
),
),
),
if (messageType == MessageType.ComplaintOnAnAppointment && model.appointHistoryList.length != 0 &&
if (messageType == MessageType.ComplaintOnAnAppointment &&
model.appointHistoryList.length != 0 &&
isShowListAppointHistory)
Container(
height: model.appointHistoryList.length>2?MediaQuery.of(context).size.height * 0.25:MediaQuery.of(context).size.height * 0.15,
height: model.appointHistoryList.length > 2
? MediaQuery.of(context).size.height * 0.25
: MediaQuery.of(context).size.height * 0.15,
child: ListView.builder(
itemCount: model.appointHistoryList.length,
itemBuilder: (context, index) => InkWell(
@ -336,6 +343,10 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
maxLines: 25,
minLines: 13,
controller: messageController,
suffixIcon: Icons.mic,
onSuffixTap: () {
openSpeechReco();
},
validator: (value) {
if (value.isEmpty)
return TranslationBase.of(context).emptyMessage;
@ -345,11 +356,12 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
),
InkWell(
onTap: () {
ImageOptions.showImageOptions(context, (String image,File file) {
ImageOptions.showImageOptions(context,
(String image, File file) {
setState(() {
images.add(image);
});
} );
});
},
child: Container(
margin: EdgeInsets.only(left: 10, right: 10, top: 15),
@ -427,18 +439,21 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
child: SecondaryButton(
label: TranslationBase.of(context).send,
textColor: Colors.white,
disabled: (titleController.text.toString().isEmpty || messageController.text.toString().isEmpty|| messageType == MessageType.NON),
disabled: (titleController.text.toString().isEmpty ||
messageController.text.toString().isEmpty ||
messageType == MessageType.NON),
onTap: () {
final form = formKey.currentState;
if (form.validate())
if (messageType != MessageType.NON){
GifLoaderDialogUtils.showMyDialog(context);
model.sendCOCItem(
if (form.validate()) if (messageType != MessageType.NON) {
GifLoaderDialogUtils.showMyDialog(context);
model
.sendCOCItem(
title: titleController.text,
attachment: images.length > 0 ? images[0] : "",
details: messageController.text,
cOCTypeName: getCOCName(),
appointHistory:messageType == MessageType.ComplaintOnAnAppointment
appointHistory: messageType ==
MessageType.ComplaintOnAnAppointment
? appointHistory
: null)
.then((value) {
@ -456,9 +471,10 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
AppToast.showErrorToast(message: model.error);
GifLoaderDialogUtils.hideDialog(context);
}
});}
else {
AppToast.showErrorToast(message: TranslationBase.of(context).selectPart);
});
} else {
AppToast.showErrorToast(
message: TranslationBase.of(context).selectPart);
}
},
),
@ -513,28 +529,64 @@ class _SendFeedbackPageState extends State<SendFeedbackPage> {
},
));
}
openSpeechReco() async {
new RoboSearch(context: context).showAlertDialog(context);
_currentLocaleId =
TranslationBase.of(AppGlobal.context).locale.languageCode;
bool available = await speech.initialize(
onStatus: statusListener, onError: errorListener);
if (available) {
speech.listen(
onResult: resultListener,
// listenMode: ListenMode.confirmation,
localeId: _currentLocaleId == 'en' ? 'en-US' : 'ar-SA',
);
} else {
print("The user has denied the use of speech recognition.");
}
}
void errorListener(SpeechRecognitionError error) {}
void statusListener(String status) {
reconizedWord = status == 'listening' ? 'Lisening...' : 'Sorry....';
}
void resultListener(result) {
reconizedWord = result.recognizedWords;
event.setValue({"searchText": reconizedWord});
if (result.finalResult == true) {
setState(() {
RoboSearch.closeAlertDialog(context);
messageController.text = reconizedWord;
});
}
}
}
class FeedbackTypeDialog extends StatefulWidget {
final Function(MessageType) onValueSelected;
final MessageType messageTypeDialog;
const FeedbackTypeDialog({Key key, this.onValueSelected, this.messageTypeDialog=MessageType.NON}) : super(key: key);
const FeedbackTypeDialog(
{Key key, this.onValueSelected, this.messageTypeDialog = MessageType.NON})
: super(key: key);
@override
State createState() => new FeedbackTypeDialogState();
}
class FeedbackTypeDialogState extends State<FeedbackTypeDialog> {
MessageType messageTypeDialog = MessageType.NON;
setMessageDialogType(MessageType messageType) {
setState(() {
messageTypeDialog = messageType;
});
setState(() {
messageTypeDialog = messageType;
});
}
@override
void initState() {
messageTypeDialog = widget.messageTypeDialog;
@ -562,10 +614,10 @@ class FeedbackTypeDialogState extends State<FeedbackTypeDialog> {
Expanded(
flex: 1,
child: InkWell(
onTap: () => setMessageDialogType(
MessageType.NON),
onTap: () => setMessageDialogType(MessageType.NON),
child: ListTile(
title: Texts(TranslationBase.of(context).notClassified),
title:
Texts(TranslationBase.of(context).notClassified),
leading: Radio(
value: MessageType.NON,
groupValue: messageTypeDialog,
@ -589,7 +641,8 @@ class FeedbackTypeDialogState extends State<FeedbackTypeDialog> {
onTap: () => setMessageDialogType(
MessageType.ComplaintOnAnAppointment),
child: ListTile(
title: Texts(TranslationBase.of(context).complainAppo),
title:
Texts(TranslationBase.of(context).complainAppo),
leading: Radio(
value: MessageType.ComplaintOnAnAppointment,
groupValue: messageTypeDialog,
@ -613,7 +666,8 @@ class FeedbackTypeDialogState extends State<FeedbackTypeDialog> {
onTap: () => setMessageDialogType(
MessageType.ComplaintWithoutAppointment),
child: ListTile(
title: Texts(TranslationBase.of(context).complainWithoutAppo),
title: Texts(
TranslationBase.of(context).complainWithoutAppo),
leading: Radio(
value: MessageType.ComplaintWithoutAppointment,
groupValue: messageTypeDialog,
@ -634,8 +688,7 @@ class FeedbackTypeDialogState extends State<FeedbackTypeDialog> {
Expanded(
flex: 1,
child: InkWell(
onTap: () =>
setMessageDialogType(MessageType.Question),
onTap: () => setMessageDialogType(MessageType.Question),
child: ListTile(
title: Texts(TranslationBase.of(context).question),
leading: Radio(
@ -690,7 +743,8 @@ class FeedbackTypeDialogState extends State<FeedbackTypeDialog> {
value: MessageType.Suggestion,
groupValue: messageTypeDialog,
activeColor: Theme.of(context).primaryColor,
onChanged: (MessageType value) => setMessageDialogType(value),
onChanged: (MessageType value) =>
setMessageDialogType(value),
),
),
),
@ -745,7 +799,7 @@ class FeedbackTypeDialogState extends State<FeedbackTypeDialog> {
padding: const EdgeInsets.all(8.0),
child: Center(
child: Texts(
TranslationBase.of(context).ok,
TranslationBase.of(context).ok,
fontWeight: FontWeight.w400,
)),
),

@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/core/viewModels/feedback/feedback_view_mode
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/button.dart';
import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/cupertino.dart';
@ -100,6 +101,23 @@ class _StatusFeedbackPageState extends State<StatusFeedbackPage> {
),
),
),
bottomSheet: Container(
height: MediaQuery.of(context).size.height * 0.12,
width: double.infinity,
padding: EdgeInsets.all(15.0),
child: Center(
child: Container(
height: MediaQuery.of(context).size.height * 0.1,
child: SecondaryButton(
label: TranslationBase.of(context).search,
textColor: Colors.white,
disabled: true,
onTap: () {
},
),
),
),
),
),
);
}

@ -1,4 +1,5 @@
import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart';
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
@ -7,7 +8,8 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget
import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter/src/widgets/image.dart' as flutterImage;
import 'base/base_view.dart';
class FinalProductsPage extends StatefulWidget {
@ -124,7 +126,8 @@ class _FinalProductsPageState extends State<FinalProductsPage> {
),
styleOne == true
? Expanded(
child: Container(
child:model.finalProducts.length > 0
? Container(
height: MediaQuery.of(context).size.height * 3.90,
child: GridView.builder(
gridDelegate:
@ -355,10 +358,33 @@ class _FinalProductsPageState extends State<FinalProductsPage> {
));
},
),
),
)
)
: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Align(
alignment: Alignment.center,
child: Image.asset(
'assets/images/pharmacy/empty_box.png',
width: 100,
height: 100,
),
),
Text(
TranslationBase.of(context).noResult,
style: TextStyle(
fontSize: 20.0,
// fontWeight: FontWeight.bold,
),
),
],
),
),)
: Expanded(
child: Container(
child: model.finalProducts.length > 0
? Container(
height: MediaQuery.of(context).size.height * 5.0,
child: ListView.builder(
itemCount: model.finalProducts.length,
@ -546,6 +572,29 @@ class _FinalProductsPageState extends State<FinalProductsPage> {
},
);
}),
)
: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Align(
alignment: Alignment.center,
child: Image.asset(
'assets/images/pharmacy/empty_box.png',
width: 100,
height: 100,
),
),
Text(
TranslationBase.of(context).noResult,
style: TextStyle(
fontSize: 20.0,
// fontWeight: FontWeight.bold,
),
),
],
),
),
)
],

@ -362,7 +362,7 @@ class _HomePageState extends State<HomePage> {
height: 5,
),
Texts(
'${DateUtil.getMonthDayYearDateFormatted(model.user.dateofBirthDataTime)} ,${model.user.genderDescription} ${model.user.ageDesc}',
'${DateUtil.getMonthDayYearDateFormatted(model.user.dateofBirthDataTime)} ,${model.user.gender == 1 ? TranslationBase.of(context).male : TranslationBase.of(context).female} ${model.user.age.toString() + "y"}',
color: Colors.grey[100],
fontWeight: FontWeight.normal,
fontSize: 14,
@ -391,9 +391,10 @@ class _HomePageState extends State<HomePage> {
child: Center(
child: Texts(
TranslationBase.of(context)
.viewMore,
.myMedicalFile,
color: Colors.white,
fontSize: 12,
textAlign: TextAlign.center,
),
),
),
@ -465,23 +466,27 @@ class _HomePageState extends State<HomePage> {
],
),
Padding(
padding: const EdgeInsets.only(bottom: 15, right: 15, left: 15),
padding:
const EdgeInsets.only(bottom: 15, right: 15, left: 15),
child: InkWell(
onTap: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage()));
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => PackagesHomePage()));
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color(0xffB8382C),
borderRadius: BorderRadius.circular(10),
color: Color(0xffB8382C),
),
child: Padding(
padding: const EdgeInsets.all(8),
child: Row(
children: [
Texts(
TranslationBase.of(context).offerAndPackages,
color: Colors.white, fontSize: 20, fontWeight: FontWeight.normal,
TranslationBase.of(context).offerAndPackages,
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.normal,
),
Spacer(),
Image.asset("assets/images/offer_icon.png"),
@ -840,7 +845,7 @@ class _HomePageState extends State<HomePage> {
}
getPharmacyToken(DashboardViewModel model) async {
if(!model.isLogin) {
if (!model.isLogin) {
Navigator.push(context, FadePage(page: LandingPagePharmacy()));
} else {
GifLoaderDialogUtils.showMyDialog(context);

@ -543,7 +543,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
children: [
HomePage(
goToMyProfile: () {
_changeCurrentTab(0);
_changeCurrentTab(1);
},
),
MedicalProfilePage(),

@ -31,6 +31,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:local_auth/auth_strings.dart';
import 'package:local_auth/local_auth.dart';
import 'package:provider/provider.dart';
// import 'package:smart_progress_bar/smart_progress_bar.dart';
@ -383,10 +384,21 @@ class _ConfirmLogin extends State<ConfirmLogin> {
loginWithFingurePrintFace(type, isActive) async {
if (isActive == 1) {
// this.startBiometricLoginIfAvailable();
authenticated = await auth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to authenticate',
useErrorDialogs: true,
stickyAuth: true);
const iosStrings = const IOSAuthMessages(
cancelButton: 'cancel',
goToSettingsButton: 'settings',
goToSettingsDescription: 'Please set up your Touch ID.',
lockOut: 'Please reenable your Touch ID');
try {
authenticated = await auth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to authenticate',
useErrorDialogs: true,
stickyAuth: true,
iOSAuthStrings: iosStrings);
} on PlatformException catch (e) {
AppToast.showErrorToast(message: e.toString());
}
if (authenticated == true) {
if (user != null && (user.logInType == 2 || user.logInType == 3)) {
@ -530,6 +542,7 @@ class _ConfirmLogin extends State<ConfirmLogin> {
userData = result.list,
// sharedPref.setString(
// BLOOD_TYPE, result['PatientBloodType']),
authenticatedUserObject.user = result.list,
sharedPref.setObject(MAIN_USER, result.list),
sharedPref.setObject(USER_PROFILE, result.list),
loginTokenID = result.logInTokenID,

@ -21,7 +21,7 @@ class _ForgotPassword extends State<ForgotPassword> {
String selectedType = 'Saudi Arabia';
String countryCode = '966';
final TextEditingController nationalIDorFile = null;
String mobileNo;
String mobileNo = "";
var con;
@override
Widget build(BuildContext context) {
@ -53,9 +53,15 @@ class _ForgotPassword extends State<ForgotPassword> {
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[],
),
MobileNo(
onNumberChange: (value) => {mobileNo = value},
onCountryChange: (value) => countryCode = value),
MobileNo(onNumberChange: (value) {
setState(() {
mobileNo = value;
});
}, onCountryChange: (value) {
setState(() {
countryCode = value;
});
}),
],
),
),
@ -73,6 +79,10 @@ class _ForgotPassword extends State<ForgotPassword> {
sendPatientIDBySMS();
// print(mobileNo.text);
},
color: mobileNo.length >= 9 == true
? Colors.grey[900]
: Colors.grey,
textColor: Colors.white,
)),
],
),
@ -85,7 +95,7 @@ class _ForgotPassword extends State<ForgotPassword> {
sendPatientIDBySMS() {
GifLoaderDialogUtils.showMyDialog(context);
final authService = new AuthProvider();
authService.sendPatientIDSMS(mobileNo, context).then((res) {
authService.sendPatientIDSMS(mobileNo, countryCode, context).then((res) {
GifLoaderDialogUtils.hideDialog(context);
if (res['MessageStatus'] == 1) {
this.startSMSService(mobileNo, res['LogInTokenID']);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save