Android requestLocationUpdates using PendingIntent with BroadcastReceiver - android

How do I use
requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
PendingIntent intent)
In BroadcastReciver so that I can keep getting GPS coordinates.
Do I have to create a separate class for the LocationListener ?
Goal of my project is when I receive BOOT_COMPLETED to start getting GPS lats and longs periodically.
Code I tried is :
public class MobileViaNetReceiver extends BroadcastReceiver {
LocationManager locmgr = null;
String android_id;
DbAdapter_GPS db;
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
startGPS(context);
} else {
Log.i("MobileViaNetReceiver", "Received unexpected intent "
+ intent.toString());
}
}
public void startGPS(Context context) {
Toast.makeText(context, "Waiting for location...", Toast.LENGTH_SHORT)
.show();
db = new DbAdapter_GPS(context);
db.open();
android_id = Secure.getString(context.getContentResolver(),
Secure.ANDROID_ID);
Log.i("MobileViaNetReceiver", "Android id is _ _ _ _ _ _" + android_id);
locmgr = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5,
onLocationChange);
}
LocationListener onLocationChange = new LocationListener() {
public void onLocationChanged(Location loc) {
// sets and displays the lat/long when a location is provided
Log.i("MobileViaNetReceiver", "In onLocationChanged .....");
String latlong = "Lat: " + loc.getLatitude() + " Long: "
+ loc.getLongitude();
// Toast.makeText(this, latlong, Toast.LENGTH_SHORT).show();
Log.i("MobileViaNetReceiver", latlong);
try {
db.insertGPSCoordinates(android_id,
Double.toString(loc.getLatitude()),
Double.toString(loc.getLongitude()));
} catch (Exception e) {
Log.i("MobileViaNetReceiver",
"db error catch _ _ _ _ " + e.getMessage());
}
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
//pauses listener while app is inactive
/*#Override
public void onPause() {
super.onPause();
locmgr.removeUpdates(onLocationChange);
}
//reactivates listener when app is resumed
#Override
public void onResume() {
super.onResume();
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, onLocationChange);
}*/
}

There are two ways of doing this:
Use the method that you are and register a BroadcastReceiver which has an intent filter which matches the Intent that is held within your PendingIntent (2.3+) or, if you are only interested in a single location provider, requestLocationUpdates (String provider, long minTime, float minDistance, PendingIntent intent) (1.5+) instead.
Register a LocaltionListener using the requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener) method of LocationManager.
I think that you are getting a little confused because you can handle the location update using either a BroadcastReceiver or a LocationListener - you don't need both. The method of registering for updates is very similar, but how you receive them is really very different.
A BroadcastReceiver will allow your app / service to be woken even if it is not currently running. Shutting down your service when it is not running will significantly reduce the impact that you have on your users' batteries, and minimise the chance of a Task Killer app from terminating your service.
Whereas a LocationListener will require you to keep your service running otherwise your LocationListener will die when your service shuts down. You risk Task Killer apps killing your service with extreme prejudice if you use this approach.
From your question, I suspect that you need to use the BroadcastReceiver method .

public class MobileViaNetReceiver extends BroadcastReceiver {
private static final String TAG = "MobileViaNetReceiver"; // please
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())){
Log.i(TAG, "Boot : registered for location updates");
LocationManager lm = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
Intent intent = new Intent(context, this.getClass());
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000,5,pi);
} else {
String locationKey = LocationManager.KEY_LOCATION_CHANGED;
if (intent.hasExtra(locationKey)) {
Location loc = (Location) intent.getExtras().get(locationKey);
Log.i(TAG, "Location Received");
try {
DbAdapter_GPS db = new DbAdapter_GPS(context);//what's this
db.open();
String android_id = Secure.getString(
context.getContentResolver(), Secure.ANDROID_ID);
Log.i(TAG, "Android id is :" + android_id);
db.insertGPSCoordinates(android_id,
Double.toString(loc.getLatitude()),
Double.toString(loc.getLongitude()));
} catch (Exception e) { // NEVER catch generic "Exception"
Log.i(TAG, "db error catch :" + e.getMessage());
}
}
}
}
}

Related

auto send sms when gps location is available

i'm developing an app to send user location via sms after a fixed time and if the phone restarts the app should starts automatically in the background without any launcher activity. I have quiet accomplished my task I'm only facing problem in getting location, as gps takes some time and app gets crash when it does not find any location.
here is my code of main Activity
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startLocationTracking();
}
private void startLocationTracking()
{
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent alarmintent1 = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent sender1=PendingIntent.getBroadcast(MainActivity.this, 100, alarmintent1, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
try {
am.cancel(sender1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("exjfkd"+e);
}
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE,10);
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1000*600, sender1);
System.out.println("set timer");
}
}
public class AlarmReceiver extends BroadcastReceiver{
long time = 600* 1000;
long distance = 10;
#SuppressLint("NewApi")
#Override
public void onReceive(final Context context, Intent intent) {
System.out.println("alarm receiver....");
Intent service = new Intent(context, MyService.class);
context.startService(service);
//Start App On Boot Start Up
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent App = new Intent(context, MainActivity.class);
App.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(App);
}
try{
LocationManager locationManager = (LocationManager)context
.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(provider, time,
distance, locationListener);
Location location = locationManager.getLastKnownLocation(provider);
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String device_id = tm.getDeviceId(); // returns IMEI number
String phoneNo = "+923362243969";
String Text = "Latitude = " + location.getLatitude() +" Longitude = " + location.getLongitude() + " Device Id: " + device_id;
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null, Text, null, null);
Log.i("Send SMS", "");
}
catch (Exception e) {
e.printStackTrace();
}
this.abortBroadcast();
}
LocationListener locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onLocationChanged(Location location) {
}
};
}
i'm little confuse in logic I want my app to send sms when gps coordinates are available. and if gps in disabled on the phone it if network is available on the phone it should get the location through network and send it through the network.
EDIT
Your app is crashing since for the first time after reboot GPS/network won't have the lastknowlocation since
Location location = locationManager.getLastKnownLocation(provider);
In this line you will be receiving location as null.
String Text = "Latitude = " + location.getLatitude() +" Longitude = " + location.getLongitude() + " Device Id: " + device_id;
and in this line you will get the null pointer exception since location.getLatitude() is not posible.
so before this code try to check location!=null.
if(location!=null){
String Text = "Latitude = " + location.getLatitude() +" Longitude = " + location.getLongitude() + " Device Id: " + device_id;
}
Use this method to know the status of GPS availablity
public boolean isgpsavailable(Activity activity) {
LocationManager locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
boolean result = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
return result;
}
Then put your code into a if(isgpsavailable(this)){...} Statement
You can send SMS with the android.telephony package. You can see how add to your project here: How do I add ITelephony.aidl to eclipse?
Something like this permit you send a textSMS:
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, scAddress, texto, null, null);
Hope it helps you!!

Cannot able to get Location exactly every 10 minutes using Pending Intent and AlarmManager

I posted my Requirement,Problem and code,I don't know what is wrong with my code,Any help..
My Requirement : I want to get latitude,longtitude from GPS every 10 minutes
Problem : I am Keep on Getting latitude,longtitude
My Code :
1].I am using this code in activity,I am starting Broadcast Receiver from activity
//Pending Intent
Intent in = new Intent(this,GPSReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, in, 0);
//Alaram manager
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
am.setRepeating(AlarmManager.RTC, cal.getTimeInMillis(), 10*60*1000, pi);
2].BroadCast Class "GPSReceiver.class",From here I am starting service names as GPSService
public class GPSReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context,GPSService.class);
context.startService(service);
}
}
3].Service Class "GPSService",This is for getting location updates
public class GPSService extends Service {
#Override
public IBinder onBind(Intent arg0) {
return null;
}
//Flag to know GPS Status
boolean isGPSEnabled = false;
LocationManager locationmanager;
String locationgpsprovider = LocationManager.GPS_PROVIDER;
double latitude;
double longtitude;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//To get Location service
locationmanager = (LocationManager) getSystemService(LOCATION_SERVICE);
//To get GPS Status
isGPSEnabled = locationmanager.isProviderEnabled(locationgpsprovider);
if (!isGPSEnabled) {
Toast.makeText(this, "Please check your GPS connection", Toast.LENGTH_LONG).show();
}else {
locationmanager.requestLocationUpdates(locationgpsprovider, 0, 0, ll);
}
return START_NOT_STICKY;
}
LocationListener ll = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onLocationChanged(Location location) {
Log.i("Hei", "10 minutes up");
latitude = location.getLatitude();
longtitude = location.getLongitude();
}
};
Everythime you alarm goes on it delivers another Intent to Service and locationmanager starts all over again. You don't need an Alarm here since LocationManager already deliveries location at specified intervals.
It's enough starting your Service only once and instantiate your locationmanager stuff at onCreate. In this case use onStartCommand only to return START_NOT_STICKY.
Tip 1: Define a condition to stop the service, don't let it run forever.
Tip 2:Take a look at requestLocationUpdates javadoc to setup a proper minTime.
Tip 3:You can find more tips in Android docs:
http://developer.android.com/training/location/index.html

