Walorn
Walorn

Reputation: 151

Android Location service

RESOLVED

Singleton pattern was suggested. Not the most elegant way to solve the problem but it works. Here is the code I used. Just have to get the instance in the main and LocationService class to use. See answer for how you are suppose to do it.

import android.location.Location;

public class LocationSingleton {
    private Location location;

    private static LocationSingleton singleton = new LocationSingleton();
    private LocationSingleton(){
    }

    public static LocationSingleton getInstance( ) {
        return singleton;
    }

    protected void setLocation(Location newLocation)  {
        this.location = newLocation;
    }

    protected Location getLocation(){
        return this.location;
    }
}


Attempting to use a background service to handle Location updates. I create a service in Main that updates the data (working correctly I believe) but I also have a button in main that whenever pressed does some work with the location data. I can't figure out though how to pass the Location from the service back to main. I've tried passing Main to the service but that didn't work and always created the service using the constructor without main passed. I've also tried creating a method in the service that returns the location but that kept getting a null pointer exception. How does one go about doing this.

Service Class

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationListener;

import java.util.Locale;

public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private String TAG = "LocationService";
    private GoogleApiClient mGoogleApiClient;
    private static final long INTERVAL = 1000 * 15;
    private static final long FATEST_INTERVAL = 1000 * 30;
    private LocationRequest mLocationRequest;
    private Location mCurrentLocation;
    private Geocoder geocoder;
    AddressStringOperations addressOps;
    TimerUpdate timerUpdate;
    Context mainContext;
    MainActivity act;

    public LocationService(MainActivity act) {
        this.mainContext = mainContext;
        Log.e(TAG, "Correct Constructor");
    }

    public LocationService(){
        Log.e(TAG, "Shouldn't use");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate");

        this.geocoder = new Geocoder(this, Locale.getDefault());
        addressOps = new AddressStringOperations(this.geocoder);
        this.timerUpdate = new TimerUpdate(this, addressOps);
        timerUpdate.startTimer();

        mGoogleApiClient = new GoogleApiClient.Builder(LocationService.this)
                .addApi(LocationServices.API).addConnectionCallbacks(LocationService.this)
                .addOnConnectionFailedListener(LocationService.this).build();

        mGoogleApiClient.connect();
        createLocationRequest();
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
    }

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

    protected void createLocationRequest(){
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FATEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    public Location getLocation(){
        Log.e(TAG, "Latitude: "+ mCurrentLocation.getLatitude() + "\n" + "Longitude: " + mCurrentLocation.getLatitude());
        return this.mCurrentLocation;
    }

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

    @Override
    public void onConnected(Bundle bundle) {
        Log.e(TAG, "Connection Successful");
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.e(TAG, "Connection Lost");
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.e(TAG, "Connection Failed");
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.e(TAG, "Firing onLocationChanged.........");
        //Log.e(TAG, "Latitude: "+ location.getLatitude() + "\n" + "Longitude: " + location.getLatitude());
        timerUpdate.location = location;
        mCurrentLocation = location;
    }
}

Main Class

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import android.location.Geocoder;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import java.util.Locale;

public class MainActivity extends Activity {

    private Button bLogout, bWebsite;
    private ImageButton bLogData;
    private TextView etLabel;
    private UserLocalStore userLocalStore;
    private static final String TAG = "MainActivity";
    TimerUpdate timerUpdate;
    Geocoder geocoder;
    Location location;
    AddressStringOperations addressOps;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e(TAG, "On Create . . . . .");

        if(!isGooglePlayServicesAvailable()){
            startActivity(new Intent(MainActivity.this, login.class));
            Log.e(TAG, "No GooglePlayServices");
            finish();
            Toast.makeText(getApplicationContext(), "Please update GooglePlay Servies to use this Application", Toast.LENGTH_LONG).show();
        }else{
            userLocalStore = new UserLocalStore(this);
            this.geocoder = new Geocoder(this, Locale.getDefault());
            addressOps = new AddressStringOperations(this.geocoder);

            this.timerUpdate = new TimerUpdate(this, addressOps, false);

            if (authenticate() != true) {
                startActivity(new Intent(MainActivity.this, login.class));
                Log.e(TAG, "Authenticate is not true");
                finish();
            } else {
                etLabel = (TextView) findViewById(R.id.etEmailLabel);
                bLogout = (Button) findViewById(R.id.bLogout);
                bLogData = (ImageButton) findViewById(R.id.DataLog);
                bWebsite = (Button) findViewById(R.id.website);

                LocationService service = new LocationService(MainActivity.this);
                Intent start = new Intent(MainActivity.this, LocationService.class);
                MainActivity.this.startService(start);

                bLogData.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        String pressStatus = "3";
                        Log.e(TAG, "Latitude: "+ location.getLatitude() + "\n" + "Longitude: " + location.getLatitude());
                        timerUpdate.update(pressStatus);
                    }
                });

                bLogout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        userLocalStore.clearuserData();
                        userLocalStore.setUserLoggedIn(false);
                        startActivity(new Intent(MainActivity.this, login.class));
                        finish();
                    }
                });

                bWebsite.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("temp"));
                        startActivity(browserIntent);
                    }
                });
            }
        }
    }

    public void setLocation(Location newLocation){
        this.location = newLocation;
    }
}

Upvotes: 0

Views: 806

Answers (1)

Filnik
Filnik

Reputation: 138

You can do that in multiple ways. You can create a Receiver and broadcast and intent from there or you can use an EventBus ( https://github.com/greenrobot/EventBus ).

In this case I think it's more appropriate the Service/Receiver model, you can find here an example: http://www.truiton.com/2014/09/android-service-broadcastreceiver-example/

If you need it only in one activity, consider to use an AsyncTask and handle the output in the postExecute method, it would be a lot easier.

Upvotes: 1

Related Questions