Search code examples
androidandroid-activitylocalizationbroadcastreceiverandroid-service

My activity does not receive a Broadcast from my GPS service


Good morning everyone,

I have an activity that when executed, starts a service. Specifically GPSService, this service is put to wait until it reaches a latitude and longitude coordinates. When the coordinates are updated, the service sends the coordinates via LocalBroadcastManager to the activity that is waiting for it.

The problem I have is that the activity never recives anything.

Here I leave my activity:

public class MainActivity extends AppCompatActivity {

private TextView latitude;
private TextView longitude;
private static final int PETITION_PERMISSION_LOCATION = 101;
private double dLatitude;
private double dLongitude;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    IntentFilter iff= new IntentFilter(GPSService.ACTION);
    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, iff);

    latitude = findViewById(R.id.lblLatitud);
    longitude = findViewById(R.id.lblLongitud);

    ejecuteService();

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, dLatitude + " : " + dLongitude, Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
            if (isMyServiceRunning(GPSService.class)){
                stopService(new Intent(MainActivity.this, GPSService.class));
                latitude.setText(String.valueOf(dLatitude));
                longitude.setText(String.valueOf(dLongitude));
            }else {
                ejecuteService();
            }

        }
    });
}

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("onReceive","onReceive called");
        dLatitude = intent.getDoubleExtra("latitude", 0);
        dLongitude = intent.getDoubleExtra("longitude", 0);
        Log.e("receiver", "Got Latitude: " + dLatitude);
        Log.e("receiver", "Got Longitude: " + dLongitude);
    }
};

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private void ejecuteService(){
    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                PETITION_PERMISSION_LOCATION);
    } else {
        startService(new Intent(MainActivity.this, GPSService.class));
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == PETITION_PERMISSION_LOCATION) {
        if (grantResults.length == 1
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            //Permission granted
            startService(new Intent(MainActivity.this, GPSService.class));

        } else {
            //Permission denied:
            Log.e("PETITION PERMISSION", "Permission denied");
        }
    }
}

private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

}

Here is the content of the service:

public class GPSService extends Service
{
private static final String TAG = "GPSLocation";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
public static final String ACTION = "gpssend";

private class LocationListener implements android.location.LocationListener
{
    Location mLastLocation;

    public LocationListener(String provider)
    {
        Log.e(TAG, "LocationListener " + provider);
        mLastLocation = new Location(provider);
    }

    @Override
    public void onLocationChanged(Location location)
    {
        Log.e(TAG, "onLocationChanged: " + location);
        mLastLocation.set(location);
        Log.i(TAG, "Latitude: " + location.getLatitude());
        Log.i(TAG, "Longitude: " + location.getLongitude());
        sendMessage(location);
    }

    @Override
    public void onProviderDisabled(String provider)
    {
        Log.e(TAG, "onProviderDisabled: " + provider);
    }

    @Override
    public void onProviderEnabled(String provider)
    {
        Log.e(TAG, "onProviderEnabled: " + provider);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras)
    {
        Log.e(TAG, "onStatusChanged: " + provider);
    }
}

LocationListener[] mLocationListeners = new LocationListener[] {
        new LocationListener(LocationManager.GPS_PROVIDER),
        new LocationListener(LocationManager.NETWORK_PROVIDER)
};

@Override
public IBinder onBind(Intent arg0)
{
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    Log.e(TAG, "onStartCommand");
    super.onStartCommand(intent, flags, startId);
    return START_STICKY;
}

@Override
public void onCreate()
{
    Log.e(TAG, "onCreate");
    initializeLocationManager();
    try {
        mLocationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[1]);
    } catch (java.lang.SecurityException ex) {
        Log.i(TAG, "fail to request location update, ignore", ex);
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "network provider does not exist, " + ex.getMessage());
    }
    try {
        mLocationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[0]);
    } catch (java.lang.SecurityException ex) {
        Log.i(TAG, "fail to request location update, ignore", ex);
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "gps provider does not exist " + ex.getMessage());
    }
}

@Override
public void onDestroy()
{
    Log.e(TAG, "onDestroy");
    super.onDestroy();
    if (mLocationManager != null) {
        for (int i = 0; i < mLocationListeners.length; i++) {
            try {
                mLocationManager.removeUpdates(mLocationListeners[i]);
            } catch (Exception ex) {
                Log.i(TAG, "fail to remove location listners, ignore", ex);
            }
        }
    }
}

private void initializeLocationManager() {
    Log.e(TAG, "initializeLocationManager");
    if (mLocationManager == null) {
        mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
    }
}

