package kr.ac.kaist.resl.sensorservice; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.Iterator; import java.util.Map; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; import android.annotation.SuppressLint; import android.app.Service; import android.content.Intent; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.provider.Settings; @SuppressLint("DefaultLocale") public class LocationService extends Service implements LocationListener{ public static String message=""; private FileThread fileThread; private RemoteThread remoteThread; private LocationManager locationManager =null; // flag for GPS status boolean isGPSEnabled = false; // flag for network status //boolean isNetworkEnabled = false; // The minimum distance to change Updates in meters private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 1 meters // The minimum time between updates in milliseconds private static final long MIN_TIME_BW_UPDATES = 0; // 10 milliseconds public LocationService() { } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { } @Override public void onStart(Intent intent, int startId) { // Perform your long running operations here. if( locationManager == null ) locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE); // getting GPS status isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); // getting network status //isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); Location lastLoc = null; try { if( isGPSEnabled ) { locationManager.removeUpdates(LocationService.this); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); lastLoc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if( lastLoc != null ) { String androidId = android.provider.Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID); JSONObject jObj = new JSONObject(); jObj.put("longitude", lastLoc.getLongitude()); jObj.put("latitude", lastLoc.getLatitude()); jObj.put("numSatellites", 0); jObj.put("android_id", androidId); message = jObj.toString(); } } // else if( isGPSEnabled == false && isNetworkEnabled == true ) // { // locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this); // lastLoc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); // if( lastLoc != null ) // { // String androidId = android.provider.Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID); // JSONObject jObj = new JSONObject(); // jObj.put("longitude", lastLoc.getLongitude()); // jObj.put("latitude", lastLoc.getLatitude()); // jObj.put("numSatellites", 0); // jObj.put("android_id", androidId); // message = jObj.toString(); // } // } } catch(JSONException e) { e.printStackTrace(); } if( lastLoc != null ) { if( fileThread == null ) { fileThread = new FileThread(); fileThread.start(); } if( remoteThread == null ) { remoteThread = new RemoteThread(); remoteThread.start(); } } } @Override public void onDestroy() { locationManager.removeUpdates(this); if( fileThread != null ) fileThread.cont = false; if( remoteThread != null ) remoteThread.cont = false; } @Override public void onLocationChanged(Location arg0) { try { String androidId = android.provider.Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID); JSONObject jObj = new JSONObject(); jObj.put("longitude", arg0.getLongitude()); jObj.put("latitude", arg0.getLatitude()); jObj.put("speed",arg0.getSpeed()); jObj.put("numSatellites", arg0.getExtras().getInt("satellites")); jObj.put("android_id", androidId); message = jObj.toString(); if( fileThread == null ) { fileThread = new FileThread(); fileThread.start(); } if( remoteThread == null ) { remoteThread = new RemoteThread(); remoteThread.start(); } } catch (JSONException e) { e.printStackTrace(); } } @Override public void onProviderDisabled(String provider) {} @Override public void onProviderEnabled(String provider) {} @Override public void onStatusChanged(String arg0, int arg1, Bundle arg2) { // getting GPS status isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); // getting network status //isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if( isGPSEnabled ) { locationManager.removeUpdates(LocationService.this); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); } // else if( isGPSEnabled == false && isNetworkEnabled == true ) // { // locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this); // } } public class RemoteThread extends Thread { public boolean cont; public RemoteThread() { cont = true; } public void run() { String prev = ""; try { int cnt = 0; while(cont) { if( message != null && !message.equals(prev)) { new HttpAsyncTask().execute(message); prev = message; } cnt++; if( cnt%12 == 11 ) { JSONObject jObj = new JSONObject(message); jObj.put("numSatellites", 0); message = jObj.toString(); } Thread.sleep(MainActivity.period*1000); } } catch (InterruptedException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } } public class FileThread extends Thread { public boolean cont; public FileThread() { cont = true; } public void run() { try { while(cont) { if( isExternalStorageWritable() ) { writeToSDFile("Location", message); } Thread.sleep(10000); } } catch (InterruptedException e) { e.printStackTrace(); } } } public String getJSON(Map<String, Object> sensorValues) throws JSONException { Iterator<String> iter = sensorValues.keySet().iterator(); JSONObject ret = new JSONObject(); while( iter.hasNext() ) { String key = (String)iter.next(); Object value = sensorValues.get(key); if( value instanceof Float ) { ret.put(key, (Float)value); } else if( value instanceof String ) { ret.put(key, (String)value); } } return ret.toString(); } private class HttpAsyncTask extends AsyncTask<String, Integer, Double>{ @Override protected Double doInBackground(String... params) { try { postData(params[0]); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } } public void postData(String message) throws ClientProtocolException, IOException { HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(MainActivity.URL); StringEntity params = new StringEntity(message); post.setEntity(params); client.execute(post); } public boolean isExternalStorageWritable(){ String state = Environment.getExternalStorageState(); if( Environment.MEDIA_MOUNTED.equals( state)){ return true; } return false; } private void writeToSDFile(String fileName, String message){ // Find the root of the external storage. // See http://developer.android.com/guide/topics/data/data- storage.html#filesExternal File root = android.os.Environment.getExternalStorageDirectory(); // See http://stackoverflow.com/questions/3551821/android-write-to-sd-card-folder File dir = new File (root.getAbsolutePath() + "/SensorService"); dir.mkdirs(); File file = new File(dir, fileName+".json"); try { FileOutputStream f = new FileOutputStream(file); PrintWriter pw = new PrintWriter(f); pw.print(message); pw.flush(); pw.close(); f.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }