numberformat exception using alarmamanager - crashes before on start - android

---------UPDATE -----------------------------------------
When the app starts I receive numberformat exception at line :
final long thetime=Long.parseLong(time_value);
But the above aren't in the main activity...
In the xml file I have in the edittex
android:inputType="number" .
This line is in myservice class in which I have the alarmamanager(note I can't use catch because below(alarm.setRepeating) it doesn't recognize "thetime" value.
protected void onHandleIntent(Intent intent) {
//try{
String time_value;
time_value=(String) intent.getStringExtra("time_value");
final long thetime=Long.parseLong(time_value);// }
// catch (NumberFormatException e) {
//}
mContext = getApplicationContext();
mHandler.post(new Runnable(){
#Override
public void run() {
// Start service using AlarmManager
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent = new Intent(myservice.this,selection.class);
PendingIntent pintent = PendingIntent.getService(myservice.this, 0, intent,
0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
thetime*1000, pintent);
// Tell the user about what we did.
Toast.makeText(myservice.this, "Configured time interval",
Toast.LENGTH_LONG).show();
}
});
}
}
I load the time_value from another activity:
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
edit11=edit1.getText().toString();
edit22=edit2.getText().toString();
Intent i=new Intent(this,selection.class);
i.putExtra("code_value",edit11);
Intent k=new Intent(this,myservice.class);
k.putExtra("time_value",edit22);
this.startService(k);
Intent l=new Intent(this,MainActivity.class);
startActivity(l);
break;
}
}

because I made lonfitude and latitude Strings (I had them as double before). How can I overcome that?
To get String from double use String.valueOf();
String latitude = String.valueOf(location.getLatitude());
Repeat
Also,how can I select to send the data in time intervals that the user will define?
To repeat at specific interval use AlarmManager.

