package org.gfd.gsmlocation; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.gfd.gsmlocation.model.CellInfo; import org.microg.nlp.api.LocationBackendService; import org.microg.nlp.api.LocationHelper; import android.app.Service; import android.content.Context; import android.content.Intent; import android.location.Location; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.util.Log; public class GSMService extends LocationBackendService { protected String TAG = "o.gfd.gsmlp.LocationBackendService"; protected Lock lock = new ReentrantLock(); protected Thread worker = null; protected CellbasedLocationProvider lp = null; public void start() { if (worker != null && worker.isAlive()) return; Log.d(TAG, "Starting location backend"); Handler handler = new Handler(Looper.getMainLooper()); final Context ctx = getApplicationContext(); handler.post(new Runnable() { public void run() { CellbasedLocationProvider.getInstance().init(ctx); } }); try { lock.lock(); if (worker != null && worker.isAlive()) worker.interrupt(); worker = new Thread() { public void run() { Log.d(TAG, "Starting reporter thread"); lp = CellbasedLocationProvider.getInstance(); double lastLng = 0d; double lastLat = 0d; try { while (true) { Thread.sleep(1000); try { CellInfo[] infos = lp.getAll(); if (infos.length == 0) continue; double lng = 0d; double lat = 0d; for(CellInfo c : infos) { lng += c.lng; lat += c.lat; } lng /= infos.length; lat /= infos.length; float acc = (float)(800d / infos.length); if (lng != lastLng || lat != lastLat) { Log.d(TAG, "report (" + lat + "," + lng + ") / " + acc); lastLng = lng; lastLat = lat; report(LocationHelper.create("gsm", lat, lng, acc)); } } catch (Exception e) { Log.e(TAG, "Update loop failed", e); } } } catch (InterruptedException e) {} } }; worker.start(); } catch (Exception e) { Log.e(TAG, "Start failed", e); } finally { try { lock.unlock(); } catch (Exception e) {} } } @Override protected Location update() { start(); if (lp == null) return null; CellInfo[] infos = lp.getAll(); if (infos.length == 0) return null; double lng = 0d; double lat = 0d; for(CellInfo c : infos) { lng += c.lng; lat += c.lat; } lng /= infos.length; lat /= infos.length; float acc = (float)(800d / infos.length); Log.d(TAG, "update (" + lat + "," + lng + ")"); return LocationHelper.create("gsm", lat, lng, acc); } @Override protected void onOpen() { super.onOpen(); start(); Log.d(TAG, "Binder OPEN called"); } protected void onClose() { Log.d(TAG, "Binder CLOSE called"); super.onClose(); try { lock.lock(); if (worker != null && worker.isAlive()) worker.interrupt(); if (worker != null) worker = null; } finally { try { lock.unlock(); } catch (Exception e) {} } } }