Android library project that lets you manage the location updates to be as painless as possible

Overview

Smart Location Library

Android Arsenal Build Status

Android library project that intends to simplify the usage of location providers and activity recognition with a nice fluid API.

Supported Android versions: Android 4.0+

Adding to your project

You should add this to your dependencies:

implement 'io.nlopez.smartlocation:library:3.3.3'

Google Play Services compatible version: 11.4.2

If you want the rxjava wrappers, these are now in a separate dependency. Just add this new dependency as well:

implement 'io.nlopez.smartlocation:rx:3.3.3'

If you got any problem compiling, please check the Common Issues section at the bottom of this document.

Location

Starting

For starting the location service:

SmartLocation.with(context).location()
    .start(new OnLocationUpdatedListener() { ... });

If you just want to get a single location (not periodic) you can just use the oneFix modifier. Example:

SmartLocation.with(context).location()
    .oneFix()
    .start(new OnLocationUpdatedListener() { ... });

Stopping

For stopping the location just use the stop method.

SmartLocation.with(context).location().stop();

Status

You can get some information about the current status of location providers to know if you will be able to use the location providers.

// Check if the location services are enabled
SmartLocation.with(context).location().state().locationServicesEnabled();

// Check if any provider (network or gps) is enabled
SmartLocation.with(context).location().state().isAnyProviderAvailable();

// Check if GPS is available
SmartLocation.with(context).location().state().isGpsAvailable();

// Check if Network is available
SmartLocation.with(context).location().state().isNetworkAvailable();

// Check if the passive provider is available
SmartLocation.with(context).location().state().isPassiveAvailable();

// Check if the location is mocked
SmartLocation.with(context).location().state().isMockSettingEnabled();

Location strategy

There are three presets for location parameters:

  • LocationParams.BEST_EFFORT (default)
  • LocationParams.NAVIGATION
  • LocationParams.LAZY

You can change it (if you want one other than the default one) by using the config(locationParams) modifier.

If you want to add some custom parameters for the distances or times involved in the location strategy, you can create your own LocationParams class.

Changing providers

There are some providers shipped with the library.

  • LocationGooglePlayServicesWithFallbackProvider (default). This one will use the Fused Location Provider if it's present, or the LocationManager as fallback if it's not.
  • LocationGooglePlayServicesProvider This will use the Fused Location Provider.
  • LocationManagerProvider This is the legacy implementation that uses LocationManager.
  • LocationBasedOnActivityProvider This allows you to use the activity recognition system to modify the location strategy depending on the activity changes (if the user is walking, running, on a car, a bike...).
  • MultiFallbackLocationProvider This lets you create your own "fallback provider" if the underlying location service is not available. See "Multiple Fallback Provider" below for details.

You can implement your own if you want. That's ideal if you wanted to use a mock one for testing or something like that, or add support to another possible provider.

Example:

SmartLocation.with(context).location(new LocationBasedOnActivityProvider(callback))
    .start(new OnLocationUpdatedListener() { ... });

Multiple Fallback Provider

The MultiFallbackProvider lets you create your own provider that utilizes multiple underlying location services. The provider will use the location services in the order in which they are added to its Builder, which has convenience methods for setting up the Google Play Services provider and the default LocationManager provider. Providers must implement the ServiceLocationProvider interface to enable the fallback behavior. Example:

LocationProvider myProvider = new MyLocationProvider();
LocationProvider fallbackProvider = new MultiFallbackProvider.Builder()
    .withGooglePlayServicesProvider().withProvider(myProvider).build();

Activity

Starting

For starting the activity recognition service, you should run:

SmartLocation.with(context).activityRecognition()
    .start(new OnActivityUpdatedListener() { ... });

Stopping

For stopping the activity recognition you could use the stop method.

SmartLocation.with(context).activityRecognition().stop();

Geofencing

We can add geofences and receive the information when we enter, exit or dwell in a Geofence. The geofences are defined by a GeofenceModel, and you should use the requestId as a identifier.

We can add and remove geofences with a similar syntax as all the others.

GeofenceModel mestalla = new GeofenceModel.Builder("id_mestalla")
    .setTransition(Geofence.GEOFENCE_TRANSITION_ENTER)
    .setLatitude(39.47453120000001)
    .setLongitude(-0.358065799999963)
    .setRadius(500)
    .build();

GeofenceModel cuenca = new GeofenceModel.Builder("id_cuenca")
    .setTransition(Geofence.GEOFENCE_TRANSITION_EXIT)
    .setLatitude(40.0703925)
    .setLongitude(-2.1374161999999615)
    .setRadius(2000)
    .build();

SmartLocation.with(context).geofencing()
    .add(mestalla)
    .add(cuenca)
    .remove("already_existing_geofence_id")
    .start(new OnGeofencingTransitionListener() { ... });

If you want to capture the Geofence transitions without the app running, you can hook up a BroadcastReceiver to the intent action stored in the GeofencingGooglePlayServicesProvider.BROADCAST_INTENT_ACTION constant. The intent will come with the geofence, the location and the type of transition within the bundle.

Geocoding

The library has support for direct geocoding (aka getting a Location object based on a String) and reverse geocoding (getting the Street name based on a Location object).

There are pretty basic calls in the API for both operations separatedly.

Direct geocoding

SmartLocation.with(context).geocoding()
    .direct("Estadi de Mestalla", new OnGeocodingListener() {
        @Override
        public void onLocationResolved(String name, List<LocationAddress> results) {
            // name is the same you introduced in the parameters of the call
            // results could come empty if there is no match, so please add some checks around that
            // LocationAddress is a wrapper class for Address that has a Location based on its data
            if (results.size() > 0) {
            	Location mestallaLocation = results.get(0).getLocation();
            	// [...] Do your thing! :D
            }
        }
    });

Reverse geocoding

SmartLocation.with(context).geocoding()
    .reverse(location, new OnReverseGeocodingListener() {
        @Override
        public onAddressResolved(Location original, List<Address> results) {
            // ...
        }
    });