how can I select to send the data in time intervals that the user will define
You can use Timer and TimerTask. Take the user input for time interval and pass it to schedule() of Timer. Thing that should be taken into consideration is when app is closed or user changes time interval then cancel previous TimerTask and purge Timer, if any.
For Alarm, do the following in your activity class:
PendingIntent Sender = null;
Intent AlarmIntent = new Intent("com.example.gpstrackdemo.RECEIVEALARM");
AlarmManager AlmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Sender = PendingIntent.getBroadcast(GpsTrackActivity.this, 0,
AlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlmMgr.setRepeating(AlarmManager.RTC_WAKEUP, 0, 15 * 60 * 1000,
Sender);
AlarmIntent is the intent for BroadcastReceiver. Here is its code:
public class StartServiceReceiver extends BroadcastReceiver
{
private static final String TAG = "StartServiceReceiver";
#Override
public void onReceive(Context context, Intent intent)
{
Intent serviceIntent = new Intent(context, MyLocationService.class);
context.startService(serviceIntent);
Log.v(TAG, "onReceive called");
}
}
On receiving the broadcast, it will start Location service, in which we will get current location of user.
Service Class:
public class MyLocationService extends Service implements
OnLocationReceivedListener {
private LocationManager manager;
private Location location = null;
PowerManager powerManager;
private WakeLock wakeLock;
private String country;
GPSLocationListener mGPSLocationListener;
NetworkLocationListener mNetworkLocationListener;
private static final int MAX_ATTEMPTS = 250;
private static String TAG = "MyLocationService";
LocTimerTask mTimerTask;
int mSattelites;
Timer myLocTimer;
int count = 0;
boolean isGPS;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v(TAG, "onStartCommand called");
getCurrentLocation();
return START_STICKY;
}
#Override
public void onCreate() {
Log.v(TAG, "onCreate called");
powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"mywakelock");
mGPSLocationListener = new GPSLocationListener();
mNetworkLocationListener = new NetworkLocationListener();
wakeLock.acquire();
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void getCurrentLocation() {
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
manager.addGpsStatusListener(mGPSStatusListener);
mTimerTask = new LocTimerTask(LocationManager.GPS_PROVIDER);
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Log.v(TAG, "GPS ENABLED");
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L,
50.0f, mGPSLocationListener);
}
if(manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000L,
50.0f, mNetworkLocationListener);
}
myLocTimer = new Timer("LocationRunner", true);
myLocTimer.schedule(mTimerTask, 0, 500);
}
public class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location argLocation) {
location = argLocation;
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
public class NetworkLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location argLocation) {
location = argLocation;
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
class LocTimerTask extends TimerTask {
String provider;
public LocTimerTask(String provider) {
this.provider = provider;
}
final Handler mHandler = new Handler(Looper.getMainLooper());
Runnable r = new Runnable() {
#Override
public void run() {
count++;
Log.v(TAG, "Timer Task run" + i);
location = manager.getLastKnownLocation(provider);
if (location != null) {
Log.v(TAG, "in timer task run in if location not null");
onLocationReceived(location);
myLocTimer.cancel();
myLocTimer.purge();
mTimerTask.cancel();
return;
} else {
isGPS = false;
if (location == null && count == MAX_ATTEMPTS) {
turnGPSOff();
location = manager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
onLocationReceived(location);
myLocTimer.cancel();
myLocTimer.purge();
mTimerTask.cancel();
return;
}
} else {
return;
}
}
count = 0;
}
};
public void run() {
mHandler.post(r);
}
}
private GpsStatus.Listener mGPSStatusListener = new GpsStatus.Listener() {
#Override
public synchronized void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
GpsStatus status = manager.getGpsStatus(null);
mSattelites = 0;
Iterable<GpsSatellite> list = status.getSatellites();
for (GpsSatellite satellite : list) {
if (satellite.usedInFix()) {
mSattelites++;
}
}
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
break;
case GpsStatus.GPS_EVENT_STARTED:
break;
case GpsStatus.GPS_EVENT_STOPPED:
break;
default:
break;
}
}
};
public void onDestroy() {
super.onDestroy();
if (myLocTimer != null) {
myLocTimer.cancel();
myLocTimer.purge(); //Timer not required any more
}
if (mTimerTask != null) {
if (mTimerTask.r != null) {
mTimerTask.mHandler.removeCallbacks(mTimerTask.r);
}
}
if (manager != null) {
if (mGPSLocationListener != null) {
manager.removeUpdates(mGPSLocationListener);
}
//remove location updates for listener once your work is done, otherwise it will drain battery
if (mNetworkLocationListener != null) {
manager.removeUpdates(mNetworkLocationListener);
}
if (mGPSStatusListener != null) {
manager.removeGpsStatusListener(mGPSStatusListener);
}
}
}
#Override
public void onLocationReceived(Location mLoc) {
//Send data to http server once you get location.
}
}
Here my service class implements a listener which have a callback method onLocationReceived in which you can do your stuff after you get location.
public interface OnLocationReceivedListener {
public void onLocationReceived(Location mLoc);
}
And in your manifest, declare broadcast receiver and service respectively:
<receiver
android:name=".receiver.StartServiceReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="com.example.gpstrackdemo.RECEIVEALARM" />
</intent-filter>
</receiver>
<service android:name=".service.MyLocationService"
android:enabled="true"></service>

Ok, I had forgot the :
startService() im my main activity.
I had to put it in myservice activity.
Thanks to all

Related

Create a background service to collect and send positions