LocationListener and updates to webservice in an interval of time as background proocess

My Andoid application contains many activities. I want to run a background process that is independent of these activities (no matter whichever activity is running on UI). In this background process, I want to capture Location Updates using LocationListener and want to call web service to store the captured location in the database. And this calling of webservice has to happen only in 2 min interval. Can someone please help me in implementing this.
Thanks.
Android developer
Check this
public class LocationUpdator extends Service{
Location location;
private int normallocationwait = 2000;
Timer timer = new Timer();
private final Handler handler = new Handler();
Intent intent;
public void onCreate(){
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
updateNotification();
}
//int onStartCommand(Intent intent, int flags, int startId)
public void onStart(Intent intent,int startId){
super.onStart(intent, startId);
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
Log.v("Location Servics", "Start Service");
}
public void onDestroy(){
super.onDestroy();
Log.v("Location Servics", "Destroy Service");
}
protected void updateNotification() {
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new MyLocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, normallocationwait, 0.250f, locationListener);
location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
private class MyLocationlistener implements LocationListener {
public void onLocationChanged(Location location){
if(location!=null){
dumpLocation(location);
}
}
public void onProviderDisabled(String provider){
Log.v("Loc Update","\nProvider disabled: " + provider);
}
public void onProviderEnabled(String provider){
Log.v("Loc Update","\nProvider enabled: " + provider);
}
public void onStatusChanged(String provider, int status, Bundle extras){
Log.v("Loc Update","\nProvider status changed: " + provider + ", status="
+ status + ", extras=" + extras);
}
private void dumpLocation(Location location) {
Log.v("Loc Update","\n" + location.toString());
Log.v("Demo", location.toString());
if(GlobalValues.whereRegister == 1){
String url = TaxiUrls.taxiLocationUpdate_url + "taxi_device_id="+ GlobalValues.deviceID +
"&lat="+ location.getLatitude() + "&lng=" + location.getLongitude();
Toast.makeText(getBaseContext(), "Location Update", Toast.LENGTH_SHORT).show();
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
try {
HttpResponse response = httpclient.execute(httppost);
Log.v("Message", response.toString());
} catch (ClientProtocolException e) {
Log.e("Sending Message",e.getMessage().toString());
} catch (IOException e) {
Log.e("Sending Message",e.getMessage().toString());
}
}
}
}
}
Maybe worth launching a simple AsyncTask to do this in the background.

get current device location after specific interval

