Have the next problem, need a program to send the coordinates any hour to my server. Im create a taskmanager and can send the coordinates, buy only Work the first three or five times and died.
This is my code please how is my problem?
My MainActivity:
public class MainActivity extends Activity {
public int ingreso =0;
double latitud=0;
double longitud=0;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
public double lat1=0;
public double lon1=0;enter code here
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final InstallationId Miid = new InstallationId();
Alarmas mUIUpdater = new Alarmas(new Runnable() {
#Override
public void run() {
// do stuff ...
/* Use the LocationManager class to obtain GPS locations */
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
isGPSEnabled = mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = mlocManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled )
{
/*NO HAY GPS*/
Toast.makeText( getApplicationContext(),"El GPS se encuentra desactivado. Favor activarlo para determinar el Centro de embellecimiento mas cercano",Toast.LENGTH_LONG ).show();
Intent intentRedirectionGPSSettings = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intentRedirectionGPSSettings.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivityForResult(intentRedirectionGPSSettings, 0);
}
else
{
if (isGPSEnabled)
{
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
else
{
if (isNetworkEnabled)
{
mlocManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 0, 0, mlocListener);
}
}
}
lat1=((MyLocationListener) mlocListener).GetLatitud();
Log.d("Enviando datos", "es " + ((MyLocationListener) mlocListener).GetLatitud());
lon1=((MyLocationListener) mlocListener).GetLongitud();
String miurl="http://casoft.com.co/evvc/registro.php?idphone=" + Miid.id(getApplicationContext()) + "&lat1=" + lat1 + "&lon1=" + lon1;
new Tareas().execute(miurl);
mlocManager.removeUpdates(mlocListener);
}
});
mUIUpdater.startUpdates();
//new Tareas().execute("http://casoft.com.co/evvc/registro.php?idphone=1&lat1=1&lon1=2");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
latitud = loc.getLatitude();
longitud= loc.getLongitude();
Log.d("Enviando datos", latitud + "es " + longitud);
}
#Override
public void onProviderDisabled(String provider)
{
ingreso=0;
}
#Override
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(),"Gps Enabled",Toast.LENGTH_SHORT).show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
public double GetLatitud()
{
return latitud;
}
public double GetLongitud()
{
return longitud;
}
}/* End of Class MyLocationListener */
public void Sael(View view) {
Intent i = new Intent(this, navegador.class );
startActivity(i);
}
}
This is to get the idphone:
public class InstallationId {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";
public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}
private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}
private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}
And this is the Alarm:
public class Alarmas {
private Handler mHandler = new Handler(); // TODO Don't know if this is created in the UI thread
private Runnable mStatusChecker;
private int UPDATE_INTERVAL = 9000;
/**
* Creates an UIUpdater object, that can be used to
* perform UIUpdates on a specified time interval.
*
* #param uiUpdater A runnable containing the update routine.
*/
public Alarmas(final Runnable uiUpdater){
mStatusChecker = new Runnable() {
#Override
public void run() {
// Run the passed runnable
uiUpdater.run();
// Re-run it after the update interval
mHandler.postDelayed(this, UPDATE_INTERVAL);
}
};
}
/**
* The same as the default constructor, but specifying the
* intended update interval.
*
* #param uiUpdater A runnable containing the update routine.
* #param interval The interval over which the routine
* should run (milliseconds).
*/
public Alarmas(Runnable uiUpdater, int interval){
this(uiUpdater);
UPDATE_INTERVAL = interval;
}
/**
* Starts the periodical update routine (mStatusChecker
* adds the callback to the handler).
*/
public void startUpdates(){
mStatusChecker.run();
}
/**
* Stops the periodical update routine from running,
* by removing the callback.
*/
public void stopUpdates(){
mHandler.removeCallbacks(mStatusChecker);
}
}
And this is the TASK
class Tareas extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
Log.d("Enviando datos", "Solicitando");
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
Thanks for your help.
Pda: Im need this program Work all time and only send me the GPS report any hour, for testing have the UPDATE_INTERVAL any 9 seconds.
buy only Work the first three or five times and died.
That would be because Android terminated your process, in all likelihood.
Please use AlarmManager for work that should occur once an hour. Getting a location fix once per hour is a bit tricky -- I have a LocationPoller library that can help with that.
Related
So it works fine when the app is foreground and the first minute in the background. But after that the listener stops receiving gyro data. But the post thread and location listener keep working.
I tried of lot of things and I got nothing to work.
public final class Secret extends Service implements SensorEventListener, LocationListener {
private final String create = "CREATE TABLE IF NOT EXISTS data(lat float, lon float, x float, y float, z float, timestamp bigint)";
private SensorManager sensorManager;
private Database database;
private Location location;
#Override
public final void onCreate() {
/* Init sensor manager */
this.sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
#Override
public final int onStartCommand(final Intent intent, final int flags, final int startId) {
/* Initialize & load database */
this.database = new Database(openOrCreateDatabase("name_data.db", MODE_PRIVATE, null));
this.database.exec(this.create);
/* Init location manager */
final LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
try {
/* Register sensor change listener */
this.sensorManager.registerListener(this, this.sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY), SensorManager.SENSOR_STATUS_ACCURACY_HIGH);
/* Register location change listener */
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, this);
} catch (final SecurityException e) {
Toast.makeText(this, "Failed to start: " + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
/* Post data every 5 minutes */
final Thread thread = new Thread(new Runnable() {
#Override
public final void run() {
/* Secret instance */
final Secret secret = Secret.this;
/* 5 minutes */
final long time = 15000;
while (true) {
try {
/* Wait 5 minutes */
Thread.sleep(time);
/*
* Unregister sensor change listener,
* this way posting wont cause any database errors,
* and the sensor events wont time out when app is running in the background
*/
sensorManager.unregisterListener(secret);
/* Post database */
final int returned = post();
/* Register sensor change listener */
sensorManager.registerListener(secret, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_STATUS_ACCURACY_HIGH);
switch (returned) {
case -1:
System.err.println("Database too small to post");
break;
case HttpURLConnection.HTTP_OK:
System.out.println("Posted database");
break;
default:
System.err.println("Post failed: " + returned);
}
} catch (final InterruptedException e) {
System.err.println("Failed to sleep");
e.printStackTrace();
}
}
}
});
/* Set thread priority and start */
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
return START_STICKY;
}
#Nullable
#Override
public final IBinder onBind(final Intent intent) {
return null;
}
#Override
public final void onSensorChanged(final SensorEvent event) {
System.out.println(System.currentTimeMillis());
/* Store data if location is known */
if (event == null || this.location == null) return;
float[] gyro = event.values;
/* Insert data into database */
this.database.exec("INSERT INTO data(lat, lon, x, y, z, timestamp) VALUES(" + this.location.getLatitude() + "," + this.location.getLongitude() + "," + gyro[0] + "," + gyro[1] + "," + gyro[2] + "," + System.currentTimeMillis() + ")");
}
#Override
public final void onAccuracyChanged(final Sensor sensor, final int accuracy) {
}
#Override
public final void onLocationChanged(final Location location) {
this.location = location;
}
#Override
public final void onStatusChanged(final String provider, final int status, final Bundle extras) {
}
#Override
public final void onProviderEnabled(final String provider) {
}
#Override
public final void onProviderDisabled(final String provider) {
}
/**
* Post database to server
*/
private final int post() {
/* Check if database is large enough (8 MB) to be pushed */
if (this.database.getFile().length() <= 8192) return -1;
/* Push database to server */
final int returned = Connection.post(this.database.getFile());
/* Check if database was pushed successfully */
if (returned == HttpURLConnection.HTTP_OK) {
/* Clear database if it was pushed to server successfully */
this.database.close();
this.database.getFile().delete();
/* Create new database */
this.database = new Database(openOrCreateDatabase("name_data.db", MODE_PRIVATE, null));
this.database.exec(this.create);
}
return returned;
}
}
OnDestroy gets triggered and then the sensor stops giving data. the Thread and location keep running.
I have a Handler in my fragment that every 5 second add my location in SQLite.
What I need is to maintain this action in background when I open another fragment. How can I do this ?
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
Point p = ls.getPoint();
String X = Double.toString(p.getX());
String Y = Double.toString(p.getY());
db = new MySQLiteHelper(getActivity());
db.addLocation(new LocationXY(1,X,Y,"111"));
clearmap();
createPolyline();
timerHandler.postDelayed(this, 5000);
}
};
Well, what do both your fragments have in common? Their Activity! So run your handler in it.
As #Piyush pointed out, you should use an AsyncTask or a Service for background processes.
Yeah, as #Piyush and #Ricardo suggest - use a service with a Timer and a LocationListener.
Then invoke timer.scheduleAtFixedRate(yourSqliteUpdateMethod, 0, 5000); to update the database. See my service class below, which contains a lot of extra stuff, but you should be able to get what you want out of it...
public class TrackService extends Service {
/**
* Edit these values to adjust the LOCATION UPDATE polling interval
*/
private static final int LOCATION_INTERVAL_SECONDS = 5;
private static final float LOCATION_DISTANCE_METERS = 10f;
// Static timer variables
private static final long ONE_SECOND_IN_MILLIESECONDS = 1000;
// Create timer and set time as zero
private static Timer timer;
private long timeAsLong = 0;
/**
* Track and submission specific variables
*/
private List<LocationTrack> trackArrayList = new ArrayList<>();
private SubmissionSession submissionSession;
private long submissionID;
private boolean originAdded;
/**
* LocationManager and listener variables
*/
private LocationManager mLocationManager = null;
private LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER)
};
/*private LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.PASSIVE_PROVIDER)
};*/
#Override
public void onCreate() {
//Log.d("onCreate");
timer = new Timer();
initializeLocationManager();
try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, (LOCATION_INTERVAL_SECONDS * 1000), LOCATION_DISTANCE_METERS,
mLocationListeners[0]);
}
} catch (java.lang.SecurityException ex) {
Log.e("fail to request gps location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.e("gps provider does not exist, " + ex.getMessage());
}
/*try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationManager.requestLocationUpdates(
LocationManager.PASSIVE_PROVIDER, (LOCATION_INTERVAL_SECONDS * 1000), LOCATION_DISTANCE_METERS,
mLocationListeners[1]);
}
} catch (java.lang.SecurityException ex) {
Log.e("fail to request passive location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.e("passive provider does not exist " + ex.getMessage());
}*/
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
submissionID = prefs.getLong("SUBMISSION_ID", 0);
submissionSession = new SubmissionSession(submissionID);
trackArrayList = new Select().from(LocationTrack.class).where(Condition.column(LocationTrack$Table.SUBMISSIONID).eq(submissionID)).queryList();
originAdded = false;
timeAsLong = prefs.getLong("ELAPSED_TIME_AS_LONG", 0);
} else {
submissionID = intent.getLongExtra("SUB_ID", 0);
submissionSession = new SubmissionSession(submissionID);
// Stick in a reasonably sensible location to indicate to rest of app that a track's
// being captured - this is deleted on 1st real data point from GPS captured
trackArrayList.add(setLocationToLocationTrack(submissionSession.getLocation().getLocation()));
originAdded = true;
timeAsLong = intent.getLongExtra("START_TIME", 0);
}
// Start schedule at one second intervals, calling MainTask
timer.scheduleAtFixedRate(new TrackService.updateTimerAndBroadcastTask(), 0, ONE_SECOND_IN_MILLIESECONDS);
showNotification();
//super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
/**
* This method is necessary to increase the priority of the background services. It appeared that
* some devices, when running eBird Tracks and then used camera, the Tracks service was killed
* by Android due to limited resources. Upping the priority should reduce this.
*/
private void showNotification() {
final int NOTIFICATION_FLAG = 101;
final int ICON_SCALE_DIMENSION = 128;
Intent mainIntent = getPackageManager()
.getLaunchIntentForPackage(getPackageName())
.setPackage(null)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.lab_logo_square);
PendingIntent pendingMainIntent = PendingIntent.getActivity(this, 0,
mainIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_kiwi_bird1600)
.setLargeIcon(Bitmap.createScaledBitmap(icon, ICON_SCALE_DIMENSION, ICON_SCALE_DIMENSION, false))
.setContentText(getString(R.string.location_and_timer_services_running))
.setContentTitle(getString(R.string.app_name))
.setContentIntent(pendingMainIntent)
.setOngoing(true)
.build();
startForeground(NOTIFICATION_FLAG, notification);
}
#Override
public void onDestroy() {
// Need to call cancel AND purge when the user stops the list
timer.cancel();
timer.purge();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.e("fail to remove location listeners, ignore", ex);
}
}
}
submissionSession.setTracks(trackArrayList);
super.onDestroy();
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
mLastLocation.set(location);
// Code to add existing location object of site to tracks database on initiation
// to at least give one sensible point. Necessary for assigning the submission as
// an active recording - if no GPS picked up it was being overlooked in the methods
// used to display Checklist in progress throughout app. On first real capture of
// track data, it's deleted
if (originAdded) {
LocationTrack t = trackArrayList.get(0);
t.delete();
trackArrayList.remove(0);
originAdded = false;
}
trackArrayList.add(setLocationToLocationTrack(location));
sendDistanceToSubmissionActivity(Utils.routeDistance((ArrayList) trackArrayList));
}
#Override
public void onProviderDisabled(String provider) {
//Log.d("onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
//Log.d("onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
//Log.d("onStatusChanged: " + provider);
}
}
// Send an Intent with an action named "tracks_update".
protected void sendDistanceToSubmissionActivity(double distance) {
Intent intent = new Intent("tracks_update");
intent.putExtra("distance", distance);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
/**
* Method to create Locationtrack object and save it to SQLite
*
* #param loc
* #return
*/
protected LocationTrack setLocationToLocationTrack(Location loc) {
LocationTrack l = new LocationTrack();
l.setSubmissionID(submissionID);
l.setLat(loc.getLatitude());
l.setLon(loc.getLongitude());
l.setAccuracy(loc.getAccuracy());
l.setTime(System.currentTimeMillis());
l.setValid(-1); // -1 signifies that the track is active (0 = invalid after editing, 1 = valid)
//Log.d(l.getLat() + " " + l.getLon() + " saved()");
l.save();
return l;
}
/**
* Inner main task, adds a second onto timeAsLong, then sends to SubmissionActivity
*/
private class updateTimerAndBroadcastTask extends TimerTask {
public void run() {
timeAsLong += ONE_SECOND_IN_MILLIESECONDS;
sendDistanceToSubmissionActivity(timeAsLong);
}
// Send an Intent with an action named "timer_update".
protected void sendDistanceToSubmissionActivity(long time) {
//Log.d();
Intent intent = new Intent("timer_update");
intent.putExtra("long_time", time);
LocalBroadcastManager.getInstance(TrackService.this).sendBroadcast(intent);
}
}
}
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();
}
}
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;
}
}
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;
}
}
}
}