I found hundreds of topics related to the same problem, but I cannot understand where I get wrong! Because I have written the same code basically...
This is a service which controls the position and adds a promityAlert
public class GeoReminderService extends Service implements LocationListener{
private LocationManager locationManager;
private final String proximityIntentAction = "com.example.geo.ProximityIntentReceiver";
private float latitude;
private float longitude;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 400, 10, this);
addProximityAlert(45.477872,9.23457);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onLocationChanged(Location location) {
Log.v("Service","Location changed");
if (location != null) {
Log.v("Location changed : Lat: ", ""+location.getLatitude());
Log.v("Location changed : Lon: ", ""+location.getLongitude());
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
private void addProximityAlert(double latitude, double longitude) {
Log.v("Service","proximity alert added" + latitude +" "+ longitude);
Intent intent = new Intent(proximityIntentAction);
PendingIntent proximityIntent = PendingIntent.getBroadcast(getApplicationContext(), -1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
locationManager.addProximityAlert(latitude, longitude, 3000, -1, proximityIntent);
IntentFilter filter = new IntentFilter(proximityIntentAction);
registerReceiver(new ProximityIntentReceiver(), filter);
}
Instead this one is the receiver which should captures the event
public class ProximityIntentReceiver extends BroadcastReceiver {
private static final int NOTIFICATION_ID = 1000;
#Override
public void onReceive(Context context, Intent intent) {
Log.v("proximity receiver", "alert received");
String key = LocationManager.KEY_PROXIMITY_ENTERING;
Boolean entering = intent.getBooleanExtra(key, false);
if (entering) {
Log.v("ProximityIntentReceiver", "entering");
}
else {
Log.v("ProximityIntentReceiver", "exiting");
}
}
Even if I change the position (I am using the Android emulator) the event onReceive doesn't fire. At the same time I am sure that I am changing the position correctly , since the event locationChanged works. Can anyone help me, please?
Have you declared ProximityIntentReceiver in the manifest?
In the same area of the manifest where you declare activites, etc., you'd also declare your BroadcastReceiver.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.geo"
android:versionCode="001"
android:versionName="0.1"
>
<application>
...
<receiver android:name=".ProximityIntentReceiver">
</receiver>
</application>
</manifest>
Related
I want to get the current location and add a proximity alert to that location. When ever I exit or enter a radius around the current location. As I am getting the current location's latitude and longitude and adding the proximity alert, I get an alert as soon as I register. But I am not getting when I exit even if i am on the foreground. I have registered my reciever in the manifest.
This is my Activity.
public class GeoFencer extends FragmentActivity implements LocationListener {
private LocationManager locMan, locManForProximitySensor;
private Intent i;
private PendingIntent pService;
Context context;
#Override
protected void onCreate(Bundle arg0) {
setContentView(R.layout.geo_fencer_layout);
super.onCreate(arg0);
context = this;
locMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locManForProximitySensor = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
i = new Intent("com.packagename.proximity");
pService = PendingIntent.getBroadcast(this, 0 , i, 0);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater inflater= getMenuInflater();
inflater.inflate(R.menu.geofencemenu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.action_geo){
if(locMan.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
else if(locMan.isProviderEnabled(LocationManager.GPS_PROVIDER)){
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
else
Toast.makeText(this, "GPS is disabled. Please Enable.", Toast.LENGTH_LONG).show();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onLocationChanged(Location location) {
locManForProximitySensor.addProximityAlert(location.getLatitude(), location.getLongitude(), 10, -1 , pService) ;
Log.d(getClass().getSimpleName(),"Proximity alert added (" + location.getLatitude() + ", "+ location.getLongitude() + ")");
locMan.removeUpdates(this);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
My Reciever
public class ProximityAlertReceiver extends BroadcastReceiver{
private static final int NOTIFICATION_ID = 1000;
#Override
public void onReceive(Context context, Intent intent) {
String key = LocationManager.KEY_PROXIMITY_ENTERING;
String message = " ";
Boolean entering = intent.getBooleanExtra(key, false);
if (entering) {
Log.d(getClass().getSimpleName(), "entering");
message = "You are entering your point";
}
else {
Log.d(getClass().getSimpleName(), "exiting");
message = "You are exiting your point";
}
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.app_icon)
.setContentTitle("CompanyName")
.setContentText(message);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
Please tell me what I am doing wrong here. Thanks in Adavance.
you should add one of this flags: PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_UPDATE_CURRENT .
i want a background service class that which will get the user current location sends as a notification to the user if the user changes its location then the updated location will sends back to the user as a notification..even if the user close the application then also will receive the notification (the service will trace the location in background even application closed)
currently i am using this service for tracing the location which works if the application in foreground
can u pls. help me to get out of this i am struggling for 4 hours
in your activity unlike the one that you are using make your buttons start and stop the service and it will run in the background unless the user reopens the app and stops it
Intent i = new Intent(MainActivity.this,gpsservice.class);
startService(new Intent(i));
or to stop
Intent j = new Intent(MainActivity.this,gpsservice.class);
stopService(new Intent(j));
use this service
public class gpsservice extends Service{
private LocationManager locationManager;
MyLocationListener locationListenerp;
public gpsservice() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
locationListenerp = new MyLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 5000, 10, locationListenerp);
}
#Override
public void onDestroy() {
locationManager.removeUpdates(locationListenerp);
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "location Service Started", Toast.LENGTH_LONG).show();
}
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
Toast.makeText(getApplicationContext(), "I was here", Toast.LENGTH_LONG).show();
}
#Override
public void onProviderDisabled(String s) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
}
I have a service within an android app which implements locationListener to keep track of users changing location.
Every time the location is changed, I want to send it to the server.
So, in the onLocationChanged method I am fetching the latitude and longitude. I want to send them to the server over network. Hence, I created a new thread (as network operations are not allowed on main thread). However, I get a java.lang.NullPointerException for this thread.
What should I do?
Here's my code .....
public class SService extends Service implements LocationListener{
public class LocalBinder extends Binder {
SplashService getService() {
return SplashService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
//Shows notification
showNotification();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("SService", "Received start id " + startId + ": " + intent);
// Sets parameters and location providers
setLocationParam();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// Cancel the persistent notification.
mNM.cancel(NOTIFICATION);
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients. See
// RemoteService for a more complete example.
private final IBinder mBinder = new LocalBinder();
#Override
public void onLocationChanged(Location location) {
// Getting latitude of the current location
latitude = location.getLatitude();
// Getting longitude of the current location
longitude = location.getLongitude();
Log.v("SSERVICE",latitude+" "+longitude);
final SMessage sm=new SMessage("0", latitude, longitude,"");
// Creates new thread
new SThread(sm).start();
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
i'm currently writing an app that should to the following:
The UI only contains one toggle button. If it is turned on the GPS Position shall be sent to an external server. If it is turned off, nothing shall happen.
If the Button was turned on and the app (activity) is closed the location should still be send until the Button is turned off again.
How can i achieve this ? I read a lot of threads and tutorials and on dev.google.com, but i was not able to find the best solution for my problem.
My current approach:
MainActivity.java
public void onClick(View v) {
if (onOffButton.isChecked()) {
Intent startIntent = new Intent(this, LocationService.class);
startService(startIntent);
} else {
stopService(new Intent(this, LocationService.class));
}
}
LocationService.java
public class LocationService extends Service implements LocationListener {
final public static String START_ACTION = "START_LOCATION";
final public static int NOTE_ID = 1;
private int updateRate;
private LocationManager locationManager;
private NotificationManager notifyManager;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// show popup message
Toast.makeText(this, getText(R.string.start_message), Toast.LENGTH_SHORT).show();
// display icon in status bar
requestLocationUpdates();
}
private void requestLocationUpdates() {
if(locationManager != null)
locationManager.removeUpdates(this);
// get location service
Criteria crit = new Criteria();
crit.setPowerRequirement(Criteria.ACCURACY_FINE);
String bestProvider = getLocationManager().getBestProvider(crit, true);
getLocationManager().requestLocationUpdates(bestProvider, updateRate * 1000,
0 /* minDist */, this);
LocationService.running = true;
}
#Override
public void onDestroy() {
super.onDestroy();
getLocationManager().removeUpdates(this);
notifyManager.cancel(NOTE_ID);
Toast.makeText(this, getText(R.string.stop_message), Toast.LENGTH_SHORT).show();
LocationService.running = false;
}
#Override
public void onLocationChanged(Location location) {
//Send Location to Server
}
#Override
public void onProviderDisabled(String provider) {
// TODO stop service, notify user
}
#Override
public void onProviderEnabled(String provider) {
requestLocationUpdates();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO notify user
}
private LocationManager getLocationManager() {
if (this.locationManager == null)
this.locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return this.locationManager;
}
}
I got this from a very old gps tracker i found on the Internet (i know that onStart() is deprecated and should replaced with onCommandStart()) I just want to know if the general approach is good..
Regards.
The approach looks fine. You just need to implement the call-back methods to report your location.
My app scenario is that I want to track employees location. I have a broadcastreceiver which listens device boot broadcast and register an alarm manager. When alarm manager ticks, it registers two location listeners, one to listen to gps and other for network. I want that when I got first location update in onLocationChange() method, save location and unregister that location listener so that when alarm manager ticks again, it does not get duplicate. To unregister, I have location listeners as static objects to access them in onLocationChange(). But I have found that it is NOT removing location listener. Here is my code example:
public class BootTimeServiceActivator extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Calendar calendar = Calendar.getInstance();
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent mIntent = new Intent(context, MyBroadCastReceiver.class);
PendingIntent mPendingIntent = PendingIntent.getBroadcast(context, 0, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 20 * 60 * 1000, mPendingIntent);
}
}
//..........
public class MyBroadCastReceiver extends BroadcastReceiver{
public static LocationManager locationManager;
public static MyLocationListener networkLocationListener;
public static MyLocationListener gpsLocationListener;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "Alarm has been called...", Toast.LENGTH_SHORT).show();
initLocationListeners(context);
registerLocationListeners();
}
public void initLocationListeners(Context context) {
locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
networkLocationListener = new MyLocationListener(context);
gpsLocationListener = new MyLocationListener(context);
}
public void registerLocationListeners() {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, gpsLocationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100, 0, gpsLocationListener);
}
}
\\.....
public class MyLocationListener implements LocationListener {
Context context;
public MyLocationListener(Context context) {
this.context = context;
}
#Override
public void onLocationChanged(Location location) {
if(location != null) {
SDCardService sdService = new SDCardService(context);
try {
sdService.logToDB(location);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("provider",location.getProvider());
if(location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
MyBroadCastReceiver.locationManager.removeUpdates(MyBroadCastReceiver.gpsLocationListener);
}
else if(location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
MyBroadCastReceiver.locationManager.removeUpdates(MyBroadCastReceiver.networkLocationListener);
}
}
}
Can anyone guide me where I am wrong?
Try this..
lmNetwork.removeUpdates(networkLocationListener);
lmGps.removeUpdates(gpsLocationListener);
Ahh... I have a typo mistake. Actually in MyBroadCastREciever class I was registering gpsListener twice as:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
100, 0,
gpsLocationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
100, 0,
networkLocationListener); //previously was gpsLocationListener again. Wrong.
that's y network listener was not being removed.
you can do it this way with an insider class and remove the listener onPause() :
#Override
protected void onPause() {
super.onPause();
GPSlocationManager.removeUpdates(GPSLocationListener);
CellLOcationManager.removeUpdates(NetworkLocationListener);
}
private void SetLocationManager() {
GPSlocationManager =(LocationManager)getSystemService(Context.LOCATION_SERVICE);
CellLOcationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
NetworkLocationListener = new MyNetworkLocationListener();
GPSLocationListener = new MyGPSLocationListener();
GPSlocationManager.requestLocationUpdates("gps", 5000, 1, GPSLocationListener);
CellLOcationManager.requestLocationUpdates("network", 10000, 1, NetworkLocationListener);
}
private class MyNetworkLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
}