Mixing things up

But we can mix and batch those requests, if needed. Also, you can provide the number of maximum possible matches you want to receive for each one of the lookups separatedly.

Location myLocation1 = new Location(...);

SmartLocation.with(context).geocoding()
    .add("Estadi de Mestalla", 5)
    .add("Big Ben", 2)
    .add(myLocation1, 4)
    .start(directGeocodingListener, reverseGeocodingListener);

This will launch a new call to the callbacks everytime one of the geofence lookups is resolved.

Stopping

You should invoke the stop method whenever the calling activity/fragment or whatever is going to be destroyed, for cleanup purposes.

RxJava / RxAndroid support

The wrappers to rxjava2 are located in this package.

implement 'io.nlopez.smartlocation:rx:3.3.1'

You can wrap the calls with ObservableFactory methods to retrieve an Observable object. You won't need to call start, just subscribe to the observable to get the updates.

For example, for location:

Observable<Location> locationObservable = ObservableFactory.from(SmartLocation.with(context).location());
locationObservable.subscribe(new Action1<Location>() {
    @Override
    public void call(Location location) {
        // Do your stuff here :)
    }
});

Common issues

If you are already using Google Play Services in your project and have problems compiling, you can try setting the transitive property to false:

implement ('io.nlopez.smartlocation:library:3.3.3') {
	transitive = false
}

If you got an error in the manifest merging, like this one:

> Manifest merger failed : Attribute meta-data#com.google.android.gms.version@value value=(@integer/google_play_services_version) from AndroidManifest.xml:44:13
    is also present at io.nlopez.smartlocation:library:3.0.5:28:13 value=(6587000)
    Suggestion: add 'tools:replace="android:value"' to <meta-data> element at AndroidManifest.xml:42:9 to override


    Error:(46, 13) Attribute meta-data#com.google.android.gms.version@value value=(@integer/google_play_services_version) from AndroidManifest.xml:46:13

If you follow the suggestion provided, you can get rid of it easily. Just change in your manifest the meta-data tag with the google play services version, like this:

<meta-data tools:replace="android:value" android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

Contributing

Forks, patches and other feedback are welcome.

Creators

Nacho López @mrmans0n

License

The MIT License (MIT)