private void sendMessage(Location location) {
    Log.d(TAG, "Broadcasting message");
    Intent intent = new Intent(ACTION);
    // You can also include some extra data.
    intent.putExtra("latitude", location.getLatitude());
    intent.putExtra("longitude", location.getLongitude());
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

}

In the content of the Log you can see how the service works by updating the coordinates immediately. But the activity does not recive anything.

02-19 20:03:18.815 5238-5267/com.google.android.apps.docs I/ProviderInstaller: Installed default security provider GmsCore_OpenSSL
02-19 20:03:24.347 5366-5366/es.jjsr.newmygpsapp:my_service E/GPSLocation: onLocationChanged: Location[gps 37.424998,-122.081998 acc=20 et=+1h2m37s264ms alt=0.0 {Bundle[mParcelledData.dataSize=40]}]
02-19 20:03:24.347 5366-5366/es.jjsr.newmygpsapp:my_service I/GPSLocation: Latitude: 37.42499833333333
02-19 20:03:24.347 5366-5366/es.jjsr.newmygpsapp:my_service I/GPSLocation: Longitude: -122.08199833333335
02-19 20:03:24.347 5366-5366/es.jjsr.newmygpsapp:my_service D/GPSLocation: Broadcasting message
02-19 20:03:24.348 5366-5366/es.jjsr.newmygpsapp:my_service E/GPSLocation: onStatusChanged: gps
02-19 20:03:27.159 1640-2158/system_process D/WifiService: acquireWifiLockLocked: WifiLock{NlpWifiLock type=2 uid=10012}
02-19 20:03:27.163 1640-1651/system_process D/WifiService: releaseWifiLockLocked: WifiLock{NlpWifiLock type=2 uid=10012}
02-19 20:03:47.163 1640-1667/system_process D/WifiService: acquireWifiLockLocked: WifiLock{NlpWifiLock type=2 uid=10012}
02-19 20:03:47.167 1640-1863/system_process D/WifiService: releaseWifiLockLocked: WifiLock{NlpWifiLock type=2 uid=10012}
02-19 20:04:07.210 1640-2187/system_process D/WifiService: acquireWifiLockLocked: WifiLock{NlpWifiLock type=2 uid=10012}
02-19 20:04:07.215 1640-1863/system_process D/WifiService: releaseWifiLockLocked: WifiLock{NlpWifiLock type=2 uid=10012}
02-19 20:04:11.092 1392-1412/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 772859 , only wrote 772560
02-19 20:04:11.101 5366-5366/es.jjsr.newmygpsapp:my_service E/GPSLocation: onDestroy
02-19 20:04:11.102 1640-2156/system_process I/GnssLocationProvider: WakeLock acquired by sendMessage(3, 0, com.android.server.location.GnssLocationProvider$GpsRequest@35d3846)
02-19 20:04:11.103 1640-1653/system_process I/GnssLocationProvider: WakeLock released by handleMessage(3, 0, com.android.server.location.GnssLocationProvider$GpsRequest@35d3846)
02-19 20:04:14.303 1392-1413/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 1078684 , only wrote 926640
02-19 20:05:07.215 1640-1652/system_process D/WifiService: acquireWifiLockLocked: WifiLock{NlpWifiLock type=2 uid=10012}

The Manifest file:

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

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
    android:name=".GlobalApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    <service android:name=".GPSService" android:process=":my_service" />
</application>

 </manifest>

Thanks to this community, I am learning a lot. Thank you so much for everything


