0

I'm been having this problem, I couldn't find related question, although the errors were similar they seemed to be different problem.

Before I state the problem, I tested this on my android emulator and all the code works fine! But when I run tested on two android devices with older and same android version, there is the following problem:

java.lang.RuntimeException: Unable to start service me.xxx.landmarkapp.XXXService@3ab946ed with Intent { cmp=me.xxx.landmarkapp/.XXXService}: kotlin.KotlinNullPointerException

The service won't start (it worked fine on android emulator, service code worked perfectly).

Here is how I start the service.

val serviceIntent = Intent(applicationContext, XXXService::class.java)
startService(serviceIntent)

I assume the service code is irrelevant.

I have checked to make sure applicationContext variable is not null (by Log.d it on screen), as I thought this might be the null pointer issue.

I also have made sure to call super.onCreate(savedInstanceState); at the top of overrided onCreate method in this activity, this seemed to be the issue in other questions.

Another issue in other questions which I seem to be doing right, is I defined the service in Manifest.xml...

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="me.xxx.landmarkapp" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <application
        ... >
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name=".XXXService" >
        </service>
    </application>

</manifest>

Does anyone know what the issue is? I've been stuck at this for hours

(BTW I'm using Kotlin, but I'm sure it's the same problem Java)

EDIT:

Service code

package me.xxx.landmarkapp

class XXXService: Service(), LocationListener {

    ////////////////////////////////////////
    // NOTIFICATIONS
    ////////////////////////////////////////

    private lateinit var notificationManager: NotificationManager
    private val CHANNEL_ID = "my_channel_01"
    private val NOTIFICATION_ID_SERVICE = 1
    private val NOTIFICATION_ID_LANDMARK = 2

    private fun initNotifications() {
        notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(CHANNEL_ID, CHANNEL_ID, importance).apply {
                description = CHANNEL_ID
            }

            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun buildNotification(title: String, message: String, intent: PendingIntent?): Notification {
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.messageicon)
            .setContentTitle(title)
            .setContentText(message)
            .setContentIntent(intent)
            .setAutoCancel(true)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()
    }

    private fun produceNotification(id: Int, title: String, message: String) {
        val notification = buildNotification(title, message, null)

        with(NotificationManagerCompat.from(this)) {
            notify(id, notification)
        }
    }

    ////////////////////////////////////////
    // LOCATION
    ////////////////////////////////////////

    private var lat: Double = 0.toDouble()
    private var long: Double = 0.toDouble()

    private fun enableLocation() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
            val criteria = Criteria()
            val provider = locationManager.getBestProvider(criteria, false)
            val location = locationManager.getLastKnownLocation(provider)

            locationManager.requestLocationUpdates(provider, 5000, 20f, this)
            setLocation(location)
        } else {
            produceNotification(NOTIFICATION_ID_LANDMARK, "Landmark App", "Location permission error")
        }
    }

    private fun disableLocation() {
        val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        locationManager.removeUpdates(this)
    }

    private fun setLocation(location: Location?) {
        lat = location!!.latitude
        long = location.longitude

        findLandmarks()
    }

    override fun onLocationChanged(location: Location?) {
        setLocation(location)
    }

    override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {

    }

    override fun onProviderEnabled(p0: String?) {

    }

    override fun onProviderDisabled(p0: String?) {

    }

    ////////////////////////////////////////
    // LANDMARKS
    ////////////////////////////////////////

    private val client = OkHttpClient()

    private fun findLandmarks() {
        val request = Request.Builder()
                .url("https://example.com/?userLat=$lat&userLong=$long")
                .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                produceNotification(NOTIFICATION_ID_LANDMARK, "Landmark App", "Network error")
            }

            override fun onResponse(call: Call, response: Response) {
                val msg = response.body()?.string()

                if (msg != null)
                {
                    val landmarks = JSONObject(msg).getJSONArray("landmarks")

                    for (i in 0 until landmarks.length()) {
                        val landmark = landmarks.getJSONObject(i)
                        // val id = landmark.getString("id")
                        val name = landmark.getString("name")
                        val location = landmark.getJSONObject("location")
                        val latitude = location.getString("latitude").toFloatOrNull()
                        val longitude = location.getString("longitude").toFloatOrNull()
                        // TODO: unique id for each notification
                        produceNotification(NOTIFICATION_ID_LANDMARK, "Found Landmark: $name!", "Latitude: $latitude, Longitude: $longitude")
                    }
                }
            }
        })
    }

    ////////////////////////////////////////
    // SERVICE
    ////////////////////////////////////////

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()

        initNotifications()

        val intent: PendingIntent =
            Intent(this, MainActivity::class.java).let { notificationIntent ->
                PendingIntent.getActivity(this, 0, notificationIntent, 0)
            }

        val notification = buildNotification("Landmark App", "Service running", intent)
        startForeground(NOTIFICATION_ID_SERVICE, notification)
    }

    override fun onDestroy() {
        super.onDestroy()

        disableLocation()
    }

    override fun onStartCommand(intent: Intent, flags: Int, startid: Int): Int {
        enableLocation()
        return START_STICKY
    }
}

Stack trace:

at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3086)
        at android.app.ActivityThread.access$2200(ActivityThread.java:163)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1465)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5608)
        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:1397)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1192)
     Caused by: kotlin.KotlinNullPointerException
        at me.xxx.landmarkapp.XXXService.setLocation(XXXService.kt:92)
        at me.xxx.landmarkapp.XXXService.enableLocation(XXXService.kt:80)
        at me.xxx.landmarkapp.XXService.onStartCommand(XXXService.kt:181)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3069)
        at android.app.ActivityThread.access$2200(ActivityThread.java:163) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1465) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:135) 
        at android.app.ActivityThread.main(ActivityThread.java:5608) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:372) 
David Callanan
  • 5,601
  • 7
  • 63
  • 105
  • 1
    Could you show your Service code? – Arka Prava Basu Nov 22 '19 at 19:22
  • 1
    And the complete stack trace, please. – Mike M. Nov 22 '19 at 19:26
  • 1
    That's done. Now I noticed that there is a problem in my service code by looking at the stack trace. I was only looking at the top of the trace, didn't notice the "Caused by" section and the rest of the trace underneath. – David Callanan Nov 22 '19 at 19:41
  • Simple fix: I was using `location!!` in `setLocation`, and the location ended up being null. I just changed it to `location?`. Thanks anyway everyone for taking your time to look at this question :) – David Callanan Nov 22 '19 at 19:50
  • 3
    I think your location is null that why you are getting this error add a null check before getting latitude and longitude. – Ritu Suman Mohanty Nov 22 '19 at 19:58

0 Answers0