Copyright (c) 2013-2017 Nacho Lopez

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • Error:(79, 0) No such property: sonatypeRepo for class: org.gradle.api.publication.maven.internal.deployer.DefaultGroovyMavenDeployer

    Error:(79, 0) No such property: sonatypeRepo for class: org.gradle.api.publication.maven.internal.deployer.DefaultGroovyMavenDeployer

    I've just cloned the repo, imported to Android Studio and gradle sync failed with:

    Error:(79, 0) No such property: sonatypeRepo for class: org.gradle.api.publication.maven.internal.deployer.DefaultGroovyMavenDeployer
    <a href="openFile:/home/fr/githubzz/smart-location-lib/library/build.gradle">Open File</a>
    
    opened by farmazon3000 10
  • Timeout for one fix.

    Timeout for one fix.

    Is there timeout for

    SmartLocation.with(getActivity()).location() .oneFix() .start(new OnLocationUpdatedListener() { @Override public void onLocationUpdated(Location location) {

    }}

    Because I would like to have a one fix that happens every time I send something to a server. But I have waited over 2 1/2 hours hoping that something would kick off but as i write this the device is still stuck.

    Im checking to make sure google services are installed as well as SmartLocation.with(getActivity()).location().state().isAnyProviderAvailable() & SmartLocation.with(getActivity()).location().state().locationServicesEnabled() before I even attempt to get the location but it passes all of the checks and then just sits until I close the application. I would love a time out if that is possible.

    opened by adfleshner 8
  • Location settings popup if location is disabled.

    Location settings popup if location is disabled.

    Hello,

    Thanks for this awesome library.

    Any chance to have the functionality to show Location Settings Dialog if device's location services are disabled?

    I found this code provided by Google which does exactly the same. But its too much of code and its redundant to initialize Google Play Services again if to be done manually.

    https://github.com/googlesamples/android-play-location/blob/master/LocationSettings/app/src/main/java/com/google/android/gms/location/sample/locationsettings/MainActivity.java

    Thanks in advance.

    enhancement 
    opened by xaxist 8
  • Its crashing with Google plus library

    Its crashing with Google plus library

    I was really happy when I made my project worked using this library but on final testing I found that my "Goolge plus login" screen was clashing with this. I removed the google login and it worked. This was the line where the google login was crashing : mGoogleApiClient = new GoogleApiClient.Builder(activity) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this).addApi(Plus.API) .addScope(Plus.SCOPE_PLUS_LOGIN).build();

    Unfortunately I didn't find a single solution of this problem on Google so left writing here.

    Edit 1 : I removed the smart-location-lib and all worked fine Edit 2 : I removed Google plus login screen and all worked fine. Edit 3 : I have added tools:replace attribute on manifest

    Staketrace of error

    10-08 08:53:14.898 18895-18895/? E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.irinnovative.peepinnow, PID: 18895 java.lang.NoSuchMethodError: No virtual method zzog()Landroid/accounts/Account; in class Lcom/google/android/gms/common/internal/zzf; or its super classes (declaration of 'com.google.android.gms.common.internal.zzf' appears in /data/app/com.irinnovative.peepinnow-2/base.apk) at com.google.android.gms.plus.Plus$1.zza(Unknown Source) at com.google.android.gms.plus.Plus$1.zza(Unknown Source) at com.google.android.gms.internal.zzli.zza(Unknown Source) at com.google.android.gms.internal.zzli.(Unknown Source) at com.google.android.gms.common.api.GoogleApiClient$Builder.build(Unknown Source) at com.irinnovative.peepinnow.fragments.FragmentGoogleLogin.setupGoooglePlus(FragmentGoogleLogin.java:120) at com.irinnovative.peepinnow.fragments.FragmentGoogleLogin.onCreateView(FragmentGoogleLogin.java:111) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1026) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1207) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1572) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:493) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5290) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

    screen shot 2015-10-08 at 8 47 45 am
    opened by irfaan008 7
  • FATAL EXCEPTION with  Google Play Services 6.5.87

    FATAL EXCEPTION with Google Play Services 6.5.87

    FATAL EXCEPTION http://stackoverflow.com/questions/27372638/android-play-services-6-5-locationclient-is-missing

    12-11 09:10:36.758  26218-26218/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
        Process: xxx, PID: 26218
        java.lang.NoClassDefFoundError: com.google.android.gms.location.LocationClient
                at io.nlopez.smartlocation.SmartLocationService.initLocation(SmartLocationService.java:90)
                at io.nlopez.smartlocation.SmartLocationService.onCreate(SmartLocationService.java:75)
                at android.app.ActivityThread.handleCreateService(ActivityThread.java:2558)
                at android.app.ActivityThread.access$1800(ActivityThread.java:135)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:136)
                at android.app.ActivityThread.main(ActivityThread.java:5001)
                at java.lang.reflect.Method.invokeNative(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:515)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
                at dalvik.system.NativeStart.main(Native Method)
    
    enhancement 
    opened by kamilwlf 7
  • Memory leak

    Memory leak

    Samsung Galaxy S7 on Android 7.0 Using SmartLocation version 3.3.2

    LeakCanary info:

    In com.companyname.appname.development:1.0-development:1.
    * com.companyname.appname.activities.TaskCheckoutActivity has leaked:
    * GC ROOT com.google.android.gms.internal.zzbyw.zzfwc
    * references com.google.android.gms.internal.zzbyt.zzhyy
    * references io.nlopez.smartlocation.location.providers.LocationGooglePlayServicesProvider.context
    * leaks com.companyname.appname.activities.TaskCheckoutActivity instance
    
    * Retaining: 1,6 MB.
    * Reference Key: ba2a19b1-d5ca-4971-a5c7-e0fd99ea95a6
    * Device: samsung samsung SM-G930F heroltexx
    * Android Version: 7.0 API: 24 LeakCanary: 1.5.4 74837f0
    * Durations: watch=5010ms, gc=215ms, heap dump=1792ms, analysis=128865ms
    
    * Details:
    * Instance of com.google.android.gms.internal.zzbyw
    |   static $classOverhead = byte[752]@858164225 (0x33268c01)
    |   zzfwc = com.google.android.gms.internal.zzbyt@861919192 (0x335fd7d8)
    |   mDescriptor = java.lang.String@854648480 (0x32f0e6a0)
    |   mObject = 501026202704
    |   mOwner = com.google.android.gms.internal.zzbyw@856066112 (0x33068840)
    |   shadow$_klass_ = com.google.android.gms.internal.zzbyw
    |   shadow$_monitor_ = 0
    * Instance of com.google.android.gms.internal.zzbyt
    |   static $classOverhead = byte[792]@855184385 (0x32f91401)
    |   zzhyy = io.nlopez.smartlocation.location.providers.LocationGooglePlayServicesProvider@856875576 (0x3312e238)
    |   zzfda = com.google.android.gms.common.api.Api@856792448 (0x33119d80)
    |   zzfip = com.google.android.gms.common.api.Api$zzf@854593816 (0x32f01118)
    |   mStatus = com.google.android.gms.common.api.Status@856929688 (0x3313b598)
    |   zzaj = true
    |   zzaop = java.util.concurrent.CountDownLatch@855708832 (0x330114a0)
    |   zzfhl = com.google.android.gms.common.api.Status@856929688 (0x3313b598)
    |   zzfiz = java.lang.Object@854593632 (0x32f01060)
    |   zzfja = com.google.android.gms.common.api.internal.zzu@856066144 (0x33068860)
    |   zzfjb = java.lang.ref.WeakReference@857866976 (0x332202e0)
    |   zzfjc = java.util.ArrayList@857867120 (0x33220370)
    |   zzfjd = null
    |   zzfje = java.util.concurrent.atomic.AtomicReference@855708848 (0x330114b0)
    |   zzfjf = null
    |   zzfjg = false
    |   zzfjh = false
    |   zzfji = null
    |   zzfjj = null
    |   zzfjk = false
    |   shadow$_klass_ = com.google.android.gms.internal.zzbyt
    |   shadow$_monitor_ = -1953408656
    * Instance of io.nlopez.smartlocation.location.providers.LocationGooglePlayServicesProvider
    |   static REQUEST_CHECK_SETTINGS = 20001
    |   static GMS_ID = java.lang.String@856784656 (0x33117f10)
    |   static $classOverhead = byte[748]@857097217 (0x33164401)
    |   static REQUEST_START_LOCATION_FIX = 10001
    |   alwaysShow = true
    |   checkLocationSettings = false
    |   client = com.google.android.gms.common.api.internal.zzbd@856996208 (0x3314b970)
    |   context = com.companyname.appname.activities.TaskCheckoutActivity@860313600 (0x33475800)
    |   fulfilledCheckLocationSettings = false
    |   googlePlayServicesListener = io.nlopez.smartlocation.location.providers.LocationGooglePlayServicesWithFallbackProvider@856791392 (0x33119960)
    |   listener = com.companyname.appname.activities.TaskCheckoutActivity$1@856799680 (0x3311b9c0)
    |   locationRequest = com.google.android.gms.location.LocationRequest@856876304 (0x3312e510)
    |   locationStore = io.nlopez.smartlocation.location.LocationStore@859517520 (0x333b3250)
    |   logger = io.nlopez.smartlocation.utils.LoggerFactory$Sssht@854569160 (0x32efb0c8)
    |   serviceListener = null
    |   settingsResultCallback = io.nlopez.smartlocation.location.providers.LocationGooglePlayServicesProvider$1@856798672 (0x3311b5d0)
    |   shouldStart = false
    |   stopped = true
    |   shadow$_klass_ = io.nlopez.smartlocation.location.providers.LocationGooglePlayServicesProvider
    |   shadow$_monitor_ = -2147272239
    * Instance of com.companyname.appname.activities.TaskCheckoutActivity
    |   static $classOverhead = byte[4720]@856289281 (0x3309f001)
    |   BARCODE_SCANNER_REQUEST = java.lang.Integer@856384016 (0x330b6210)
    |   BEGIN_SIGNATURE_REQUEST = java.lang.Integer@856384000 (0x330b6200)
    |   mApiKey = java.lang.String@856965696 (0x33144240)
    |   mCheckoutEmptyStepView = null
    |   mCurrentLocation = android.location.Location@859607248 (0x333c90d0)
    |   mDamagedAddressUnknownDescriptionCheckFailed = java.lang.Boolean@1881937168 (0x702c1510)
    |   mDamagedAddressUnknownDescriptionEditText = null
    |   mDamagedAddressUnknownStepView = null
    |   mJobManager = com.birbit.android.jobqueue.JobManager@851730080 (0x32c45ea0)
    |   mKibCardInputCheckFailed = java.lang.Boolean@1881937168 (0x702c1510)
    |   mKibCardInputEditText = null
    |   mKibCardInputStepView = null
    |   mKibCardNextTimeframe = null
    |   mKibNextAbbrevation = null
    |   mKibNextDay = null
    |   mMarginBetweenStatusAndIcons = android.support.v7.widget.AppCompatTextView@860264448 (0x33469800)
    |   mNameCheckFailed = java.lang.Boolean@1881937168 (0x702c1510)
    |   mNeighbourAddressStepView = null
    |   mNeighbourCityFailed = java.lang.Boolean@1881937168 (0x702c1510)
    |   mNeighbourCityInputEditText = null
    |   mNeighbourStreetFailed = java.lang.Boolean@1881937168 (0x702c1510)
    |   mNeighbourStreetInputEditText = null
    |   mNeighbourStreetNumberFailed = java.lang.Boolean@1881937152 (0x702c1500)
    |   mNeighbourStreetNumberInputEditText = null
    |   mNeighbourZipcodeFailed = java.lang.Boolean@1881937168 (0x702c1510)
    |   mNeighbourZipcodeInputEditText = null
    |   mOpenBarcodeScannerButton = null
    |   mParcelKey = java.lang.String@856985856 (0x33149100)
    |   mPaymentCompleted = java.lang.Boolean@1881937168 (0x702c1510)
    |   mPaymentStepView = null
    |   mPaymentSwitch = null
    |   mPaymentTextView = null
    |   mRecipientContainer = android.widget.RelativeLayout@860361728 (0x33481400)
    |   mRecipientNameEditText = android.widget.EditText@860366848 (0x33482800)
    |   mRefusedReasonCheckFailed = java.lang.Boolean@1881937168 (0x702c1510)
    |   mRefusedReasonEditText = null
    |   mRefusedStepView = null
    |   mSignatureBitmap = android.graphics.Bitmap@854106464 (0x32e8a160)
    |   mSignatureButton = android.widget.Button@860369920 (0x33483400)
    |   mSignatureFragmentContainer = android.widget.RelativeLayout@860368896 (0x33483000)
    |   mSignaturePreviewImageView = android.widget.ImageView@860370944 (0x33483800)
    |   mSignatureStepView = android.widget.RelativeLayout@860360704 (0x33481000)
    |   mSigned = java.lang.Boolean@1881937152 (0x702c1500)
    |   mSpecialContainerTaskStatusTextView = android.support.v7.widget.AppCompatTextView@860262400 (0x33469000)
    |   mSpecialIconA = android.support.v7.widget.AppCompatImageView@860296192 (0x33471400)
    |   mSpecialIconB = android.support.v7.widget.AppCompatImageView@860297216 (0x33471800)
    |   mSpecialIconC = android.support.v7.widget.AppCompatImageView@860298240 (0x33471c00)
    |   mSpecialIconD = android.support.v7.widget.AppCompatImageView@860299264 (0x33472000)
    |   mSpecialIconsLinearLayout = android.widget.LinearLayout@860261376 (0x33468c00)
    |   mSteps = java.lang.String[2]@860283592 (0x3346e2c8)
    |   mTask = com.companyname.appname.models..Task@857797632 (0x3320f400)
    |   mTaskCheckout = com.companyname.appname.helpers.TaskCheckout@859397192 (0x33395c48)
    |   mTaskCheckoutMainLinLayout = android.widget.LinearLayout@856667136 (0x330fb400)
    |   mTaskStatus = com.companyname.appname.enums.TaskStatus@851451392 (0x32c01e00)
    |   mTaskStatusLabel = android.widget.TextView@860358656 (0x33480800)
    |   mTaskStatusSelectedIndex = java.lang.Integer@1882345520 (0x70325030)
    |   mTaskStatusText = java.lang.String@858039008 (0x3324a2e0)
    |   mTaskStatusTextView = android.widget.TextView@860359680 (0x33480c00)
    |   mTaskStatusView = android.widget.FrameLayout@860321792 (0x33477800)
    |   mVerticalStepperForm = ernestoyaquello.com.verticalstepperform.VerticalStepperFormLayout@860300288 (0x33472400)
    |   mDelegate = android.support.v7.app.AppCompatDelegateImplN@856322976 (0x330a73a0)
    |   mResources = null
    |   mThemeId = 2131427510
    |   mCreated = true
    |   mFragments = android.support.v4.app.FragmentController@856383984 (0x330b61f0)
    |   mHandler = android.support.v4.app.FragmentActivity$1@856395936 (0x330b90a0)
    |   mNextCandidateRequestIndex = 0
    |   mPendingFragmentActivityResults = android.support.v4.util.SparseArrayCompat@856400656 (0x330ba310)
    |   mReallyStopped = true
    |   mRequestedPermissionsFromFragment = false
    |   mResumed = false
    |   mRetaining = false
    |   mStopped = true
    |   mStartedActivityFromFragment = false
    |   mStartedIntentSenderFromFragment = false
    |   mExtraDataMap = android.support.v4.util.SimpleArrayMap@856309016 (0x330a3d18)
    |   mActionBar = null
    |   mActionModeTypeStarting = 0
    |   mActivityInfo = android.content.pm.ActivityInfo@855609200 (0x32ff8f70)
    |   mActivityTransitionState = android.app.ActivityTransitionState@856227168 (0x3308fd60)
    |   mAppLockCheckRunnable = android.app.Activity$1@856383936 (0x330b61c0)
    |   mAppLockIsInMultiWindowMode = false
    |   mApplication = com.companyname.appname.DeliveryApplication@851900944 (0x32c6fa10)
    |   mCalled = true
    |   mChangeCanvasToTranslucent = false
    |   mChangingConfigurations = false
    |   mComponent = android.content.ComponentName@856313936 (0x330a5050)
    |   mConfigChangeFlags = 0
    |   mCurrentConfig = android.content.res.Configuration@855650184 (0x33002f88)
    |   mDecor = null
    |   mDefaultKeyMode = 0
    |   mDefaultKeySsb = null
    |   mDestroyed = true
    |   mDoReportFullyDrawn = false
    |   mEatKeyUpEvent = false
    |   mEmbeddedID = null
    |   mEnableDefaultActionBarUp = false
    |   mEnterTransitionListener = android.app.SharedElementCallback$1@1891321968 (0x70bb4870)
    |   mExitTransitionListener = android.app.SharedElementCallback$1@1891321968 (0x70bb4870)
    |   mFinished = true
    |   mFlipfont = 0
    |   mFragments = android.app.FragmentController@856383904 (0x330b61a0)
    |   mHandler = android.os.Handler@856395872 (0x330b9060)
    |   mHasCurrentPermissionsRequest = false
    |   mIdent = 226856808
    |   mInstanceTracker = android.os.StrictMode$InstanceTracker@856383920 (0x330b61b0)
    |   mInstrumentation = android.app.Instrumentation@851709880 (0x32c40fb8)
    |   mIntent = android.content.Intent@858578880 (0x332cdfc0)
    |   mLastNonConfigurationInstances = null
    |   mMainThread = android.app.ActivityThread@851460448 (0x32c04160)
    |   mManagedCursors = java.util.ArrayList@856308968 (0x330a3ce8)
    |   mManagedDialogs = null
    |   mMenuInflater = null
    |   mParent = null
    |   mPolicyManager = null
    |   mReferrer = java.lang.String@856356128 (0x330af520)
    |   mResultCode = -1
    |   mResultData = null
    |   mResumed = false
    |   mScreenChangeListener = null
    |   mSearchEvent = null
    |   mSearchManager = null
    |   mStartedActivity = false
    |   mStopped = true
    |   mTaskDescription = android.app.ActivityManager$TaskDescription@856395904 (0x330b9080)
    |   mTemporaryPause = false
    |   mTitle = java.lang.String@851901504 (0x32c6fc40)
    |   mTitleColor = 0
    |   mTitleReady = true
    |   mToken = android.os.BinderProxy@856318080 (0x330a6080)
    |   mTranslucentCallback = null
    |   mUiThread = java.lang.Thread@1999246640 (0x772a1530)
    |   mVisibleBehind = false
    |   mVisibleFromClient = true
    |   mVisibleFromServer = true
    |   mVoiceInteractor = null
    |   mWindow = com.android.internal.policy.PhoneWindow@860593808 (0x334b9e90)
    |   mWindowAdded = true
    |   mWindowManager = android.view.WindowManagerImpl@856400152 (0x330ba118)
    |   mInflater = com.android.internal.policy.PhoneLayoutInflater@858279648 (0x33284ee0)
    |   mOverrideConfiguration = null
    |   mResources = android.content.res.Resources@858466752 (0x332b29c0)
    |   mTheme = android.content.res.Resources$Theme@856384208 (0x330b62d0)
    |   mThemeResource = 2131427510
    |   mBase = android.app.ContextImpl@854679440 (0x32f15f90)
    |   shadow$_klass_ = com.companyname.appname.activities.TaskCheckoutActivity
    |   shadow$_monitor_ = 1073743558
    * Excluded Refs:
    | Field: android.view.inputmethod.InputMethodManager.mNextServedView
    | Field: android.view.inputmethod.InputMethodManager.mServedView
    | Field: android.view.inputmethod.InputMethodManager.mServedInputConnection
    | Field: android.view.textservice.SpellCheckerSession$1.this$0
    | Field: com.samsung.android.content.clipboard.SemClipboardManager.mContext
    | Field: com.samsung.android.emergencymode.SemEmergencyManager.mContext
    | Field: android.view.Choreographer$FrameDisplayEventReceiver.mMessageQueue (always)
    | Thread:FinalizerWatchdogDaemon (always)
    | Thread:main (always)
    | Thread:LeakCanary-Heap-Dump (always)
    | Class:java.lang.ref.WeakReference (always)
    | Class:java.lang.ref.SoftReference (always)
    | Class:java.lang.ref.PhantomReference (always)
    | Class:java.lang.ref.Finalizer (always)
    | Class:java.lang.ref.FinalizerReference (always)
    

    Code:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
    
        SmartLocation.with(this).location()
        .oneFix()
        .start(new OnLocationUpdatedListener() {
            @Override
            public void onLocationUpdated(Location location) {
                mCurrentLocation = location;
            }
        });
    
        ...
    }
    
    ...
    
    @Override
    protected void onStop() {
        super.onStop();
    
        SmartLocation.with(this).location().stop();
    }
    
    opened by narzero 6
  • Enabling Location with mode High Accuracy or Battery saving without user needing to visit Settings

    Enabling Location with mode High Accuracy or Battery saving without user needing to visit Settings

    First of all, brilliant library, thanks for making it public. Now, to the problem, as question states, how to enable Location Service without sending user to the Settings screen. I have seen some apps do that including Tinder and Google Maps. Related stackoverflow question can be found @ http://stackoverflow.com/q/28759454/1979347.

    opened by rohannexialabs 6
  • Crashlytics reports NullPointerException in GeofencingGooglePlayServicesProvider line 246

    Crashlytics reports NullPointerException in GeofencingGooglePlayServicesProvider line 246

    I got the following crash report from Crashlytics (Android 2.3.4):

    java.lang.NullPointerException
           at io.nlopez.smartlocation.geofencing.providers.GeofencingGooglePlayServicesProvider$GeofencingService.onHandleIntent(GeofencingGooglePlayServicesProvider.java:246)
           at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:59)
           at android.os.Handler.dispatchMessage(Handler.java:99)
           at android.os.Looper.loop(Looper.java:130)
           at android.os.HandlerThread.run(HandlerThread.java:60)
    
    thread
           at java.lang.Object.wait(Object.java)
           at java.lang.Thread.parkFor(Thread.java:1429)
           at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
           at sun.misc.Unsafe.park(Unsafe.java:337)
           at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
           at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016)
           at java.util.concurrent.PriorityBlockingQueue.take(PriorityBlockingQueue.java:228)
           at io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue.performOperation(DependencyPriorityBlockingQueue.java:197)
           at io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue.get(DependencyPriorityBlockingQueue.java:236)
           at io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue.take(DependencyPriorityBlockingQueue.java:65)
           at io.fabric.sdk.android.services.concurrency.DependencyPriorityBlockingQueue.take(DependencyPriorityBlockingQueue.java:46)
           at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1021)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
           at java.lang.Thread.run(Thread.java:1019)
    
    bug 
    opened by erf 6
  • geofence doesnt trigger

    geofence doesnt trigger

    Amazing lib! I made some intent service that implements location listener , activity listener and geo fencing listener all works but geo fencing listener doesnt trigger .

    is this issue known to happen ? or is it some bug ?

    Thanks.

    opened by Lir10 6
  • more than one library with package name 'com.google.android.gms'

    more than one library with package name 'com.google.android.gms'

    adding the library to my project gives the error as above.

    Error:Execution failed for task ':app:processDebugResources'.
    > Error: more than one library with package name 'com.google.android.gms'
      You can temporarily disable this error with android.enforceUniquePackageName=false
      However, this is temporary and will be enforced in 1.0
    
    opened by matantsu 6
  • java.lang.IllegalArgumentException: no providers found for criteria

    java.lang.IllegalArgumentException: no providers found for criteria

    My app is crashing on this piece of code.

    LocationAccuracy locationAccuracy;
    if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
        locationAccuracy = LocationAccuracy.HIGH;
    } else{
        locationAccuracy = LocationAccuracy.MEDIUM;
    }
    
    LocationParams locationParams = (new LocationParams.Builder()).setAccuracy(locationAccuracy)
                    .setDistance(LOCATION_UPDATE_DISTANCE_METRES)
                    .setInterval(LOCATION_UPDATE_INTERVAL_MILLISECONDS).build();
    
    //crashing on this line.
    SmartLocation.with(this).location(new LocationManagerProvider()).config(locationParams).start(this);
    

    Is it an issue with the library or with the way I'm using it?

    opened by droidster 5
  • Interview partners for research about communication in GitHub projects wanted

    Interview partners for research about communication in GitHub projects wanted

    Hi. My name is Verena Ebert, and I am a PhD student at the University of Stuttgart in Germany.
    A few months ago, I have examined 90 GitHub projects to see what communication channels they use and how they write about them in the written documents, for example README or wiki. If you are interested in the previous results, you can find them here: https://arxiv.org/abs/2205.01440 Your project was one of these 90 projects and, therefore, I am interested in further details about your communication setup.

    To gather more data about your communication setup, I kindly ask one of the maintainers to do an interview with me. The interview will be about 30-35 minutes long and via Skype, WebEx or any other provider you prefer. The interviews should be done in November 2022, if possible.

    In this interview, I would like to ask some questions about the reasons behind the channels, to understand the thoughts of the maintainers in addition to the written information.

    The long goal of my PhD is to understand how communication works in GitHub projects and how a good set of communication channels and information for other maintainers and developers looks like. One possible outcome is a COMMUNICATION.md with instructions and tips about which channels could be useful and how these channels should be introduced to other projects participants. Of course, if you are interested, I will keep you up to date about any further results in my research.

    If you are interested in doing an interview, please respond here or contact me via email ([email protected]). We will then make an appointment for the interview at a time and date that suits you.

    If you agree, I would like to record the interview and transcribe the spoken texts into anonymized written texts. In this case, I will send you the transcript for corrections afterwards. Only if you agree, the transcripts or parts of it would be part of a publication.

    opened by verenya 0
  • java.lang.IllegalArgumentException:: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

    java.lang.IllegalArgumentException:: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

    Hi , there is problem in newer android versions

    Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.

    2 at android.app.PendingIntent.checkFlags(PendingIntent.java:382) 3 at android.app.PendingIntent.buildServicePendingIntent(PendingIntent.java:752) 4 at android.app.PendingIntent.getService(PendingIntent.java:714) 5 at io.nlopez.smartlocation.geofencing.providers.GeofencingGooglePlayServicesProvider.init(GeofencingGooglePlayServicesProvider.java:86) 6 at io.nlopez.smartlocation.SmartLocation$GeofencingControl.<init>(SmartLocation.java:377) 7 at io.nlopez.smartlocation.SmartLocation.geofencing(SmartLocation.java:108) 8 at io.nlopez.smartlocation.SmartLocation.geofencing(SmartLocation.java:100)

    opened by khoshbin 5
  • Configure Renovate

    Configure Renovate

    Mend Renovate

    Welcome to Renovate! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.

    🚦 To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.


    Detected Package Files

    • settings.gradle (gradle)
    • build.gradle (gradle)
    • library/build.gradle (gradle)
    • rxjava/build.gradle (gradle)
    • sample/build.gradle (gradle)
    • gradle/wrapper/gradle-wrapper.properties (gradle-wrapper)

    Configuration

    🔡 Renovate has detected a custom config for this PR. Feel free to ask for help if you have any doubts and would like it reviewed.

    Important: Now that this branch is edited, Renovate can't rebase it from the base branch any more. If you make changes to the base branch that could impact this onboarding PR, please merge them manually.

    What to Expect

    With your current configuration, Renovate will create 17 Pull Requests:

    Update dependency com.android.tools.build:gradle to v3.6.4
    • Schedule: ["at any time"]
    • Branch name: renovate/com.android.tools.build-gradle-3.x
    • Merge into: master
    • Upgrade com.android.tools.build:gradle to 3.6.4
    Update dependency com.google.android.gms:play-services-location to v11.8.0
    • Schedule: ["at any time"]
    • Branch name: renovate/com.google.android.gms-play-services-location-11.x
    • Merge into: master
    • Upgrade com.google.android.gms:play-services-location to 11.8.0
    Update dependency com.squareup.leakcanary:leakcanary-android to v1.6.3
    Update dependency com.squareup.leakcanary:leakcanary-android-no-op to v1.6.3
    Update dependency gradle to v4.10.3
    • Schedule: ["at any time"]
    • Branch name: renovate/gradle-4.x
    • Merge into: master
    • Upgrade gradle to 4.10.3
    Update dependency io.reactivex.rxjava2:rxandroid to v2.1.1
    • Schedule: ["at any time"]
    • Branch name: renovate/io.reactivex.rxjava2-rxandroid-2.x
    • Merge into: master
    • Upgrade io.reactivex.rxjava2:rxandroid to 2.1.1
    Update dependency io.reactivex.rxjava2:rxjava to v2.2.21
    • Schedule: ["at any time"]
    • Branch name: renovate/io.reactivex.rxjava2-rxjava-2.x
    • Merge into: master
    • Upgrade io.reactivex.rxjava2:rxjava to 2.2.21
    Update dependency junit:junit to v4.13.2
    • Schedule: ["at any time"]
    • Branch name: renovate/junitversion
    • Merge into: master
    • Upgrade junit:junit to 4.13.2
    Update dependency org.mockito:mockito-core to v2.28.2
    • Schedule: ["at any time"]
    • Branch name: renovate/mockito-monorepo
    • Merge into: master
    • Upgrade org.mockito:mockito-core to 2.28.2
    Update dependency org.robolectric:robolectric to v3.8
    Update dependency com.android.support:support-annotations to v28
    Update dependency com.android.tools.build:gradle to v7
    • Schedule: ["at any time"]
    • Branch name: renovate/com.android.tools.build-gradle-7.x
    • Merge into: master
    • Upgrade com.android.tools.build:gradle to 7.3.1
    Update dependency com.google.android.gms:play-services-location to v21
    • Schedule: ["at any time"]
    • Branch name: renovate/com.google.android.gms-play-services-location-21.x
    • Merge into: master
    • Upgrade com.google.android.gms:play-services-location to 21.0.1
    Update dependency com.squareup.leakcanary:leakcanary-android to v2
    Update dependency gradle to v7
    • Schedule: ["at any time"]
    • Branch name: renovate/gradle-7.x
    • Merge into: master
    • Upgrade gradle to 7.5.1
    Update dependency org.mockito:mockito-core to v4
    • Schedule: ["at any time"]
    • Branch name: renovate/major-mockito-monorepo
    • Merge into: master
    • Upgrade org.mockito:mockito-core to 4.9.0
    Update dependency org.robolectric:robolectric to v4
    • Schedule: ["at any time"]
    • Branch name: renovate/major-robolectricversion
    • Merge into: master
    • Upgrade org.robolectric:robolectric to 4.9

    🚸 Branch creation will be limited to maximum 2 per hour, so it doesn't swamp any CI resources or spam the project. See docs for prhourlylimit for details.


    ❓ Got questions? Check out Renovate's Docs, particularly the Getting Started section. If you need any further assistance then you can also request help here.


    This PR has been generated by Mend Renovate. View repository job log here.

    opened by renovate[bot] 0
  • Getting crash: java.lang.IllegalStateException: GoogleApiClient is not connected yet.

    Getting crash: java.lang.IllegalStateException: GoogleApiClient is not connected yet.

    We are using version 3.3.3. Getting this crash in our project.

    Fatal Exception: java.lang.IllegalStateException: GoogleApiClient is not connected yet. at com.google.android.gms.common.api.internal.zaaf.zab(zaaf.java:134) at com.google.android.gms.common.api.internal.zaaz.zab(zaaz.java:23) at com.google.android.gms.common.api.internal.zaar.execute(zaar.java:71) at com.google.android.gms.internal.location.zzae.addGeofences(zzae.java:6) at com.google.android.gms.internal.location.zzae.addGeofences(zzae.java:5) at io.nlopez.smartlocation.geofencing.providers.GeofencingGooglePlayServicesProvider.onConnected(GeofencingGooglePlayServicesProvider.java:202) at com.google.android.gms.common.internal.zaj.zaa(zaj.java:30) at com.google.android.gms.common.api.internal.zaar.zaa(zaar.java:295) at com.google.android.gms.common.api.internal.zaaf.zaf(zaaf.java:130) at com.google.android.gms.common.api.internal.zaaf.zaa(zaaf.java:108) at com.google.android.gms.common.api.internal.zaaz.onConnected(zaaz.java:105) at com.google.android.gms.common.api.internal.zaq.onConnected(zaq.java:5) at com.google.android.gms.common.internal.zah.onConnected(zah.java:2) at com.google.android.gms.common.internal.BaseGmsClient$zzf.zza(BaseGmsClient.java:24) at com.google.android.gms.common.internal.BaseGmsClient$zza.zza(BaseGmsClient.java:12) at com.google.android.gms.common.internal.BaseGmsClient$zzc.zzc(BaseGmsClient.java:11) at com.google.android.gms.common.internal.BaseGmsClient$zzb.handleMessage(BaseGmsClient.java:49) at android.os.Handler.dispatchMessage(Handler.java:107) at com.google.android.gms.internal.common.zzi.dispatchMessage(zzi.java:8) at android.os.Looper.loop(Looper.java:237) at android.app.ActivityThread.main(ActivityThread.java:7948) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)

    opened by tashariko 0
  •   java.lang.SecurityException: Activity detection usage requires the ACTIVITY_RECOGNITION permission

    java.lang.SecurityException: Activity detection usage requires the ACTIVITY_RECOGNITION permission

    This is error in android 10 return the following error java.lang.SecurityException: Activity detection usage requires the ACTIVITY_RECOGNITION permission

    opened by GamalSebaee 1
Owner
Nacho Lopez
Nacho Lopez
Positional is a location information app for Android with Compass, Clock, Level, Sun and Moon and many other features.

Positional is a location based app that utilizes the device's GPS and fetches various details of the current latitude and longitude data like Altitude, Speed, Address and similar other information and show it in easily understandable format to the user. Alongside this main functionality of being a location app, Positional also provides a separate panel for Compass and Clock, and they serve their own purpose as their name suggests.

Hamza Rizwan 85 Dec 28, 2022
An android app that uses Google Maps API and SDK to track a user's location and calculate the total distance travelled

Bike Rush is an android app that uses Google Maps API and SDK to track a user's location and calculate the total distance travelled by him or her along with time and average speed.

Ishant Chauhan 21 Nov 14, 2022
LocationPicker 2.1 0.4 Java - A simple and easy to way to pick a location from map

Introduction LocationPicker is a simple and easy to use library that can be integrated into your project. The project is build with androidx. All libr

Shivpujan yadav 61 Sep 17, 2022
My Maps displays a list of maps, each of which show user-defined markers with a title, description, and location. The user can also create a new map. The user can save maps and load them in from previous usages of the app.

My Maps Bryant Jimenez My Maps displays a list of maps, each of which show user-defined markers with a title, description, and location. The user can

