Friday, September 2, 2011

Acquiring GPS location fix



GPS has opened a Pandora's box for mobile developer. There has been a huge influx of such application ranging from tracking apps to location based social networking apps.

Many of today's applications require us to get a GPS fix on the location of the device when the application is being used.

Therefore without further ado lets get into some coding.
The following snippet of codes employ a service and a broadcast receiver to get onto a location fix. It gets the most recent fix on the location and then closes the GPS updates as soon as it gets a fix.

public class FindGPSActivity extends Activity{

Intent myGpsService;
MainGpsReciever gpsReciever;
final String GPS_FILTER = "MyGPSLocation";  

protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.textlayout);
                initGpsListeners()
}



- initGpsListeners method initializes the necessary services and the recievers. 

private void initGpsListeners() {
           
            myGpsService = new Intent(this, GpsService.class);
            startService(myGpsService);
            String GPS_FILTER = getResources().getString(GPS_FILTER);
            IntentFilter mainFilter = new IntentFilter(GPS_FILTER);
            gpsReciever = new MainGpsReciever();
            registerReceiver(gpsReciever, mainFilter);
           
      }

- this is where i get my location data which i can further use in my activity.
This receiver is called from within the service which is actually looking for a GPS location. A GPS location fix is an unreliable bit of information and we cannot be sure when we might get it. it can range anywhere from 5 seconds to 5 minutes or if you are inside a huge structure like a building you might never get it unless you come out. Therefore we use a service because we do not want our location finder to be garbage collected by android.


private class MainGpsReciever extends BroadcastReceiver {

             public void onReceive(Context arg0, Intent calledIntent) {
                       
                   Constants.GPSLatitude = calledIntent.getDoubleExtra("latitude", -1);
                   Constants.GPSLongitude = calledIntent.getDoubleExtra("longitude", -1);
                   Constants.GPSSpeed = calledIntent.getFloatExtra("speed", -1);
                       
                   Log.i("GPS Demo", "Lat & Long --- "+Constants.GPSLatitude+"--"+Constants.GPSLongitude);
                   Log.i("GPS Demo", Speed --- "+Constants.GPSSpeed);
//               
                                         
             }
       }
}

This is the service class in its entirety. 

public class GpsService extends Service {

      String GPS_FILTER = "";
      Thread triggerService;
      LocationManager lm;
      GpsListener gpsLocationListener;
      boolean isRunning = true;
     
      @Override
      public void onCreate() {
           
            // TODO Auto-generated method stub
            super.onCreate();
            GPS_FILTER = “MyGPSLocation”;
           
      }
     
      @Override
      public void onStart(Intent intent, int startId) {
            // TODO Auto-generated method stub
            super.onStart(intent, startId);          
            triggerService = new Thread(new Runnable(){
                  public void run(){
                        try{
                              Looper.prepare();//Initialize the current thread as a looper.
                              lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
                              gpsLocationListener = new GpsListener();
                              long minTime = 30000; // 5 sec...
                              float minDistance = 10;
                              lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime,
                                          minDistance, gpsLocationListener);
                              Looper.loop();
                        }catch(Exception ex){
                              System.out.println("Exception in triggerService Thread -- "+ex);
                        }
                  }
            }, "myLocationThread");
            triggerService.start();
      }
     
      @Override
      public void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            removeGpsListener();
      }
     
      @Override
      public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
      }
     
      private void removeGpsListener(){
            try{
                  lm.removeUpdates(gpsLocationListener);
            }
            catch(Exception ex){
                  System.out.println("Exception in GPSService --- "+ex);
            }
      }
     
      class GpsListener implements LocationListener{

            public void onLocationChanged(Location location) {
                  // TODO Auto-generated method stub
                  double latitude = location.getLatitude();
                  double longitude = location.getLongitude();
                  float speed = location.getSpeed();
                  Intent filterRes = new Intent(GPS_FILTER);
                  filterRes.putExtra("latitude", latitude);
                  filterRes.putExtra("longitude", longitude);
                  filterRes.putExtra("speed", speed);
                  sendBroadcast(filterRes);
            }

            public void onProviderDisabled(String provider) {
                  // TODO Auto-generated method stub
                 
            }

            public void onProviderEnabled(String provider) {
                  // TODO Auto-generated method stub
                 
            }

            public void onStatusChanged(String provider, int status, Bundle extras) {
                  // TODO Auto-generated method stub
                 
            }

      }

}

Sunday, July 31, 2011

Facebook implementation into android

There has been a lot of tutorials about social sites and its implementations into Android. Most of these tutorials are very well written and fairly simple. Facebook in particular came up with a brilliantly yet easy to implement sdk and the documentation that comes with it is also good.

About six months ago, i was working on an application that needed me to implement FB, and while doing so i came up with a strange problem. My facebook login dialog disappeared soon after loading. After banging my head for some time and goggling i came across something called an SSO in facebook. 



This mainly happens because there are more than one facebook implementation in your phone. i mean you might have the usual FB application in which you have already signed in, and one you are presently working on.

According to FB "one of the most compelling features of the Android SDK is Single-Sign-On (SSO). SSO lets users sign into your app using their Facebook identity. If they are already signed into the Facebook Android app on their device they do not have to even type a username and password. Further, because they are signing to your app with their Facebook identity, you will have access to their profile information and social graph."


Since you have already signed in the FB application, when you try to implement FB in your application the SSO feature would sign you in straightaway and therefore the login dialog box disappear almost immediately after it first appears. There are however ways in which you can FB that this is a different application and you need me to ask to sign in again.


1.  by forcing the login dialog rather than SSO by passing FORCE_DIALOG_AUTH in the authorize methods in Facebook.java.


2. This method is quite complicated and involves a lot of steps. there is a brilliant blog dealing with this method therefore i might as well save myself some time and provide a link to this bolg. http://sean.lyn.ch/2011/07/android-the-facebook-sdk-sso-and-you/

3. The third way is very simple and effective. It tackles the problem stated in step 2, but in a very easy way. Just replace the package name "com.facebook.katana" to your own application package name in the file Facebook.java. Also replace the class name "com.facebook.katana.ProxyAuth" to "your-package-name.ProxyAuth" and see for yourself if you are good to go.