Unable to instantiate a service which sends data to firebase. - android

My service stops running after i ran the app.
The Log shows a runtime error which says the following lines
java.lang.RuntimeException: Unable to instantiate service com.example.hp.newtrial.Service_Location: java.lang.NullPointerException
The code for the activity and the service is shared. The manifest is also given for reference.
I am basically trying to upload data to firestore at particular intervals but this error keeps showing up.
My Main Activity code which call for the service
package com.example.hp.newtrial;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.FirebaseApp;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity_Log";
private LocalBroadcastManager manager;
private BroadcastReceiver receiver;
double latitude, longitude;
//Location location;
//private Service_Location service_location;
//creating class
//public MyBroadcastReceiver myBroadcastReceiver;
EditText nameUser;
Button click;
String userName;
// Access a Cloud Firestore instance from your Activity
String reference_id;
Intent intents;
FirebaseFirestore db;
ServiceConnection mServiceConn;
#Override
protected void onStart() {
super.onStart();
FirebaseApp.initializeApp(this);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseApp.initializeApp(this);
// service_location = new Service_Location();
db = FirebaseFirestore.getInstance();
nameUser = findViewById(R.id.usrName);
click = findViewById(R.id.button_3);
Log.d(TAG, "Main Activity");
try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
}
} catch (Exception e) {
Log.d(TAG, "Error: ", e);
}
//to start the service . . . .
try {
intents = new Intent(MainActivity.this, Service_Location.class);
//bindService(intents, mServiceConn, BIND_AUTO_CREATE);
startService(intents);
} catch (Exception e) {
Log.d(TAG, String.valueOf(e));
}
/*try {
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("Location"));
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Bundle b = intent.getExtras();
if (b != null) {
latitude = b.getDouble("latitude");
longitude = b.getDouble("longitude");
}
Log.d("MainActivity", "Latitude: " + latitude + " Longitude:" + longitude);
Toast.makeText(MainActivity.this, "Location: Latitude: " + latitude + " Longitude: " + latitude, Toast.LENGTH_LONG).show();
}
};
} catch (Exception e) {
Log.d("MainActivity", String.valueOf(e));
}*/
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//to Firebase . . . .
try {
userName = String.valueOf(nameUser.getText());
Map<String, Object> data = new HashMap<>();
data.put("UserName", userName);
Map<String, Object> data2 = new HashMap<>();
data.put("UserName", "Akshansh");
db.collection("Users").add(data).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
//Getting the reference id . . . .
reference_id = documentReference.getId();
intents.putExtra("Reference_id", reference_id);
startService(intents);
Log.d(TAG, documentReference.getId());
Log.d(TAG, "On Success Listener :: document Added . .. . ");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "On Failure Listener some trouble");
}
});
} catch (Exception e) {
Log.d(TAG, "Error " + String.valueOf(e));
}
}
});
}
}
And here is the code of my service
package com.example.hp.newtrial;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.FirebaseApp;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.WriteBatch;
import java.io.FileDescriptor;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class Service_Location extends Service implements com.google.android.gms.location.LocationListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
public static Location mCurrentLocation;
long BACKGROUND_INTERVAL = 5000;
Context context;
String TAG = "Service_Location";
Intent send = new Intent("Location");
Handler handler;
String reference_id;
IBinder binder;
//Firebase Reference . . . .
private FirebaseFirestore db;
private DocumentReference documentReference;
//We'll try to use batch to perform what we need . . . .
WriteBatch batch = Objects.requireNonNull(db).batch();
public Service_Location() {
super();
}
//Google Api Connection . . .
#SuppressLint("RestrictedApi")
#Override
public void onCreate() {
super.onCreate();
//initializing app
FirebaseApp.initializeApp(this);
db = FirebaseFirestore.getInstance();
try {
Log.d(TAG, "onCreate()");
LocationManager locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
assert locationManager != null;
boolean isGPSenabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!isGPSenabled) {
showSettingDialog();
}
} catch (Exception e) {
Log.d(TAG, String.valueOf(e));
}
//show error dialog if GoolglePlayServices not available
try {
if (isGooglePlayServicesAvailable()) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(BACKGROUND_INTERVAL);
mLocationRequest.setFastestInterval(BACKGROUND_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//mLocationRequest.setSmallestDisplacement(10.0f); /* min dist for location change, here it is 10 meter */
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
} catch (Exception e) {
Log.d(TAG, String.valueOf(e));
}
handler = new Handler(getMainLooper());
}
private void showSettingDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("GPS is setting");
alertDialog.setMessage("GPS not enabled!!!");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
alertDialog.show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Data received from intent Reference_id:" + intent.getStringExtra("Reference_id"));
reference_id = intent.getStringExtra("Reference_id");
return START_STICKY;
}
private boolean isGooglePlayServicesAvailable() {
Log.d(TAG, "isGooglePlayServicesAvailable()");
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
return ConnectionResult.SUCCESS == status;
}
//Service
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
//Location Listener. . .
#Override
public void onLocationChanged(final Location location) {
try {
if (reference_id != null) {
documentReference = db.collection("Users").document(reference_id);
//update(location);
//now trying with batch. . .
updateBatch(location);
}
Log.d(TAG, "OnLocationChanged()");
Log.d(TAG, "Latitude: " + location.getLatitude() + " Longitude: " + location.getLongitude());
} catch (Exception e) {
Log.d(TAG, String.valueOf(e));
}
handler.post(new Runnable() {
#Override
public void run() {
//Toast.makeText(getApplicationContext(), "this helps", Toast.LENGTH_LONG).show();
}
});
}
private void updateBatch(Location location) {
Log.d(TAG, "inside updateBatch");
try {
LatLng lng = new LatLng(location.getLatitude(), location.getLongitude());
Map<String, LatLng> map = new HashMap<>();
map.put("Location", lng);
batch.update(documentReference, "Location", map);
} catch (Exception e) {
Log.d(TAG, String.valueOf(e));
}
}
private void update(Location location) {
Log.d(TAG, "Updating Location");
LatLng lng = new LatLng(location.getLatitude(), location.getLongitude());
Map<String, LatLng> map = new HashMap<>();
map.put("Location", lng);
documentReference.set(map).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("Location", "Added Successfully. . ");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("Location", "Failed ");
}
});
}
/
//Google API Client
public void onConnected(Bundle bundle) {
Log.d(TAG, "On_Connected()");
startLocationUpdates();
}
protected void startLocationUpdates() {
try {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
} catch (Exception e) {
Log.d("Service", String.valueOf(e));
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
The Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hp.newtrial">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service android:name=".Service_Location" />
</application>
</manifest>
I don't understand what to do next . . .
Any working suggestion is acceptable

Try to ask runtime permissions like this. First add run time permission in onCreate()
private static final int LOCATION_PERMISSI0N = 2002;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSI0N);
}
else
{
startService();
}
now outside onCreate() method add this startService() method
public void startService()
{
try {
Intent intents = new Intent(MainActivity.this, Service_Location.class);
//bindService(intents, mServiceConn, BIND_AUTO_CREATE);
startService(intents);
} catch (Exception e) {
Log.d(TAG, String.valueOf(e));
}
}
handle granted permission by overriding this method outside onCreate()
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case LOCATION_PERMISSI0N:
{
if (grantResults.length > 0)
{
boolean course_location = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (course_location)
{
startService();
}
else
{
Log.d("locationpermissions","Location Permission Denied");
}
}
break;
}
}
}
this must start your service..