I work on a service that need to be stared/stopped from a specific time, collect user's locations and send them to an API.
I start my service like so
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, CONSTANTES.START_HOURS); //6
calendar.set(Calendar.MINUTE, CONSTANTES.START_MINUTES); //30
calendar.set(Calendar.SECOND, CONSTANTES.START_SECOND);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
new Intent(MainActivity.this, AlarmTask.class).setAction("START_SERVICE"), PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
My Receiver
public class AlarmTask extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("STOP_SERVICE")) {
System.out.println("service : got stop instruction");
if (isMyServiceRunning(context, ScheduleOffsetService.class)) {
context.stopService(new Intent(context, ScheduleOffsetService.class));
}
} else if (intent.getAction().equalsIgnoreCase("START_SERVICE")) {
System.out.println("service : got start instruction");
if (!isMyServiceRunning(context, ScheduleOffsetService.class)) {
context.startService(new Intent(context, ScheduleOffsetService.class));
}
}
}
private boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
And my service :
public class ScheduleOffsetService extends Service {
private LocationManager mLocationManager;
private ArrayList<Location> locations = new ArrayList<>();
private String token;
public ScheduleOffsetService() {
}
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
System.out.println("Scheduler location : " + location);
mLastLocation.set(location);
locations.add(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
stopSelf();
}
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
try {
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60, 10f, mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 1000 * 60, 10f, mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
PropertyApp app = new PropertyApp(this);
System.out.println("ScheduleOffset token : " + app.getToken());
if (app.getToken() != null) {
token = app.getToken();
} else {
stopSelf();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("Scheduler : created");
return START_STICKY;
}
private boolean gpsIsEnable() {
LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
#Override
public void onDestroy() {
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
}
}
}
onEnd();
System.out.println("Scheduler : got destroyed");
super.onDestroy();
}
private void onEnd() {
if (locations.isEmpty()) {
return;
}
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(/*URL*/)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
WebServiceInterface webServiceInterface = retrofit.create(WebServiceInterface.class);
JsonObject object = new JsonObject();
for (int i = 0; i < locations.size(); i++) {
JsonObject content = new JsonObject();
content.addProperty("lat", locations.get(i).getLatitude());
content.addProperty("lng", locations.get(i).getLongitude());
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = df.format(c);
content.addProperty("date", formattedDate);
object.add(String.valueOf(i), content);
}
String data = object.toString();
Call<ResponseRetrofitIreby> call = webServiceInterface.jetLagService(token, PropertyApp.PARNTER_ID, data);
call.enqueue(new Callback<ResponseRetrofitIreby>() {
#Override
public void onResponse(Call<ResponseRetrofitIreby> call, Response<ResponseRetrofitIreby> response) {
if (response.isSuccessful()) {
System.out.println("RESPONSE : " + response.body().getTrackingPosition().getErreur());
}
}
#Override
public void onFailure(Call<ResponseRetrofitIreby> call, Throwable t) {
t.printStackTrace();
}
});
}
}
The thing is : When the user asks to be tracked, the listener of my service is no longer called.
Moreover, if the user kill the application the service seems to restart, and thus empty my list of locations.
Can someone, explain me do to ?
you can try this library location tracker background

Save data to firebase Realtime database from Android service

I want to save user's location after every 30 seconds to firebase realtime database from android service,my service stops when i add firebase, there is no crash log, any suggestions? or best solution to achieve this? Thanks
public class LocationService extends Service {
double pLatitude, pLongitude;
private DatabaseReference mDatabase;
FirebaseUser user;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(),"Service Started", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
//service stops(crashes) on below two lines
mDatabase = FirebaseDatabase.getInstance().getReference();
user = FirebaseAuth.getInstance().getCurrentUser();
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_LONG).show();
pushtofirebase(getLocation());
} catch (Exception e) {
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 30000);
}
private void pushtofirebase(GPSTracker gps) {
pLatitude = gps.getLatitude();
pLongitude = gps.getLongitude();
mDatabase.child("location").child(user.getUid()).push().setValue(String.valueOf(pLatitude));
mDatabase.child("location").child(user.getUid()).setValue(pLongitude);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private GPSTracker getLocation() {
GPSTracker gps = new GPSTracker(getApplicationContext());
if (gps.canGetLocation()) {
Toast.makeText(getApplicationContext(), gps.getLongitude() + " " + gps.getLatitude(), Toast.LENGTH_SHORT).show();
} else {
gps.showSettingsAlert();
}
return gps;
}
}
it may be a native crash change the logcat crash level to verbose and application to no filter

Location service got stopped by Doze mode