Solution

  • Here I put how I solved it. The interesting thing is in the BroadcastReceiver of MainActivity

    My GPSService

    public class GPSService extends Service
    {
        private static final String TAG = "GPSLocation";
        private LocationManager mLocationManager = null;
        private static final int LOCATION_INTERVAL = 1000;
        private static final float LOCATION_DISTANCE = 10f;
        public static final String ACTION = "gpssend";
    
    private class LocationListener implements android.location.LocationListener
    {
        Location mLastLocation;
    
        public LocationListener(String provider)
        {
            Log.e(TAG, "LocationListener " + provider);
            mLastLocation = new Location(provider);
        }
    
        @Override
        public void onLocationChanged(Location location)
        {
            Log.e(TAG, "onLocationChanged: " + location);
            mLastLocation.set(location);
            Log.i(TAG, "Latitude: " + location.getLatitude());
            Log.i(TAG, "Longitude: " + location.getLongitude());
            sendMessage(location);
        }
    
        @Override
        public void onProviderDisabled(String provider)
        {
            Log.e(TAG, "onProviderDisabled: " + provider);
        }
    
        @Override
        public void onProviderEnabled(String provider)
        {
            Log.e(TAG, "onProviderEnabled: " + provider);
        }
    
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras)
        {
            Log.e(TAG, "onStatusChanged: " + provider);
        }
    }
    
    LocationListener[] mLocationListeners = new LocationListener[] {
            new LocationListener(LocationManager.GPS_PROVIDER),
            new LocationListener(LocationManager.NETWORK_PROVIDER)
    };
    
    @Override
    public IBinder onBind(Intent arg0)
    {
        return null;
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        Log.e(TAG, "onStartCommand");
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }
    
    @Override
    public void onCreate()
    {
        Log.e(TAG, "onCreate");
        initializeLocationManager();
        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                    mLocationListeners[1]);
        } catch (java.lang.SecurityException ex) {
            Log.i(TAG, "fail to request location update, ignore", ex);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "network provider does not exist, " + ex.getMessage());
        }
        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                    mLocationListeners[0]);
        } catch (java.lang.SecurityException ex) {
            Log.i(TAG, "fail to request location update, ignore", ex);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "gps provider does not exist " + ex.getMessage());
        }
    }
    
    @Override
    public void onDestroy()
    {
        Log.e(TAG, "onDestroy");
        super.onDestroy();
        if (mLocationManager != null) {
            for (int i = 0; i < mLocationListeners.length; i++) {
                try {
                    mLocationManager.removeUpdates(mLocationListeners[i]);
                } catch (Exception ex) {
                    Log.i(TAG, "fail to remove location listners, ignore", ex);
                }
            }
        }
    }
    
    private void initializeLocationManager() {
        Log.e(TAG, "initializeLocationManager");
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        }
    }
    
    private void sendMessage(Location location) {
        Log.d(TAG, "Broadcasting message");
        Intent intent = new Intent();
        intent.setAction(ACTION);
        // You can also include some extra data.
        intent.putExtra("latitude", location.getLatitude());
        intent.putExtra("longitude", location.getLongitude());
        sendBroadcast(intent);
    }
    
    }
    

    My MainActivity

    public class MainActivity extends AppCompatActivity {
    
    private TextView latitude;
    private TextView longitude;
    private static final int PETITION_PERMISSION_LOCATION = 101;
    private double dLatitude;
    private double dLongitude;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    
    
        latitude = findViewById(R.id.lblLatitud);
        longitude = findViewById(R.id.lblLongitud);
    
        ejecuteService();
    
        IntentFilter filter = new IntentFilter();
        filter.addAction(GPSService.ACTION);
        Receiver receiver = new Receiver();
        registerReceiver(receiver, filter);
    
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, dLatitude + " : " + dLongitude, Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
                if (isMyServiceRunning(GPSService.class)){
                    stopService(new Intent(MainActivity.this, GPSService.class));
                    latitude.setText(String.valueOf(dLatitude));
                    longitude.setText(String.valueOf(dLongitude));
                }else {
                    ejecuteService();
                }
    
            }
        });
    }
    
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
    
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
    
        return super.onOptionsItemSelected(item);
    }
    
    private void ejecuteService(){
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    PETITION_PERMISSION_LOCATION);
        } else {
            startService(new Intent(MainActivity.this, GPSService.class));
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == PETITION_PERMISSION_LOCATION) {
            if (grantResults.length == 1
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
                //Permission granted
                startService(new Intent(MainActivity.this, GPSService.class));
    
            } else {
                //Permission denied:
                Log.e("PETITION PERMISSION", "Permission denied");
            }
        }
    }
    
    private boolean isMyServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
    
    public class Receiver extends BroadcastReceiver{
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(GPSService.ACTION)){
                Log.e("onReceive","onReceive called");
                dLatitude = intent.getDoubleExtra("latitude", 0);
                dLongitude = intent.getDoubleExtra("longitude", 0);
                Log.e("receiver", "Got Latitude: " + dLatitude);
                Log.e("receiver", "Got Longitude: " + dLongitude);
            }
        }
    }
    
    }
    

    My Manifest

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="es.jjsr.newmygpsapp">
    
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <application
        android:name=".GlobalApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
        <service android:name=".GPSService" android:process=":my_service" />
    
    </application>
    

    And the Gradle

    implementation 'com.google.android.gms:play-services-location:9.4.0'
    

    Thank you very much to everyone for your help.

    I'm learning a lot.

    I leave the code here in case I can help someone who needs it