Related

Android: Location updating very slowly

I am trying to create an app that sends to my server the location of my android device on button press. Unfortunately the location updates very slowly, sometimes taking minutes and tens of meters to get the new location.
I'm relatively new to Android programming and if anyone could help me with a way to update the location every time when press the send button I would be grateful.
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
import org.json.*;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
public class DefaultActivity extends AppCompatActivity {
private String serverURL;
private TextView tv_Title, tv_Status;
private Button b_SendLocation, b_SendNow, b_StopLocation;
private User user;
private FusedLocationProviderClient locationClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_default);
Intent intent = getIntent();
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1);
locationClient = LocationServices.getFusedLocationProviderClient(this);
serverURL = intent.getExtras().getString("serverURL");
JSONParse(intent.getExtras().getString("myResponse"));
tv_Title = findViewById(R.id.TextView_Title);
tv_Status = findViewById(R.id.TextView_Status);
b_SendLocation = findViewById(R.id.Button_SendLocation);
b_SendNow = findViewById(R.id.Button_SendNow);
b_StopLocation = findViewById(R.id.Button_StopLocation);
tv_Title.setText(user.getLastName() + " " + user.getFirstName());
tv_Status.setText(" ");
b_SendLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Feedback("Sending location every 5 sec.");
}
});
b_SendNow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Feedback("Current location sent!");
GetLocation();
}
});
b_StopLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Feedback("Periodic sending halted!");
}
});
}
private void GetLocation() {
if (ActivityCompat.checkSelfPermission(DefaultActivity.this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationClient.getLastLocation().addOnSuccessListener(DefaultActivity.this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location != null){
double latitude, longitude;
latitude = location.getLatitude();
longitude = location.getLongitude();
tv_Status.setText("Latitude: " + latitude + "\nLongitude: " + longitude);
SendLocation(latitude, longitude);
}
else
tv_Status.setText("Location is null!");
}
});
}
private void SendLocation(double latitude, double longitude){
OkHttpClient client = new OkHttpClient();
String url = serverURL + "/api/user/?id=" + user.getID() + "&latitude=" + latitude + "&longitude=" + longitude;
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e){
e.printStackTrace();
runOnUiThread(new Runnable() {
#Override
public void run() {
tv_Status.append("\n\n Server error!");
}
});
}
#Override
public void onResponse(Call call, Response response) throws IOException{
if (response.isSuccessful()){
runOnUiThread(new Runnable() {
#Override
public void run() {
tv_Status.append("\n\n Server acknowledged!");
}
});
}
}
});
}
private void JSONParse(String JSONString){
User readUser = new User();
try {
JSONObject obj = new JSONObject(JSONString);
readUser.setID(Integer.parseInt(obj.getString("ID")));
readUser.setFirstName(obj.getString("FirstName"));
readUser.setLastName(obj.getString("LastName"));
readUser.setEmail(obj.getString("Email"));
readUser.setPassword(obj.getString("Password"));
readUser.setRole(obj.getString("Role"));
Feedback("Welcome back " + readUser.getFirstName() + "!");
} catch (JSONException e) {
Feedback("JSON Exception!");
e.printStackTrace();
}
user = readUser;
}
private void Feedback(String message){
Toast toast=Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG);
toast.show();
}
}