I'm developing sport tracking app that uses location manager and gps provider for getting location updates every second even if the screen is off and the phone is in the pocket.
When user pressed start button in my activity I start service in foreground, display notification and register location listener.
Service starts receiving location updates and writes them into my track file.
Suddenly I get log message 'Power manager idle mode: true', the phone goes into Doze mode and my sevice stops getting any location update until the phone wakes up.
I read docs about Doze mode and see that it shouldn't affect location services, but it does in my case.
May be I'm doing something wrong. Here is the code of my service, any help is really appreciated.
public class LocService
extends Service
implements LocationListener, GpsStatus.Listener
{
private String mName;
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private LocationManager locationManager;
public LocService(String name)
{
super();
mName = name;
}
private final class ServiceHandler extends Handler
{
public ServiceHandler(Looper looper)
{
super(looper);
}
#Override
public void handleMessage(Message msg)
{
if (msg != null && msg.obj != null)
{
onHandleIntent((Intent)msg.obj);
}
else
{
logMessage("msg for intent is not good");
}
}
}
#Override
public void onCreate()
{
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
logMessage("Enabling Doze mode listener");
IntentFilter filter = new IntentFilter();
filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
registerReceiver(new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
onDeviceIdleChanged();
}
}, filter);
}
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
}
#TargetApi(Build.VERSION_CODES.M)
private void onDeviceIdleChanged()
{
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
if(powerManager != null)
{
logMessage("Power manager idle mode: " + powerManager.isDeviceIdleMode());
} else
{
logMessage("Power manager idle changed to ?");
}
}
protected void onHandleIntent(Intent intent)
{
//call start/stop location logging on proper intent
if(intent.getIntExtra("cmd", -1) == 1)
{
startLogging();
} else
{
stopLogging();
}
}
private void startLogging()
{
logMessage("LocationService.startLogging");
try
{
locationManager.addGpsStatusListener(this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 0, this);
logMessage("requesting gps updates");
startForeground(ONGOING_NOTIFICATION, getNotification(-1, -1, true, false));
logMessage("Sending foreground service notification");
}
catch (SecurityException ex)
{
logMessage(" SecurityException while requesting location info: " + ex);
}
}
private void stopLogging()
{
try
{
locationManager.removeUpdates(this);
stopForeground(true);
notificationManager.cancel(ONGOING_NOTIFICATION);
}
catch (SecurityException ex)
{
logMessage(" SecurityException on stopLogging with location manager: " + ex);
}
}
#Override
public void onLocationChanged(Location location)
{
//save location lat, lon directly to track file
//flush file
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
//do nothing
}
#Override
public void onProviderEnabled(String provider)
{
logMessage("Location provider enabled " + provider);
}
#Override
public void onProviderDisabled(String provider)
{
logMessage("Location provider disabled " + provider);
}
#Override
public void onGpsStatusChanged(int event)
{
try
{
logMessage(" *** onGpsStatusChanged with " + event);
GpsStatus status = locationManager.getGpsStatus(null);
int inFix = 0;
int total = 0;
for (GpsSatellite satellite : status.getSatellites())
{
if (satellite.usedInFix()) inFix++;
total++;
}
logMessage(" Sats: " + total + " in fix " + inFix);
}
catch (SecurityException sex)
{
}
catch (Exception ex)
{
}
}
#Override
public void onStart(Intent intent, int startId)
{
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
onStart(intent, startId);
return START_STICKY;
}
#Override
public void onDestroy()
{
mServiceLooper.quit();
try
{
locationManager.removeUpdates(this);
}
catch (SecurityException ex)
{
logMessage(" SecurityException on Destroy service with location manager: " + ex);
}
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
private void logMessage(String msg)
{
Log.i("LocServ", msg);
}
}
It is not a given that when ACTION_DEVICE_IDLE_MODE_CHANGED is fired, doze was either turned on or off. There are more factors that can affect idle mode.
Try to create and acquire WakeLock.
PowerManager.WakeLock getLock(Context context, String lockName) {
if (wakeLock == null) {
PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
}
return wakeLock;
}
//on start service
getLock(ctxt.getApplicationContext(), "lockName").acquire();
//on destroy service
#Override
public void onDestroy() {
PowerManager.WakeLock lock = getLock(this.getApplicationContext(), "lockName");
if (lock.isHeld()) {
lock.release();
}
super.onDestroy();
}

android Geofence won't get any Transition updates