I want to capture current location (latitude and longitude) of android device after specific interval (say 30 mins).. My class (or service ?? not sure what to use ) will start listening to LocationManagerListener when device booting completed. What is the best way of implementing this? how we can make use of locationChanged() method in this scenario?
This is what i think it can go:
Listen for boot completed event and set alarm service:
public class OnBootReceiver extends BroadcastReceiver {
private static final int PERIOD=1800000; // 30 minutes
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0,
i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime()+60000,
PERIOD,
pi);
}
}
Listen for alarm service and initiate the location capture class or service:
public class OnAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
WakefulIntentService.acquireStaticLock(context);
context.startService(new Intent(context, locationCapture.class));
or
new locationCapture().classmethod();
}
}
I am not sure how locationCapture class should be implemented. Should it be normal Java class or Service class?
Any help will be appreciated.
This the service class you can use it
public class ServiceLocation extends Service{
private LocationManager locMan;
private Boolean locationChanged;
private Handler handler = new Handler();
public static Location curLocation;
public static boolean isService = true;
LocationListener gpsListener = new LocationListener() {
public void onLocationChanged(Location location) {
if (curLocation == null) {
curLocation = location;
locationChanged = true;
}else if (curLocation.getLatitude() == location.getLatitude() && curLocation.getLongitude() == location.getLongitude()){
locationChanged = false;
return;
}else
locationChanged = true;
curLocation = location;
if (locationChanged)
locMan.removeUpdates(gpsListener);
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status,Bundle extras) {
if (status == 0)// UnAvailable
{
} else if (status == 1)// Trying to Connect
{
} else if (status == 2) {// Available
}
}
};
#Override
public void onCreate() {
super.onCreate();
curLocation = getBestLocation();
if (curLocation == null)
Toast.makeText(getBaseContext(),"Unable to get your location", Toast.LENGTH_SHORT).show();
else{
//Toast.makeText(getBaseContext(), curLocation.toString(), Toast.LENGTH_LONG).show();
}
isService = true;
}
final String TAG="LocationService";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onLowMemory() {
super.onLowMemory();
}
#Override
public void onStart(Intent i, int startId){
handler.postDelayed(GpsFinder,1);
}
#Override
public void onDestroy() {
handler.removeCallbacks(GpsFinder);
handler = null;
Toast.makeText(this, "Stop services", Toast.LENGTH_SHORT).show();
isService = false;
}
public IBinder onBind(Intent arg0) {
return null;
}
public Runnable GpsFinder = new Runnable(){
public void run(){
Location tempLoc = getBestLocation();
if(tempLoc!=null)
curLocation = tempLoc;
tempLoc = null;
handler.postDelayed(GpsFinder,1000);// register again to start after 1 seconds...
}
};
private Location getBestLocation() {
Location gpslocation = null;
Location networkLocation = null;
if(locMan==null){
locMan = (LocationManager) getApplicationContext() .getSystemService(Context.LOCATION_SERVICE);
}
try {
if(locMan.isProviderEnabled(LocationManager.GPS_PROVIDER)){
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000, 1, gpsListener);// here you can set the 2nd argument time interval also that after how much time it will get the gps location
gpslocation = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
if(locMan.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000, 1, gpsListener);
networkLocation = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
} catch (IllegalArgumentException e) {
//Log.e(ErrorCode.ILLEGALARGUMENTERROR, e.toString());
Log.e("error", e.toString());
}
if(gpslocation==null && networkLocation==null)
return null;
if(gpslocation!=null && networkLocation!=null){
if(gpslocation.getTime() < networkLocation.getTime()){
gpslocation = null;
return networkLocation;
}else{
networkLocation = null;
return gpslocation;
}
}
if (gpslocation == null) {
return networkLocation;
}
if (networkLocation == null) {
return gpslocation;
}
return null;
}
}
You can set time into the handler or into the requestLocationUpdates(). you need to start this service from home. As into I have set the 1 sec for both in handler and requestLocationUpdate() for getting location after 1 sec and update me.
Edited:
As this service for getting current location of the user you can start from home activity and also start from boot time. With the home activity sure that if the service was stop by the user using another application like task killer then when the user launch your application then from the home this service will be start again, to start service you can do like this way
startService(new Intent(YourActivity.this,ServiceLocation.class));
When you need to stop service it will call the onDestroy() so the handler can cancel the thread to continue for getting the location.
As the GPS set with the 1 sec(1000) this will getting the gps location every 1 sec but for getting that location you need to call every time and in my case i have set to 1 sec and as per your requirement set to 30 sec. So you gps getting the location every 1 sec and using this service in handler set the 30 min. for saving battery life you can also set the different time in to the gps request method so it will save the battery life.
you can remove the comparison part of location and current location because locationlistener every time call when the location was changed and you can use the curLocation anywhere in your application to get the current location but be sure first that you have to start this service first then after you can use otherwise you getting null pointer exception when you access the latitude and longitude of this object
Hope you got some idea and I got the answer about your queries
This guide with source codes for various API levels comes from source:
http://android-developers.blogspot.com/search/label/Location

Android GPS as an Activity

This is working perfectly for me.
public class GPSActivity extends Activity {
LocationManager locmgr = null;
String android_id;
DbAdapter db;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = new DbAdapter(getBaseContext());
db.open();
android_id = Secure.getString(getBaseContext().getContentResolver(), Secure.ANDROID_ID);
locmgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, this.onLocationChange);
Toast.makeText(getBaseContext(), "Waiting for location..." , Toast.LENGTH_SHORT).show();
}
LocationListener onLocationChange=new LocationListener() {
public void onLocationChanged(Location loc) {
String latlong = "Lat: " + loc.getLatitude() + " Long: " + loc.getLongitude();
Toast.makeText(getBaseContext(), latlong, Toast.LENGTH_SHORT).show();
try{
db.insertGPSCoordinates(android_id, Double.toString(loc.getLatitude()), Double.toString(loc.getLongitude()));
}
catch(Exception e){
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
};
//pauses listener while app is inactive
#Override
public void onPause() {
super.onPause();
locmgr.removeUpdates(onLocationChange);
}
//reactivates listener when app is resumed
#Override
public void onResume() {
super.onResume();
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, onLocationChange);
}
}
How do I use this from Broadcastreceiver ? I want to to start collecting co-ordinates when BOOT_COMPLETE. And keep that running depending on that locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, this.onLocationChange); setting. I am getting confused how to keep that working periodically.
Don't use and activity for this stuff. Use a Service. Here's what you do. Have a broadcast receiver that receives the BOOT_COMPLETE broadcast. When it receives the broadcast have it start up a service. In this service is where you put all your code for recording the locations. The service won't stop until you call stopService on it of for what ever reason you have your service call stopSelf().

Categories

Resources