How to run geofencing app in background?

I am creating a attendance monitoring app for my campus using geofencing api.Everything else is working smoothly, but I want my app to work in the background.(Similar to a music player). Currently, it works only when the app is open. Here is the Service class code I have used:
package com.app.androidkt.geofencing;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class BackgroundService extends Service{
MainActivity main;
public int onStartCommand(Intent intent, int flags, int startId) {
main.isMonitoring = true;
main.startGeofencing();
main.startLocationMonitor();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//use this method to communicate with your activity
return null;
}
}
And here is the MainActivity.java:
package com.app.androidkt.geofencing;
import android.Manifest;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends AppCompatActivity implements
OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{
private static final String TAG = "MainActivity";
private static final int REQUEST_LOCATION_PERMISSION_CODE = 101;
private GoogleMap googleMap;
private GeofencingRequest geofencingRequest;
public GoogleApiClient googleApiClient;
public boolean isMonitoring = false;
private MarkerOptions markerOptions;
private Marker currentLocationMarker;
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION_PERMISSION_CODE);
}
}
public void startLocationMonitor() {
Log.d(TAG, "start location monitor");
LocationRequest locationRequest = LocationRequest.create()
.setInterval(2000)
.setFastestInterval(1000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
try {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
if (currentLocationMarker != null) {
currentLocationMarker.remove();
}
markerOptions = new MarkerOptions();
markerOptions.position(new LatLng(location.getLatitude(), location.getLongitude()));
markerOptions.title("Current Location");
currentLocationMarker = googleMap.addMarker(markerOptions);
Log.d(TAG, "Location Change Lat Lng " + location.getLatitude() + " " + location.getLongitude());
}
});
} catch (SecurityException e) {
Log.d(TAG, e.getMessage());
}
}
public void startGeofencing() {
Log.d(TAG, "Start geofencing monitoring call");
pendingIntent = getGeofencePendingIntent();
geofencingRequest = new GeofencingRequest.Builder()
.setInitialTrigger(Geofence.GEOFENCE_TRANSITION_ENTER)
.addGeofence(getGeofence())
.build();
if (!googleApiClient.isConnected()) {
Log.d(TAG, "Google API client not connected");
} else {
try {
LocationServices.GeofencingApi.addGeofences(googleApiClient, geofencingRequest, pendingIntent).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.d(TAG, "Successfully Geofencing Connected");
} else {
Log.d(TAG, "Failed to add Geofencing " + status.getStatus());
}
}
});
} catch (SecurityException e) {
Log.d(TAG, e.getMessage());
}
}
isMonitoring = true;
invalidateOptionsMenu();
}
#NonNull
public Geofence getGeofence() {
LatLng latLng = Constants.AREA_LANDMARKS.get(Constants.GEOFENCE_ID_STAN_UNI);
return new Geofence.Builder()
.setRequestId(Constants.GEOFENCE_ID_STAN_UNI)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setCircularRegion(latLng.latitude, latLng.longitude, Constants.GEOFENCE_RADIUS_IN_METERS)
.setNotificationResponsiveness(1000)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
}
public PendingIntent getGeofencePendingIntent() {
if (pendingIntent != null) {
return pendingIntent;
}
Intent intent = new Intent(this, GeofenceRegistrationService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.
FLAG_UPDATE_CURRENT);
}
private void stopGeoFencing() {
pendingIntent = getGeofencePendingIntent();
LocationServices.GeofencingApi.removeGeofences(googleApiClient, pendingIntent)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess())
Log.d(TAG, "Stop geofencing");
else
Log.d(TAG, "Not stop geofencing");
}
});
isMonitoring = false;
invalidateOptionsMenu();
}
#Override
protected void onResume() {
super.onResume();
int response = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(MainActivity.this);
if (response != ConnectionResult.SUCCESS) {
Log.d(TAG, "Google Play Service Not Available");
GoogleApiAvailability.getInstance().getErrorDialog(MainActivity.this, response, 1).show();
} else {
Log.d(TAG, "Google play service available");
}
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.reconnect();
}
#Override
protected void onStop() {
super.onStop();
googleApiClient.disconnect();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.manu_map_activity, menu);
if (isMonitoring) {
menu.findItem(R.id.action_start_monitor).setVisible(false);
menu.findItem(R.id.action_stop_monitor).setVisible(true);
menu.findItem(R.id.startservice).setVisible(true);
} else {
menu.findItem(R.id.action_start_monitor).setVisible(true);
menu.findItem(R.id.action_stop_monitor).setVisible(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_start_monitor:
startGeofencing();
break;
case R.id.action_stop_monitor:
stopGeoFencing();
break;
case R.id.startservice:
startService(new Intent(this, BackgroundService.class));
break;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public void onMapReady(GoogleMap googleMap) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
this.googleMap = googleMap;
LatLng latLng = Constants.AREA_LANDMARKS.get(Constants.GEOFENCE_ID_STAN_UNI);
googleMap.addMarker(new MarkerOptions().position(latLng).title("Stanford University"));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17f));
googleMap.setMyLocationEnabled(true);
Circle circle = googleMap.addCircle(new CircleOptions()
.center(new LatLng(latLng.latitude, latLng.longitude))
.radius(Constants.GEOFENCE_RADIUS_IN_METERS)
.strokeColor(Color.RED)
.strokeWidth(4f));
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "Google Api Client Connected");
isMonitoring = true;
startGeofencing();
startLocationMonitor();
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "Google Connection Suspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
isMonitoring = false;
Log.e(TAG, "Connection Failed:" + connectionResult.getErrorMessage());
}
}
When I try to run the app in background by clicking the background option i have provided in the app, the app crashes and i get a runtime error saying:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app.androidkt.geofencing, PID: 24176
java.lang.RuntimeException: Unable to start service com.app.androidkt.geofencing.BackgroundService#52135c5 with Intent { cmp=com.app.androidkt.geofencing/.BackgroundService }: java.lang.NullPointerException: Attempt to write to field 'boolean com.app.androidkt.geofencing.MainActivity.isMonitoring' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3335)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1578)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Caused by: java.lang.NullPointerException: Attempt to write to field 'boolean com.app.androidkt.geofencing.MainActivity.isMonitoring' on a null object reference
at com.app.androidkt.geofencing.BackgroundService.onStartCommand(BackgroundService.java:13)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3318)
at android.app.ActivityThread.-wrap21(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1578) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6123) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
Please suggest me changes in my code.
MainActivity main;
is not initialized in your BackgroundService.
Try to implement the interface instead accessing the Activity's method like this.
Check this answer to implement the interface.

