android - Google Glass - WifiCompass intergration. PAINT LOOP ONLY TRIGGERED ONCE -
my problem hard explain going try. making project inhouse navigation software (wificompass - https://code.google.com/p/wificompass/ ) , google glass. using orientation of google glass , wificompass software running on phone) info sent true wifi glass(server) phone (client). part working , tested already. problem when integrate client code wificompass framework. post situation before , after edited source code. problem blocking ui thread if utilize glassorientationsocket, can still press buttons on ui screen , code behind these buttons still runs, painting of objects (compass , user) gets blocked , have no thought how can happen. know how behavior can explained ?
extra info: after hours of debugging found paint loop multiple drawables doesnt loop. in original source code loop works fine , keeps drawing (constantly calling draw on drawables), in code loop works 1 time (then dispatchdraw called on drawables), , when pause activity loop triggered once. thing changed in originial code serversocket (that runs on thread). have idea?, advice welcome.
before
public class compasssensorwatcher implements sensoreventlistener { protected sensormanager sensormanager; protected sensor compass; protected sensor accelerometer; protected context context; float[] inr = new float[16]; float[] = new float[16]; float[] gravity = new float[3]; float[] geomag = new float[3]; float[] orientvals = new float[3]; float azimuth = 0; float angle = 0; int minx = 0, miny = 0, maxx = 0, maxy = 0, centerx = 0, centery = 0, width = 0, height = 0; float l = 0.3f; protected compasslistener listener; protected float lastazimuth = 0f; public compasssensorwatcher(context context,compasslistener cl,float lowpassfilter) { this.context = context; this.listener=cl; this.l=lowpassfilter; sensormanager = (sensormanager) context.getsystemservice(context.sensor_service); compass = sensormanager.getdefaultsensor(sensor.type_magnetic_field); accelerometer = sensormanager.getdefaultsensor(sensor.type_accelerometer); seek { sensormanager.registerlistener(this, compass, sensormanager.sensor_delay_ui); sensormanager.registerlistener(this, accelerometer, sensormanager.sensor_delay_ui); } grab (exception e) { logger.e("could not register listener", e); } } /* * (non-javadoc) * * @see android.hardware.sensoreventlistener#onaccuracychanged(android.hardware.sensor, int) */ @override public void onaccuracychanged(sensor sensor, int accuracy) { } /* * (non-javadoc) * * @see android.hardware.sensoreventlistener#onsensorchanged(android.hardware.sensorevent) */ @override public void onsensorchanged(sensorevent event) { // logger.d("sensor changed "+event); // utilize type_magnetic_field changes in direction, utilize sensormanager directions if (event.accuracy == sensormanager.sensor_status_unreliable) return; // gets value of sensor has been changed switch (event.sensor.gettype()) { case sensor.type_accelerometer: gravity = event.values.clone(); break; case sensor.type_magnetic_field: geomag = event.values.clone(); break; } // if gravity , geomag have values find rotation matrix if (gravity != null && geomag != null) { // checks rotation matrix found boolean success = sensormanager.getrotationmatrix(inr, i, gravity, geomag); sensormanager.getorientation(inr, orientvals); angle = (float) toolbox.normalizeangle(orientvals[0]); azimuth = (float) math.todegrees(angle); lowpassfilter(); angle=(float) math.toradians(azimuth); if(listener!=null){ listener.oncompasschanged(azimuth,angle,getazimuthletter(azimuth)); } } } public void stop(){ seek { sensormanager.unregisterlistener(this); } grab (exception e) { logger.w("could not unregister listener", e); } } public string getazimuthletter(float azimuth) { string letter = ""; int = (int) azimuth; if (a < 23 || >= 315) { letter = "n"; } else if (a < 45 + 23) { letter = "no"; } else if (a < 90 + 23) { letter = "o"; } else if (a < 135 + 23) { letter = "so"; } else if (a < (180 + 23)) { letter = "s"; } else if (a < (225 + 23)) { letter = "sw"; } else if (a < (270 + 23)) { letter = "w"; } else { letter = "nw"; } homecoming letter; } protected void lowpassfilter() { // lowpass filter float dazimuth = azimuth -lastazimuth; if (dazimuth > 180) { // alter range -180 0 dazimuth = (float) (dazimuth - 360f); } else if (dazimuth < -180) { // alter range 0 180 dazimuth = (float) (360f + dazimuth); } // lowpass filter azimuth = lastazimuth+ dazimuth*l; azimuth%=360; if(azimuth<0){ azimuth+=360; } lastazimuth=azimuth; }}
//
public class compassmonitor { static protected arraylist<compasslistener> listeners=new arraylist<compasslistener>(); static protected compasssensorwatcher monitor=null; static public synchronized void registerlistener(context context,compasslistener listener){ if(listeners.size()==0){ monitor=new compasssensorwatcher(context,new compasslistener(){ @override public void oncompasschanged(float azimuth, float angle,string direction) { notifylisteners(azimuth,angle,direction); } },0.5f); } listeners.add(listener); } static synchronized public void unregisterlistener(compasslistener listener){ if (listeners != null && listener != null) listeners.remove(listener); if (listeners != null && listeners.size() == 0 && monitor != null) { seek { monitor.stop(); } grab (exception e) { logger.w("could not stop compass monitor", e); } monitor = null; } } static synchronized protected void notifylisteners(float azimuth,float angle, string direction){ for(compasslistener l:listeners){ try{ l.oncompasschanged(azimuth,angle,direction); }catch(exception ex){} } }}
after
public class glassorientationsocket implements runnable { public final static int port = 6604; socket mclientsocket; context context; string mresult; compasslistener listener; public glassorientationsocket(context context,compasslistener listener) { this.context = context; this.listener = listener; } @suppresswarnings("deprecation") @override public void run() { //replace ip-address of android server (aka google glass) string serverip = "192.168.1.104"; //port should same serversocketactivity seek { mclientsocket = new socket(serverip, port); bufferedreader input = new bufferedreader(new inputstreamreader(mclientsocket.getinputstream())); wifimanager wim = (wifimanager) context.getsystemservice(context.wifi_service); list<wificonfiguration> l = wim.getconfigurednetworks(); wificonfiguration wc = l.get(0); while(true) { mresult = input.readline(); int anglecutter = mresult.indexof("|",0); int azimuthlettercutter = mresult.indexof("|",anglecutter + 1); //check if stream contatins info if(mresult.substring(0,anglecutter) != "bad data") { float azimuth = float.valueof(mresult.substring(0, anglecutter)); float angle = float.valueof(mresult.substring(anglecutter + 1, azimuthlettercutter)); string azimuthletter = mresult.substring(azimuthlettercutter, mresult.length()); listener.oncompasschanged(azimuth, angle, azimuthletter); } else { toast.maketext(context, "bad sensor data", toast.length_short).show(); } } } grab (unknownhostexception e) { e.printstacktrace(); } grab (ioexception e) { e.printstacktrace(); } }}
//
public class compassmonitor { static protected arraylist<compasslistener> listeners=new arraylist<compasslistener>(); static protected glassorientationsocket monitor=null; static public synchronized void registerlistener(context context,compasslistener listener){ if(listeners.size()==0){ monitor=new glassorientationsocket(context,new compasslistener(){ @override public void oncompasschanged(float azimuth, float angle,string direction) { notifylisteners(azimuth,angle,direction); } }); thread thread = new thread(monitor); thread.isdaemon(); thread.start(); } listeners.add(listener); } static synchronized public void unregisterlistener(compasslistener listener){ if (listeners != null && listener != null) listeners.remove(listener); } static synchronized protected void notifylisteners(float azimuth,float angle, string direction){ for(compasslistener l:listeners){ try{ l.oncompasschanged(azimuth,angle,direction); }catch(exception ex){} } }
}
generic interface (same in both versions)
public interface compasslistener { /** * method called, if azimuth of compass changes. values lowpass filtered, smother results. * @param azimuth current direction of device towards north in degrees * @param angle current direction of device towards north in radiant * @param direction string describing the compass direction, i.e. n, so, nw */ public void oncompasschanged(float azimuth,float angle,string direction);
i fixed issue not passing listener thread. used message handler handle message, , phone call notify listeners in compassmonitor class, works charm now.
android multithreading orientation google-glass
No comments:
Post a Comment