null 0 Nov 1, 2021
App usage tracker which maps your app usage to geo location.

Guilt Guilt is an inspiration from Meta (pun intended), it tracks the apps usage and maps it with geo location data where the app was last used. The a

null 6 Dec 28, 2022
This project allows you to calculate the route between two locations and displays it on a map.

Google-Directions-Android This project allows you to calculate the direction between two locations and display the route on a Google Map using the Goo

Joel Dean 970 Dec 15, 2022
EasyRoutes allows you to easily draw routes through the google maps address api.

EasyRoutes EasyRoutes allows you to easily draw routes through the google maps address api. Note: You need to generate an API key from the google cons

Antonio Huerta Reyes 7 Jul 26, 2022
Android Maps Extensions is a library extending capabilities of Google Maps Android API v2.

Android Maps Extensions Library extending capabilities of Google Maps Android API v2. While Google Maps Android API v2 is a huge leap forward comapare

Maciej Górski 408 Dec 15, 2022
Curve-Fit is an Android library for drawing curves on Google Maps

Curve-Fit Android library for drawing curves on Google Maps. This library uses Bezier cubic equation in order to compute all intermediate points of a

Sarweshkumar C R 63 Mar 7, 2021
Maps SDK for Android Utility Library

Maps SDK for Android Utility Library Description This open-source library contains utilities that are useful for a wide range of applications using th