android: Location returns null object reference error

I am trying to get the user's location, more specifically their city. The app asks for permission at runtime. But when it tries to put the location into an ArrayList, it gives a null object reference error.
I will comment the specific line below.
What am I doing wrong?
ERROR
Attempt to invoke virtual method 'java.util.List android.location.Geocoder.getFromLocation(double, double, int)' on a null object reference
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class PhoneList extends AppCompatActivity implements LocationListener {
LocationManager locationManager;
private String provider;
public final static int MY_PERMISSIONS_REQUEST_READ_LOCATION = 1;
public double myLng;
public double myLat;
List addresses = new ArrayList();
public Geocoder myGeo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_list);
if (1 == 0) {
showAlert();
} else {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
GetLocationPermission();
return;
}
locationManager.requestLocationUpdates(provider, 0, 0, this);
Location location = locationManager.getLastKnownLocation(provider);
onLocationChanged(location);
myLat = location.getLatitude();
myLng = location.getLongitude();
}
}
private void showAlert() {
final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Enable Location")
.setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
"use this app")
.setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.show();
}
public void GetLocationPermission(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_READ_LOCATION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("Yes");
} else {
System.out.println("boo");
}
return;
}
}
}
#Override
public void onLocationChanged(Location location) {
try {
//ERROR IS ON THIS LINE
addresses = myGeo.getFromLocation(location.getLatitude(), location.getLongitude(), 10);
} catch (IOException e) {
Log.e("LocateMe", "Could not get Geocoder data", e);
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
Looks like you haven't initialized your myGeo reference.
To fix it, just initialize it before you call getFromLocation(). As a side note, you should also make sure that the Location is not null, since the locationManager.getLastKnownLocation() call has the potential to return null.
#Override
public void onLocationChanged(Location location) {
try {
//Add initialization:
myGeo = new Geocoder(this, Locale.getDefault());
//Make sure that the Location is not null:
if (location != null) {
addresses = myGeo.getFromLocation(location.getLatitude(), location.getLongitude(), 10);
}
} catch (IOException e) {
Log.e("LocateMe", "Could not get Geocoder data", e);
}
}

how to get real time geolocation with movings(like google maps) on android with movings

I'm new to android and I'm creating an application based on GPS . So i have implement Google maps and location point identifier on my application but it takes only my first attempt geo location , when I'm moving it is not get updated . please help me to solve this . Thank you.
package com.android.locationtracker;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.android.app.AppConst;
import com.android.app.AppController;
import com.android.common.GPSTracker;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
public class NearByActivity extends Activity {
private static final String TAG = "error";
private GoogleMap googleMap;
private static String URL = AppConst.GEOMETRY;
private static String URL_UPDATE = AppConst.GEOMETRY_UPDATE;
private String jsonResponse;
private ProgressDialog pDialog;
GPSTracker gps;
double latitude;
double longtitude;
String id;
String type;
List<Marker> markerList = new ArrayList<Marker>();
Marker marker;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nearby_activity);
try {
// Loading map
initilizeMap();
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
googleMap.getUiSettings().setCompassEnabled(true);
googleMap.getUiSettings().setRotateGesturesEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
gps = new GPSTracker(this);
if (gps.canGetLocation()) {
latitude = gps.getLatitude();
longtitude = gps.getLongtitude();
} else {
gps.showSettingAllerts();
}
new LoadGeo().execute();
}
private void initilizeMap() {
try {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager()
.findFragmentById(R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onResume() {
super.onResume();
initilizeMap();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
private class LoadGeo extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(NearByActivity.this);
pDialog.setMessage("Loading...");
pDialog.show();
//
}
#Override
protected Void doInBackground(Void... arg0) {
SharedPreferences prefs = getSharedPreferences("conetext",
Context.MODE_PRIVATE);
id = prefs.getString("userid", null);
type = prefs.getString("persontype", null);
Map<String, String> params = new HashMap<String, String>();
params.put("userid", id);
params.put("usertype", type);
params.put("lat", String.valueOf(latitude));
params.put("lng", String.valueOf(longtitude));
JsonObjectRequest req = new JsonObjectRequest(URL_UPDATE,
new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d("map", "msg");
VolleyLog.v("Response:%n %s",
response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
AppController.getInstance().addToRequestQueue(req);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Thread thread = new Thread() {
#Override
public void run() {
try {
while (true) {
sleep(1000);
JsonArrayRequest req = new JsonArrayRequest(URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(
JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
try {
markerList.clear();
googleMap.clear();
for (int i = 0; i < response
.length(); i++) {
JSONObject geo = (JSONObject) response
.get(i);
String usertype = geo
.getString("UserType");
MarkerOptions markerblue = new MarkerOptions();
markerblue.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_CYAN));
markerblue.position(new LatLng(latitude, longtitude));
googleMap.addMarker(markerblue);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
latitude, longtitude), 17));
if (usertype
.equals("driver")) {
double lat = geo
.getDouble("Lat");
double lng = geo
.getDouble("Lng");
MarkerOptions markerop = new MarkerOptions();
markerop.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
markerop.position(
new LatLng(lat,
lng))
.draggable(true)
.visible(true);
marker= googleMap
.addMarker(markerop);
markerList.add(marker);
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(
getApplicationContext(),
"Error: "
+ e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(
VolleyError error) {
VolleyLog.d(
TAG,
"Error: "
+ error.getMessage());
Toast.makeText(
getApplicationContext(),
error.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(req);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
}
}
You need to register LocationListener and implement method
#Override
public void onLocationChanged(Location location) {
//smth like this
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(), location.getLongtitude()), 17));
}
detailed info is here https://developer.android.com/training/location/receive-location-updates.html
You need to execute this code in specific interval
if (gps.canGetLocation()) {
latitude = gps.getLatitude();
longtitude = gps.getLongtitude();
} else {
gps.showSettingAllerts();
}
new LoadGeo().execute();
i would suggest use Handler.postDelayed(Runnable,Interval) method to work this out.
You can use Location service. Here is the code for that:
Call this function by giving a desired frequency (in mins):
private void requestLocation(Context context, int frequency) //frequency in mins
{
LocationMgr loc_mgr = new LocationMgr(context);
loc_mgr.requestLocationUpdates(frequency);
}
Here is the LocationMgr class:
public class LocationMgr implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener
{
private final Context context;
private GoogleApiClient googleApiClient;
private boolean inProgress;
public enum REQUEST_TYPE {START, STOP, LAST_KNOWN}
private REQUEST_TYPE requestType;
private Intent intent;
LocationRequest mLocationRequest;
LocationListener ll;
public LocationMgr(Context context)
{
this.context = context;
this.googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
intent = new Intent(context, LocationService.class);
inProgress = false;
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
inProgress = false;
}
#Override
public void onConnectionSuspended(int arg0) {
googleApiClient.connect();
}
#Override
public void onConnected(Bundle connectionHint) {
PendingIntent pendingIntent = PendingIntent.getService(context, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
switch (requestType)
{
case START :
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, mLocationRequest, pendingIntent);
break;
case STOP :
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, pendingIntent);
break;
case LAST_KNOWN :
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
ll.onNewLocationUpdate(location);
break;
default :
log.e("Unknown request type in onConnected().");
break;
}
inProgress = false;
googleApiClient.disconnect();
}
/**
*
* #param frequency (minutes) minimum time interval between location updates
*/
public void requestLocationUpdates(int frequency)
{
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(frequency * 60 * 1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setFastestInterval(1000);
if (inProgress)
{
log.e("A request is already underway");
return;
}
inProgress = true;
requestType = REQUEST_TYPE.START;
googleApiClient.connect();
}
public void removeContinuousUpdates()
{
if (inProgress)
{
log.e("A request is already underway");
return;
}
inProgress = true;
requestType = REQUEST_TYPE.STOP;
googleApiClient.connect();
}
public void getLastKnownLocation(LocationListener ll)
{
this.ll = ll;
if (inProgress)
{
log.e("A request is already underway");
return;
}
inProgress = true;
requestType = REQUEST_TYPE.LAST_KNOWN;
googleApiClient.connect();
}
}
Here is the LocationService class:
public class LocationService extends IntentService
{
public LocationService()
{
super("NOTIFICATION_SERVICE");
}
/**
* Called when a new location update is available.
*/
#Override
protected void onHandleIntent(Intent intent)
{
LocationListener ll = new LocationListener()
{
#Override
public void onNewLocationUpdate(Location location)
{
// here you will get the latest location
}
};
LocationMgr lm = new LocationMgr(getApplicationContext());
lm.getLastKnownLocation(ll);
}
}

Difference in android code execution

I have two different devices running the same code but executing them in different ways. Whenever I minimize the application and then pull it back up on the tablet it works the way I wanted it to, by not creating another timer. When I run it on the phone though and minimize/maximize it another timer is started, thus having 2 run at the same time. Why does this work differently on the two devices or is there something else happening I am not seeing. (I know I need to create a background service and that the way I am doing it currently is incorrect)
Tablet Specs
Android Version: 4.4.2
Kernal Version: 3.4.67
Model Number: DL701Q
Phone Specs
Android Version: 4.4.2
Kernal Version: 3.4.0+
Software/Model: VS450PP1
Code
Main Class
package temp;
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 com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends Activity implements LocationListener,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
private Button bLogout, bWebsite;
private ImageButton bLogData;
private TextView etLabel;
private UserLocalStore userLocalStore;
private String mLastUpdateTime;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private static final String TAG = "MainActivity";
private static final long INTERVAL = 1000 * 15;
private static final long FATEST_INTERVAL = 1000 * 30;
private Geocoder geocoder;
AddressOps addressOps;
TimerUpdate timerUpdate;
int count = 0;
#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));
finish();
Toast.makeText(getApplicationContext(), "Please update GooglePlay Servies to use this Application", Toast.LENGTH_LONG).show();
}else {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
createLocationRequest();
userLocalStore = new UserLocalStore(this);
this.geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
addressOps = new AddressOps(this.geocoder);
etLabel = (TextView) findViewById(R.id.etEmailLabel);
bLogout = (Button) findViewById(R.id.bLogout);
bLogData = (ImageButton) findViewById(R.id.DataLog);
bWebsite = (Button) findViewById(R.id.website);
bLogData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
String pressStatus = "3";
timerUpdate.update(pressStatus);
}
});
bLogout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
userLocalStore.clearuserData();
userLocalStore.setUserLoggedIn(false);
timerUpdate.stopTimerTask();
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("http://temp"));
startActivity(browserIntent);
}
});
}
}
private void displayUserDetails(){
User user = userLocalStore.getLoggedInUser();
String userdisplay = "Logged in as: " + user.username;
etLabel.setText(userdisplay);
}
private boolean authenticate(){
return userLocalStore.getUserLoggedIn();
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
Log.e(TAG, "Network Check");
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
protected void createLocationRequest(){
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onConnected(Bundle bundle) {
Log.e(TAG, "onConnected: Connected - " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
protected void startLocationUpdates() {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
Log.e(TAG, "Location update started ");
}
#Override
public void onConnectionSuspended(int i) {
stopLocationUpdates();
Log.e(TAG, "On Connection Suspended " + mGoogleApiClient.isConnected());
Toast.makeText(getApplicationContext(), "No Network Connection", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "Connection failed " + connectionResult.toString());
stopLocationUpdates();
Log.e(TAG, "onConnectionFailed " + mGoogleApiClient.isConnected());
Toast.makeText(getApplicationContext(), "No Network Connection", Toast.LENGTH_LONG).show();
}
#Override
public void onLocationChanged(Location location) {
Log.e(TAG, "Firing onLocationChanged.........");
if(this.timerUpdate != null) {
timerUpdate.location = location;
}else{
Log.e(TAG, "Timer is null");
}
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
Log.e(TAG, "Location update stopped");
}
#Override
protected void onPause() {
super.onPause();
Log.e(TAG, "MainActivity Paused");
}
#Override
public void onResume() {
super.onResume();
Log.e(TAG, "MainActivity Resumed");
if (mGoogleApiClient.isConnected()) {
if(!isGooglePlayServicesAvailable()){
startActivity(new Intent(MainActivity.this, login.class));
Toast.makeText(getApplicationContext(), "Please update GooglePlay Servies to use this Application", Toast.LENGTH_LONG).show();
finish();
}
}
}
#Override
public void onStart() {
super.onStart();
if(authenticate() == true){
displayUserDetails();
if(this.timerUpdate == null) {
this.timerUpdate = new TimerUpdate(this, addressOps);
Log.e(TAG, "Timer created: " + count);
timerUpdate.startTimer();
}
}else{
startActivity(new Intent(MainActivity.this, login.class));
finish();
}
mGoogleApiClient.connect();
Log.e(TAG, "MainActivity Started, GoogleApi Connection: " + mGoogleApiClient.isConnected());
}
#Override
public void onStop() {
super.onStop();
Log.e(TAG, "MainActivity Stopped");
}
}
Timer class
package temp;
import android.content.Context;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
import java.util.Timer;
import java.util.TimerTask;
public class TimerUpdate {
private Timer timer;
private TimerTask timertask;
public boolean timerScheduled = false;
private final Handler handler = new Handler();
private static final String TAG = "UpdateTimer";
AddressOps addressOps;
private Context mainContext;
private UserLocalStore userLocalStore;
public Location location;
public TimerUpdate(Context context, AddressOps ops){
Log.e(TAG, "Constructor");
initializeTimerTask();
this.mainContext = context;
this.addressOps = ops;
userLocalStore = new UserLocalStore(context);
}
private void initializeTimerTask(){
Log.e(TAG, "InitializeTimerTask");
timertask = new TimerTask() {
public void run(){
handler.post(new Runnable(){
public void run(){
Log.e(TAG, "TimerTask Ran");
String status = "5";
update(status);
}
});
}
};
}
public void startTimer(){
Log.e(TAG, "startTimer");
timer = new Timer();
timer.schedule(timertask, 1000 * 30, 1000 * 60 * 2);
timerScheduled = true;
Log.e(TAG, "Start Schedule created");
}
public void stopTimerTask(){
Log.e(TAG, "StopTimer");
if (timer != null){
timer.cancel();
timer = null;
Log.e(TAG, "Timer Stopped");
}
}
public void update(String status) {
Log.e(TAG, "Update initiated .............");
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
if(isNetworkAvailable()){
String address = addressOps.getAddressString(lng, lat);
if(address != null) {
User user = userLocalStore.getLoggedInUser();
ServerRequest request = new ServerRequest(this.mainContext);
request.storeLocationInBackground(lat, lng, user.username, address, status);
Toast.makeText(this.mainContext, "Longitude: " + lng + "\nLatitude: "
+ lat + "\nAddress: " + address, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this.mainContext, "Unable to retrieve Address", Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(this.mainContext, "No Network Connection" + "\nLatitude: " + lat
+ "\nLongitude: " + lng, Toast.LENGTH_LONG).show();
}
} else {
Log.e(TAG, "There is no current Location Data in Update");
Toast.makeText(this.mainContext, "There is no current Location Data ....", Toast.LENGTH_SHORT).show();
}
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager)mainContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
Log.e(TAG, "Network Check");
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
onStart() is called even when "minimizing/maximize" (see the details of Activity lifecycle.) If the authenticate() method returns false, the timer class is re-created blindly. The old instance of the timer may stick around, depending on what it is doing / registering with other components.

Categories

Resources