bkonyi / FlutterGeofencing

Rough work for Flutter geofencing plugin
BSD 3-Clause "New" or "Revised" License
338 stars 220 forks source link

Exception after register fences: android.os.Looper android.app.Activity.getMainLooper() #17

Closed raafvargas closed 4 years ago

raafvargas commented 5 years ago

I am getting the error below after a fence be registered. I've tested in some devices and all reproduced the same error. Did someone already got this exception? Could it be caused by another plugin I'm using?

I/GeofencingService(19227): Starting GeofencingService...
D/AndroidRuntime(19227): Shutting down VM
E/AndroidRuntime(19227): FATAL EXCEPTION: main
E/AndroidRuntime(19227): Process: com.example.geofencing_test, PID: 19227
E/AndroidRuntime(19227): java.lang.RuntimeException: Unable to create service io.flutter.plugins.geofencing.GeofencingService: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Looper android.app.Activity.getMainLooper()' on a null object reference
E/AndroidRuntime(19227):    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3883)
E/AndroidRuntime(19227):    at android.app.ActivityThread.access$2100(ActivityThread.java:229)
E/AndroidRuntime(19227):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1909)
E/AndroidRuntime(19227):    at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(19227):    at android.os.Looper.loop(Looper.java:148)
E/AndroidRuntime(19227):    at android.app.ActivityThread.main(ActivityThread.java:7406)
E/AndroidRuntime(19227):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(19227):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
E/AndroidRuntime(19227):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
E/AndroidRuntime(19227): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Looper android.app.Activity.getMainLooper()' on a null object reference
E/AndroidRuntime(19227):    at com.google.android.gms.common.api.GoogleApi.<init>(Unknown Source)
E/AndroidRuntime(19227):    at com.google.android.gms.location.FusedLocationProviderClient.<init>(Unknown Source)
E/AndroidRuntime(19227):    at com.google.android.gms.location.LocationServices.getFusedLocationProviderClient(Unknown Source)
E/AndroidRuntime(19227):    at com.lyokone.location.LocationPlugin.<init>(LocationPlugin.java:76)
E/AndroidRuntime(19227):    at com.lyokone.location.LocationPlugin.registerWith(LocationPlugin.java:211)
E/AndroidRuntime(19227):    at io.flutter.plugins.GeneratedPluginRegistrant.registerWith(GeneratedPluginRegistrant.java:19)
E/AndroidRuntime(19227):    at com.example.geofencing_test.Application.registerWith(Application.java:19)
E/AndroidRuntime(19227):    at io.flutter.plugins.geofencing.GeofencingService.startGeofencingService(GeofencingService.kt:75)
E/AndroidRuntime(19227):    at io.flutter.plugins.geofencing.GeofencingService.onCreate(GeofencingService.kt:115)
E/AndroidRuntime(19227):    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3873)
E/AndroidRuntime(19227):    ... 8 more
I/Process (19227): Sending signal. PID: 19227 SIG: 9

AndroidManifest.xml

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.geofencing_test">
   <uses-permission android:name="android.permission.INTERNET" />
   <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
   <uses-permission android:name="android.permission.WAKE_LOCK" />
   <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
   <application android:name=".Application" android:label="geofencing_test" android:icon="@mipmap/ic_launcher">
      <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
      <meta-data android:name="com.google.android.geo.API_KEY" android:value="XXXX"/>
      <activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">

         <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
         <meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:value="true" />
         <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>
      <receiver android:name="io.flutter.plugins.geofencing.GeofencingBroadcastReceiver" android:enabled="true" android:exported="true"/>
      <receiver android:name="io.flutter.plugins.geofencing.GeofencingRebootBroadcastReceiver" android:enabled="true">
         <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
         </intent-filter>
      </receiver>
      <service android:name="io.flutter.plugins.geofencing.GeofencingService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true"/>
   </application>
</manifest>

android/build.gradle

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}

subprojects {
    project.configurations.all {
     resolutionStrategy.eachDependency { details ->
        if (details.requested.group == 'com.android.support'
              && !details.requested.name.contains('multidex') ) {
           details.useVersion "27.1.1"
        }
     }
  }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

app/build.gradle

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
    compileSdkVersion 27

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.geofencing_test"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.android.support:support-v4:27.1.1'
}

Thanks for the help

bkonyi commented 4 years ago

Sorry for the delay.

This line makes me think there's something happening in LocationPlugin:

E/AndroidRuntime(19227): at com.lyokone.location.LocationPlugin.registerWith(LocationPlugin.java:211)

Based on this issue, it looks like the crash should have gone away (but you might still have issues if you want to use that plugin in the background since it requires an Activity to work): https://github.com/Lyokone/flutterlocation/issues/220.