Geofence does not get any transition updates, despite setting location 100 miles away,
does not trigger anything even GPS is on.
public class GeofenceManager extends IntentService implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationClient.OnAddGeofencesResultListener, LocationClient.OnRemoveGeofencesResultListener {
private Context context;
private LocationClient locClient;
private PendingIntent penIntent;
private ArrayList<Geofence> geofenceList = new ArrayList<Geofence>();
private double dLongitude, dLatitude;
private boolean bGeofenceEnable = false;
private BroadcastReceiver receiverGeofence;
/* ===========================================================================================================================
* CONSTRUCTOR -- Checks if Google play service are available
*----------------------------------------------------------------------------------------------------------------------------*/
GeofenceManager(Context context){
super("ReceiveTransitionsIntentService");
this.context = context;
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
if (ConnectionResult.SUCCESS == resultCode) {
bGeofenceEnable = true;
} else {
Log.d(GPSManager.LOG_TAG,"GEO_FENCE: ERROR google play services not available");
}
}
/* ===========================================================================================================================
* METHOD -- using hard coded values for test purpose
*----------------------------------------------------------------------------------------------------------------------------*/
public void setGeofence( double latitude, double longitude){
if(bGeofenceEnable){
dLatitude = latitude = 51.515399;
dLongitude = longitude = -0.144313;
locClient.connect();
}
}
private PendingIntent createRequestPendingIntent() {
if (null != penIntent) {
return penIntent;
} else {
Intent intent = new Intent(context, GeofenceManager.class); // Create an Intent pointing to the IntentService
return PendingIntent.getService( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
#Override public void onConnected(Bundle bundle) {
Geofence geofence = new Geofence.Builder()
.setRequestId("123")
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT|Geofence.GEOFENCE_TRANSITION_ENTER ) // exit geo fence listener
.setCircularRegion(dLatitude, dLongitude, 20) // GPS coordinates
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
geofenceList.add(geofence);
penIntent = createRequestPendingIntent();
locClient.addGeofences(geofenceList, penIntent, this);
}
#Override public void onDisconnected() { }
#Override public void onConnectionFailed(ConnectionResult connectionResult) { }
#Override public void onRemoveGeofencesByPendingIntentResult(int i, PendingIntent pendingIntent) { }
#Override public void onAddGeofencesResult(int i, String[] strings) {
if(i == LocationStatusCodes.SUCCESS){
Log.d(GPSManager.LOG_TAG, GPSManager.getTime()+" GEO_FENCE: added");
} else {
Log.d(GPSManager.LOG_TAG, GPSManager.getTime()+" GEO_FENCE: add ERROR "+i);
}
// locClient.disconnect();
}
#Override public void onRemoveGeofencesByRequestIdsResult(int i, String[] strings) {
if(i == LocationStatusCodes.SUCCESS)
Log.d(GPSManager.LOG_TAG, GPSManager.getTime()+" GEO_FENCE: old Removed");
}
#Override protected void onHandleIntent(Intent intent) {
int transition = LocationClient.getGeofenceTransition(intent);
if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER) || (transition == Geofence.GEOFENCE_TRANSITION_EXIT)){
Log.d(GPSManager.LOG_TAG,"GEO_FENCE Transition detected");
Toast.makeText(context, "Geo fence movement detected", Toast.LENGTH_LONG).show();
ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 1000); // 200 is duration in ms
} else {
Log.d(GPSManager.LOG_TAG,"GEO_FENCE Transition UPDATE");
}
}
}
and in Manifest file I have declared:
<service android:name="com.Utilities.GeofenceManager" android:exported="true" />
also have tried:
<service android:name="com.Utilities.GeofenceManager" android:exported="false" />
<service android:name=".GeofenceManager" android:exported="false" />
Geofence is added as onAddGeofencesResult() method is called with success
Manage to fix the problem, by creating a new class for Geofence transition Intent,
and removed the IntentService code from GeofenceManager class
public class GeofenceIntentService extends IntentService {
public GeofenceIntentService() {
super("GeofenceIntentService");
}
#Override protected void onHandleIntent(Intent intent) {
int transition = LocationClient.getGeofenceTransition(intent);
if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER) || (transition == Geofence.GEOFENCE_TRANSITION_EXIT)){
Log.d(GPSManager.LOG_TAG, "GEO_FENCE "+((transition == Geofence.GEOFENCE_TRANSITION_ENTER) ? "ENTER " : "EXIT") +" Transition detected");
Toast.makeText(this, "Geo fence movement detected", Toast.LENGTH_LONG).show();
ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 80);
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE, 1000); // 200 is duration in ms
} else {
Log.d(GPSManager.LOG_TAG,"GEO_FENCE Transition UPDATE");
}
}
}

Get GPS Location in a Broadcast Receiver/or Service to Broadcast Receiver data transfer

