Today i made my first background service that keeps running if i exit from my application.
It is logging lattitude and londitude.
I would like to add some more functions to my code, and i would like to ask your help about which way should i contine coding, and is it good that i made already?
I work with an Activity, with a handler that gets messages from background service:
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_act);
BackgroundLocationService.context=this;
Intent i = new Intent(this, BackgroundLocationService.class);
i.putExtra("handler", new Messenger(this.handler));
startService(i);
/*.......more code here......*/
}
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
// get data from msg
String result = msg.getData().getString("result");
Log.i("Activiti map: Locationing Service handler: ",
"get data: " + result);
super.handleMessage(msg);
}
};
And this is my background service:
public class BackgroundLocationService extends IntentService {
private static final String TAG = "Activiti map: Locationing Service";
private LocationManager locManager;
private LocationListener locListener = new MyLocationListener();
public static Context context;
private boolean gps_enabled = false;
private boolean network_enabled = false;
private boolean DEBUG=false;
private String latitude="0";
private String londitude="0";
Messenger messenger;
Timer t=new Timer();
public BackgroundLocationService()
{
super("myintentservice");
locManager = (LocationManager) context.getSystemService
(Context.LOCATION_SERVICE);
try {
gps_enabled =
locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
if(DEBUG)
Log.e(TAG, ex.toString());
}
try {
network_enabled =
locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
if(DEBUG)
Log.e(TAG, ex.toString());
}
if (gps_enabled) {
if(DEBUG)
Log.i(TAG, "Gps is Enabled!");
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0, 0, locListener);
} else {
if(DEBUG)
Log.i(TAG, "Gps is Disabled!");
}
if (network_enabled) {
if(DEBUG)
Log.i(TAG, "Network provider is enabled!");
locManager.requestLocationUpdates
(LocationManager.NETWORK_PROVIDER, 0, 0, locListener);
} else {
if(DEBUG)
Log.i(TAG, "Network provider is Disabled!");
}
}
#Override
protected void onHandleIntent(Intent intent) {
messenger=(Messenger) intent.getExtras().get("handler");
t.schedule(new TimerTask() {
#Override
public void run() {
// just call the handler every 3 Seconds
Message msg=Message.obtain();
Bundle data=new Bundle();
data.putString("result", "latitude: " + latitude+
" londitude: "+londitude);
msg.setData(data);
try {
messenger.send(msg);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 100,3000);
}
class MyLocationListener implements LocationListener {
private static final String TAG = "Activiti map: LocationListener";
public void onLocationChanged(Location location) {
if (location != null) {
locManager.removeUpdates(locListener);
londitude = Double.toString(location.getLongitude());
latitude = Double.toString(location.getLatitude());
if(DEBUG)
Log.i(TAG, "Londitude: " + londitude + " Latitude: " + latitude);
}
}
public void onProviderDisabled(String arg) {
if(DEBUG)
Log.i(TAG, "Provider just Disabled: " + arg);
}
public void onProviderEnabled(String arg) {
if(DEBUG)
Log.i(TAG, "Provider just Enabled: " + arg);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}
Some problems that i would like to solve:
Is it possible to control the handler the service or anything in my code to keep SURE, that the service is stopped, started, etc? So i would like to add controls for example from a widget button for turning on and off the service. How is it possible ?
And another thing: If i quickly starts and exit my application many times i got each time a handler initalized and i got multiple log messages. How can i make a singleton of this or something like that?
Thanks for helping
Use Application for those purposes.
You can implement singleton logic into Application class and manage your service.
If you close your activity, the Service asks Application if Activity alive.
On Launch Activity, Application knows about and Service can bind with above mentioned Activity by using some Interfaces that Application stores.
**
The main Activity must initiate Handler to make to Service to talk with Activity
Here is some code:
public class MyApplication extends Application{
private static MyApplication mSingleton;
private static final String PACKAGE = "com.code";
private static final String PROCESS_NAME = PACKAGE + ".ui";
private static final String SERVICE_NAME = PROCESS_NAME + "/" + PACKAGE + ".srvce.MyService";
#Override
public void onCreate() {
super.onCreate();
mSingleton = this;
}
public MyApplication getApp(){
return mSingleton;
}
....
public boolean isServiceRun() {
ActivityManager activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
boolean isRunnig = false;
for (int i = 0; i < services.size(); i++) {
RunningServiceInfo inf = services.get(i);
if(PROCESS_NAME.equals(inf.process)){
ComponentName cn = inf.service;
String str = cn.toString();
if(str.contains(SERVICE_NAME)){
isRunnig = true;
return isRunnig;
}
}
}
return isRunnig;
}
}
Related
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
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();
}
I'm a bit new to Android and I'm trying to move some location finding and volley methods out of my fragment into a service, but now sure where to put what. It's basically a weather app that gets your current location and uses volley to pull forecast.io api data.
Here is my fragment now:
public class WeatherListFragment extends ListFragment implements LocationListener {
private final String initialURL = "https://api.forecast.io/forecast/8fc2b0556e166fa4670d4014d318152a/";
Weather[] myWeatherArray = {};
Weather myWeatherObject;
WeatherAdapter weatherAdapter;
LocationManager mLocationManager;
String currentLoc;
JSONArray data;
JSONObject day;
#Override
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
// Remove the listener you previously added
mLocationManager.removeUpdates(this);
}
#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 onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLocationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
makeUseOfNewLocation(mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 1, this);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 1, this);
}
public void getData() {
String API_URL = setLatLong(initialURL, currentLoc);
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, API_URL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject daily = response.getJSONObject("daily");
data = daily.getJSONArray("data");
myWeatherArray = new Weather[data.length()];
for (int i = 0; i < myWeatherArray.length; i++) {
day = data.getJSONObject(i);
myWeatherObject = new Weather();
myWeatherObject.setmDate(day.getInt("time"));
myWeatherObject.setmTempMin(day.getInt("temperatureMin"));
myWeatherObject.setmTempMax(day.getInt("temperatureMax"));
myWeatherObject.setIcon(day.getString("icon"));
myWeatherArray[i] = myWeatherObject;
}
} catch (JSONException e) {
e.printStackTrace();
}
if (weatherAdapter != null) {
weatherAdapter.setData(myWeatherArray);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "volley died", Toast.LENGTH_SHORT).show();
}
}
);
requestQueue.add(jsonObjectRequest);
}
public void makeUseOfNewLocation(Location location) {
if (location == null) {
return;
}
mLocationManager.removeUpdates(this);
double latDouble = location.getLatitude();
double longDouble = location.getLongitude();
String latString = String.valueOf(latDouble);
String longString = String.valueOf(longDouble);
String latLong = latString + "," + longString;
Log.e("gps", latLong);
currentLoc = latLong;
getData();
}
public String setLatLong(String roughURL, String loc) {
return roughURL + loc;
}
and here is the blank Service class using a Handler:
public class NotificationService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
Notification n = new Notification(getApplicationContext());
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Thread.MIN_PRIORITY);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
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:
hii i am developing an app in which i m getting locations and speed. now when the user in speed , i m showing a screen in front of user on which user has 2 buttons. and doing same in a zone which we make restricted. user has to send sms to parent if he is in speed or zone.
but i m getting a problem that as user got speed my screen is not coming, phone got hanged and app is in App not responding mode. i apply threading for this also but didn't get succeed , please check my code and guide me is there is anything goes wrong.if the first screen is coming than on click of button it is going in same situation as above.
public class CheckLocation extends Service{
private static final String TAG = "CheckLocation";
private LocationManager lm;
LocationListener locationListener;
private float speed,speedinMiles,Speedvalue,lastSpeed;
private double lattitude=25.66;
private double longtitude=32.45;
private Context context;
String IMEI,result,speedStatus,wantSpeedAlert,addwithData,alertAdd,status;
String []child,parentNumber;
String serverAdd= SERVER ADDRESS FOR SAVING LOCATION DATA IN DATABASE;
String speedAlert=SERVER ADDRESS FOR SENDING MAIL
PendingIntent pendingIntent;
CursorHandler cursorHandler;
boolean zoneFlag,isState,isRestrictedZone,alreadyRunning=false;
JSONArray jArray;
JSONObject json_data=new JSONObject();
SendingSmsEmail sendingSmsEmail;
int enter=0,exit=0,speedIntent=0;
public CheckLocation(Context context)
{
this.context = context;
}
public CheckLocation()
{
Log.d(TAG,"in constructor of check location");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
Log.d(TAG, "onCreate()");
super.onCreate();
cursorHandler=new CursorHandler(this);
TelephonyManager telephonyManager=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
IMEI = telephonyManager.getDeviceId();
Log.d(TAG,"imei number of phone..got it.."+IMEI);
status=getStatus();
Log.d(TAG, "status of speed sms.."+status);
Log.d(TAG, "starting service");
startService();
}
private void startService()
{
Log.d(TAG, "startService()");
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,locationListener);
Log.d(TAG, "calling location listener");
}
private class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location loc)
{
Log.d(TAG, "onLocationChanged()");
if (loc != null)
{
lattitude=loc.getLatitude();
longtitude=loc.getLongitude();
lastSpeed = speed;
speed = loc.getSpeed();
// CHANGING SPPEED IN MILES PER SECOND
speedinMiles=(float) (speed*2.2369362920544);
Log.d(TAG, "speed in miles.."+speedinMiles);
loc.setSpeed(speedinMiles);
//BROADCASTING SPEED INTENT
Intent intent = new Intent(SOMECLASS.INTENT_SPEED_CHECK);
intent.putExtra("speed", speedinMiles);
intent.putExtra("lattitude",lattitude);
intent.putExtra("longitude", longtitude);
sendBroadcast(intent);
Log.d(TAG, "Intent Broad casted");
//SAVING LOCATION DATA IN DATABSE
saveData(lattitude,longtitude);
// CHECKING SPEED
if(speedinMiles>20)
{
new CheckSpeedTask().execute(status);// HERE STATUS IS FOR IF WE WANT TO SEND SMS OR NOT
}
else
{
Log.d(TAG, "user is not in speed ");
speedIntent=0;
}
}
}
public void onProviderDisabled(String provider)
{
Log.d(TAG, "onProviderDisabled,enableing network provider");
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0,locationListener);
Log.d(TAG, "Network provider enabled");
}
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged)");
}
}
public float getCurrentSpeed() {
return speedinMiles;
}
public double getCurrentLattitude() {
return lattitude;
}
public double getCurrentLongitude() {
return longtitude;
}
public float getLastSpeed() {
return lastSpeed;
}
private String getStatus()
{
//child=conntectionHandler.post(childstatus);
child=cursorHandler.getData("status");
for (int i = 0; i < child.length; i++)
{
Log.d(TAG,"status["+i+"]"+child[i]);
speedStatus=child[i];
System.out.println("status."+speedStatus);
}
wantSpeedAlert=speedStatus.substring(speedStatus.indexOf(",")+1,speedStatus.lastIndexOf(","));
System.out.println("speed alert is.."+wantSpeedAlert);
return wantSpeedAlert;
}
void saveData(double lattitude2, double longtitude2)
{
try{
Log.d(TAG,"Saving...latt.."+lattitude+"..long.."+longtitude);
addwithData=serverAdd+IMEI+"&latitude="+lattitude2+"&longitude="+longtitude2;
Log.d(TAG,"completeServerAdd.."+addwithData);
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet=new HttpGet(addwithData);
HttpResponse response = httpclient.execute(httpGet);
Log.d(TAG, response.toString());
Log.d(TAG,"server Connected");
Log.i(TAG,"data inserted");
}
catch(Exception e)
{
Log.e(TAG, "Error converting result "+e.getMessage());
}
}
private class CheckSpeedTask extends AsyncTask<String,Void,Void>
{
#Override
protected Void doInBackground(String... status)
{
Log.d(TAG, "CHECK SPEED TASK");
String statusForMail=status[0];
if(statusForMail.equalsIgnoreCase("y"))
{
System.out.println("speed Alert status is..."+statusForMail);
if(speedIntent==0)
{
//sending mail and sms to parent
alertAdd=speedAlert+IMEI+"&speed="+speedinMiles;
Log.d(TAG, "address for speed alert."+alertAdd);
Log.d(TAG, "prompting server ");
try
{
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet=new HttpGet(alertAdd);
HttpResponse response = httpClient.execute(httpGet);
Log.d(TAG,"mail send");
speedIntent=1;
}
catch (Exception e)
{
Toast.makeText(context,"Sever Connection Problem",Toast.LENGTH_LONG);
e.printStackTrace();
}
}
else
{
Log.d(TAG, "speed intent value is 1 so not sending mail");
}
}
else
{
Log.d(TAG, "Speed alert status is negative");
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
Log.d(TAG, "Starting Intent");
Intent screenIntent=new Intent(getApplicationContext(),SpeedScreen.class);
screenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
screenIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
getApplicationContext().startActivity(screenIntent);
Log.d(TAG, "new Activity Starts");
}
}
}
i also put a thread in on button click method.
please guide me if anything goes wrong.
thanks in advance
pls check this answer
public class CheckLocation extends Service{
private static final String TAG = "CheckLocation";
private LocationManager lm;
LocationListener locationListener;
private float speed,speedinMiles,Speedvalue,lastSpeed;
private double lattitude=25.66;
private double longtitude=32.45;
private Context context;
String IMEI,result,speedStatus,wantSpeedAlert,addwithData,alertAdd,status;
String []child,parentNumber;
String serverAdd= SERVER ADDRESS FOR SAVING LOCATION DATA IN DATABASE;
String speedAlert=SERVER ADDRESS FOR SENDING MAIL
PendingIntent pendingIntent;
CursorHandler cursorHandler;
boolean zoneFlag,isState,isRestrictedZone,alreadyRunning=false;
JSONArray jArray;
JSONObject json_data=new JSONObject();
SendingSmsEmail sendingSmsEmail;
int enter=0,exit=0,speedIntent=0;
public CheckLocation(Context context)
{
this.context = context;
}
public CheckLocation()
{
Log.d(TAG,"in constructor of check location");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
Log.d(TAG, "onCreate()");
super.onCreate();
cursorHandler=new CursorHandler(this);
TelephonyManager telephonyManager=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
IMEI = telephonyManager.getDeviceId();
Log.d(TAG,"imei number of phone..got it.."+IMEI);
status=getStatus();
Log.d(TAG, "status of speed sms.."+status);
Log.d(TAG, "starting service");
startService();
}
private void startService()
{
Log.d(TAG, "startService()");
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,locationListener);
Log.d(TAG, "calling location listener");
}
private class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location loc)
{
Log.d(TAG, "onLocationChanged()");
if (loc != null)
{
lattitude=loc.getLatitude();
longtitude=loc.getLongitude();
lastSpeed = speed;
speed = loc.getSpeed();
// CHANGING SPPEED IN MILES PER SECOND
speedinMiles=(float) (speed*2.2369362920544);
Log.d(TAG, "speed in miles.."+speedinMiles);
loc.setSpeed(speedinMiles);
//BROADCASTING SPEED INTENT
Intent intent = new Intent(SOMECLASS.INTENT_SPEED_CHECK);
intent.putExtra("speed", speedinMiles);
intent.putExtra("lattitude",lattitude);
intent.putExtra("longitude", longtitude);
sendBroadcast(intent);
Log.d(TAG, "Intent Broad casted");
//SAVING LOCATION DATA IN DATABSE
saveData(lattitude,longtitude);
// CHECKING SPEED
if(speedinMiles>20)
{
new CheckSpeedTask().execute(status);// HERE STATUS IS FOR IF WE WANT TO SEND SMS OR NOT
}
else
{
Log.d(TAG, "user is not in speed ");
speedIntent=0;
}
}
}
public void onProviderDisabled(String provider)
{
Log.d(TAG, "onProviderDisabled,enableing network provider");
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0,locationListener);
Log.d(TAG, "Network provider enabled");
}
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged)");
}
}
public float getCurrentSpeed() {
return speedinMiles;
}
public double getCurrentLattitude() {
return lattitude;
}
public double getCurrentLongitude() {
return longtitude;
}
public float getLastSpeed() {
return lastSpeed;
}
private String getStatus()
{
//child=conntectionHandler.post(childstatus);
child=cursorHandler.getData("status");
for (int i = 0; i < child.length; i++)
{
Log.d(TAG,"status["+i+"]"+child[i]);
speedStatus=child[i];
System.out.println("status."+speedStatus);
}
wantSpeedAlert=speedStatus.substring(speedStatus.indexOf(",")+1,speedStatus.lastIndexOf(","));
System.out.println("speed alert is.."+wantSpeedAlert);
return wantSpeedAlert;
}
void saveData(double lattitude2, double longtitude2)
{
try{
Log.d(TAG,"Saving...latt.."+lattitude+"..long.."+longtitude);
addwithData=serverAdd+IMEI+"&latitude="+lattitude2+"&longitude="+longtitude2;
Log.d(TAG,"completeServerAdd.."+addwithData);
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet=new HttpGet(addwithData);
HttpResponse response = httpclient.execute(httpGet);
Log.d(TAG, response.toString());
Log.d(TAG,"server Connected");
Log.i(TAG,"data inserted");
}
catch(Exception e)
{
Log.e(TAG, "Error converting result "+e.getMessage());
}
}
private class CheckSpeedTask extends AsyncTask<String,Void,Void>
{
#Override
protected Void doInBackground(String... status)
{
Log.d(TAG, "CHECK SPEED TASK");
String statusForMail=status[0];
if(statusForMail.equalsIgnoreCase("y"))
{
System.out.println("speed Alert status is..."+statusForMail);
if(speedIntent==0)
{
//sending mail and sms to parent
alertAdd=speedAlert+IMEI+"&speed="+speedinMiles;
Log.d(TAG, "address for speed alert."+alertAdd);
Log.d(TAG, "prompting server ");
try
{
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet=new HttpGet(alertAdd);
HttpResponse response = httpClient.execute(httpGet);
Log.d(TAG,"mail send");
speedIntent=1;
}
catch (Exception e)
{
Toast.makeText(context,"Sever Connection Problem",Toast.LENGTH_LONG);
e.printStackTrace();
}
}
else
{
Log.d(TAG, "speed intent value is 1 so not sending mail");
}
}
else
{
Log.d(TAG, "Speed alert status is negative");
}
Log.d(TAG, "Starting Intent");
Intent screenIntent=new Intent(getApplicationContext(),SpeedScreen.class);
screenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
screenIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
getApplicationContext().startActivity(screenIntent);
Log.d(TAG, "new Activity Starts");
return null;
}
}
}
}