Google Maps 3.4k Dec 30, 2022
A library for reverse geocoding coordinates in Android

?? AndroidReverseGeocoder A library for reverse geocoding coordinates in Android. The library is built on top of android's Geocoder library. AndroidRe

ShimShim27 1 Jun 24, 2022
Maps application in Android Studio using the Maps SDK for android

Google-Maps-Application Maps application in Android Studio using the Maps SDK for android. This app was initially developed in Java, but then was conv

Kyle McInnis 0 Nov 30, 2021
Scale bar for Android Maps (Google Maps, OSM, MapBox, Yandex)

Map Scale View Scale view for any Android Maps SDK (not only Google Maps) Contributing I encourage you to participate in this project. Feel free to op

Stas Parshin 109 Nov 18, 2022
malik dawar 87 Sep 18, 2022
Interactive, thoroughly customizable maps in native Android powered by vector tiles and OpenGL.

Interactive, thoroughly customizable maps in native Android powered by vector tiles and OpenGL.

Mapbox 247 Dec 27, 2022
This is a repo for implementing Map pan or drag (up, down, right ,left) to load more places on the Google Map for Android

Challenge Display restaurants around the user’s current location on a map ○ Use the FourSquare Search API to query for restaurants: https://developer.

Mahmoud Ramadan 7 Jul 30, 2022
Membuat Aplikasi Pencarian Bengkel dan Tambal Ban dengan Android Studio

Tambal-Ban Membuat Aplikasi Pencarian Bengkel dan Tambal Ban dengan Android Studio Tutorial Build with Android Studio https://youtu.be/82L7az6hdVI Tut

Azhar Rivaldi 15 Dec 28, 2022
🍃 Organic Maps is an Android & iOS offline maps app for travelers, tourists, hikers, and cyclists based on top of crowd-sourced OpenStreetMap data and curated with love by MapsWithMe founders.

?? Organic Maps is an Android & iOS offline maps app for travelers, tourists, hikers, and cyclists based on top of crowd-sourced OpenStreetMap data and curated with love by MapsWithMe founders. No ads, no tracking, no data collection, no crapware.

Organic Maps 4.3k Dec 31, 2022
Dual Camera, IMU, and GPS data recorder for Android

Dual Camera, IMU, and GPS data recorder for Android

AUT 3D Vision 17 Oct 24, 2022