I am new to android.
I want to get GPS Location in a broadcast receiver but it shows an error.
My code is :
public void onReceive(Context context, Intent intent) {
LocationManager locManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
// errors in getSystemService method
LocationListener locListener = new MyLocationListener();
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
locListener);
Location loc = locManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Log.d(" **location**", " location" + loc.getLatitude());
}
Questions :
Is it possible to get GPS Location data in Broadcast receiver?
Another alternative way I tried so far was to use a service which is invoked by the Broadcast receiver. The service can get GPS data, but how can I get it in the Broadcast receiver?
yes both of them are possible.
your service with a timer to send request to location receiver in periods of time:
public class SrvPositioning extends Service {
// An alarm for rising in special times to fire the
// pendingIntentPositioning
private AlarmManager alarmManagerPositioning;
// A PendingIntent for calling a receiver in special times
public PendingIntent pendingIntentPositioning;
#Override
public void onCreate() {
super.onCreate();
alarmManagerPositioning = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);
Intent intentToFire = new Intent(
ReceiverPositioningAlarm.ACTION_REFRESH_SCHEDULE_ALARM);
intentToFire.putExtra(ReceiverPositioningAlarm.COMMAND,
ReceiverPositioningAlarm.SENDER_SRV_POSITIONING);
pendingIntentPositioning = PendingIntent.getBroadcast(this, 0,
intentToFire, 0);
};
#Override
public void onStart(Intent intent, int startId) {
try {
long interval = 60 * 1000;
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long timetoRefresh = SystemClock.elapsedRealtime();
alarmManagerPositioning.setInexactRepeating(alarmType,
timetoRefresh, interval, pendingIntentPositioning);
} catch (NumberFormatException e) {
Toast.makeText(this,
"error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this,
"error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onDestroy() {
this.alarmManagerPositioning.cancel(pendingIntentPositioning);
ReceiverPositioningAlarm.stopLocationListener();
}
}
your receiver with a listener. listener can be used in your activity to be notified that a new location is ready for you:
public class ReceiverPositioningAlarm extends BroadcastReceiver {
public static final String COMMAND = "SENDER";
public static final int SENDER_ACT_DOCUMENT = 0;
public static final int SENDER_SRV_POSITIONING = 1;
public static final int MIN_TIME_REQUEST = 5 * 1000;
public static final String ACTION_REFRESH_SCHEDULE_ALARM =
"org.mabna.order.ACTION_REFRESH_SCHEDULE_ALARM";
private static Location currentLocation;
private static Location prevLocation;
private static Context _context;
private String provider = LocationManager.GPS_PROVIDER;
private static Intent _intent;
private static LocationManager locationManager;
private static LocationListener locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras){
try {
String strStatus = "";
switch (status) {
case GpsStatus.GPS_EVENT_FIRST_FIX:
strStatus = "GPS_EVENT_FIRST_FIX";
break;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
strStatus = "GPS_EVENT_SATELLITE_STATUS";
break;
case GpsStatus.GPS_EVENT_STARTED:
strStatus = "GPS_EVENT_STARTED";
break;
case GpsStatus.GPS_EVENT_STOPPED:
strStatus = "GPS_EVENT_STOPPED";
break;
default:
strStatus = String.valueOf(status);
break;
}
Toast.makeText(_context, "Status: " + strStatus,
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onLocationChanged(Location location) {
try {
Toast.makeText(_context, "***new location***",
Toast.LENGTH_SHORT).show();
gotLocation(location);
} catch (Exception e) {
}
}
};
// received request from the calling service
#Override
public void onReceive(final Context context, Intent intent) {
Toast.makeText(context, "new request received by receiver",
Toast.LENGTH_SHORT).show();
_context = context;
_intent = intent;
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(provider)) {
locationManager.requestLocationUpdates(provider,
MIN_TIME_REQUEST, 5, locationListener);
Location gotLoc = locationManager
.getLastKnownLocation(provider);
gotLocation(gotLoc);
} else {
Toast t = Toast.makeText(context, "please turn on GPS",
Toast.LENGTH_LONG);
t.setGravity(Gravity.CENTER, 0, 0);
t.show();
Intent settinsIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
settinsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
_context.startActivity(settinsIntent);
}
}
private static void gotLocation(Location location) {
prevLocation = currentLocation == null ? null : new Location(
currentLocation);
currentLocation = location;
if (isLocationNew()) {
OnNewLocationReceived(location);
Toast.makeText(_context, "new location saved",
Toast.LENGTH_SHORT).show();
stopLocationListener();
}
}
private static boolean isLocationNew() {
if (currentLocation == null) {
return false;
} else if (prevLocation == null) {
return true;
} else if (currentLocation.getTime() == prevLocation.getTime()) {
return false;
} else {
return true;
}
}
public static void stopLocationListener() {
locationManager.removeUpdates(locationListener);
Toast.makeText(_context, "provider stoped", Toast.LENGTH_SHORT)
.show();
}
// listener ----------------------------------------------------
static ArrayList<OnNewLocationListener> arrOnNewLocationListener =
new ArrayList<OnNewLocationListener>();
// Allows the user to set a OnNewLocationListener outside of this class
// and react to the event.
// A sample is provided in ActDocument.java in method: startStopTryGetPoint
public static void setOnNewLocationListener(
OnNewLocationListener listener) {
arrOnNewLocationListener.add(listener);
}
public static void clearOnNewLocationListener(
OnNewLocationListener listener) {
arrOnNewLocationListener.remove(listener);
}
// This function is called after the new point received
private static void OnNewLocationReceived(Location location) {
// Check if the Listener was set, otherwise we'll get an Exception
// when we try to call it
if (arrOnNewLocationListener != null) {
// Only trigger the event, when we have any listener
for (int i = arrOnNewLocationListener.size() - 1; i >= 0; i--) {
arrOnNewLocationListener.get(i).onNewLocationReceived(
location);
}
}
}
}
an interface for listener:
import android.location.Location;
public interface OnNewLocationListener {
public abstract void onNewLocationReceived(Location location);
}
in your activity for getting just one point:
protected void btnGetPoint_onClick() {
Intent intentToFire = new Intent(
ReceiverPositioningAlarm.ACTION_REFRESH_SCHEDULE_ALARM);
intentToFire.putExtra(ReceiverPositioningAlarm.COMMAND,
ReceiverPositioningAlarm.SENDER_ACT_DOCUMENT);
sendBroadcast(intentToFire);
OnNewLocationListener onNewLocationListener = new OnNewLocationListener() {
#Override
public void onNewLocationReceived(Location location) {
// use your new location here then stop listening
ReceiverPositioningAlarm.clearOnNewLocationListener(this);
}
};
// start listening for new location
ReceiverPositioningAlarm
.setOnNewLocationListener(onNewLocationListener);
}
edit:
if you want to start service in your activity:
this.startService(new Intent(this, SrvPositioning.class));
similarly you can define a listener in your service to receive locations found by receiver
Edit
Add the following lines in Manifest
<service
android:name="org.mabna.order.services.SrvPositioning"
android:enabled="true" />
<receiver android:name="org.mabna.order.receivers.ReceiverPositioningAlarm" >
<!-- this Broadcast Receiver only listens to the following intent -->
<intent-filter>
<action android:name="org.mabna.order.ACTION_REFRESH_SCHEDULE_ALARM" />
</intent-filter>
</receiver>
From BroadcastReceiver I could not start Location Manager as well. So I started a service on BroadcastReceiver and in that service I manipulated Location Manager. I think I found this solution in Android development documentation. You also can start Activity instead of Service.
Here is the code of switch to Service on BroadcastReceiver:
write this in onReceive method
Intent serviceIntent = new Intent(context,MyService.class);
serviceIntent.putExtra("locateRequest", "locateRequest"); // if you want pass parameter from here to service
serviceIntent.putExtra("queryDeviceNumber", results[1]);
context.startService(serviceIntent); //start service for get location
STEP 1:
Open AndroidManifest.xml and add the broadcast receiver.
<receiver
android:name=".Util.GpsConnectorReceiver"
android:enabled="true">
<intent-filter>
<!-- Intent filters for broadcast receiver -->
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>`
STEP 2: create activity with dialog theme:
<activity
android:name=".Activity.ActivityDialogGps"
android:theme="#style/AppTheme.Dark.Dialog"></activity>
STEP 3:
Make a BroadcastReceiver Class named GpsConnectorReceiver
public class GpsConnectorReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
Intent pushIntent = new Intent(context, ConnectivityCheck .class);
context.startService(pushIntent);
}
}}
STEP 4: Make another service class named ConnectivityCheck :
public class ConnectivityCheck extends Service {
#Override
public void onCreate() {
super.onCreate();
if (!checkConnection()) {
Toast.makeText(context, "off", Toast.LENGTH_LONG).show();
Intent dialogIntent = new Intent(this, ActivityDialogInternet.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
}
stopSelf();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private boolean checkConnection() {
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}}
STEP 5: create a activity called ActivityDialogGps
public class ActivityDialogGps extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog_gps);
}}
STEP 6: When Gps connection is turned off ActivityDialogGps called and show the dialog:

Categories

Resources