Test Script

Saturday, October 6, 2012

Proximity Alerts

Ok here is a simple Tutorial on how to implement the Proximity Alerts in Android.This tutorial is a just a guide on how to use the Proximity Alerts feature in Android & in no way is a complete application by itself.

Here i am going to be using two classes to implement this:
1. MainActivity.java
2. ProximityReciever.java

The MainActvity is the class used to set the Proximity alerts. Here is my Implementation for MainActivity.java:
========================================================================


    public void import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.view.Menu;

public class MainActivity extends Activity {
LocationManager lm;
double lat=123,long1=34;    //Defining Latitude & Longitude
float radius=3000;                         //Defining Radius
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lm=(LocationManager) getSystemService(LOCATION_SERVICE);
        Intent i= new Intent("com.adnan.proximityalert");           //Custom Action
        PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), -1, i, 0);
        lm.addProximityAlert(lat, long1, radius, -1, pi);
    }


}
========================================================================

Nothing special or any Rocket Science above , here is a small explantion of what i did:

1.Defined the latitude & longitude co-ordinates of the location for which we want to setup the alert.

2.Radius is range for which the alert should work.(This is in meters, so in my example 3km radius)

3.Create a new Intent with a custom action(in my example its "com.adnan.proximityalert")

4.Finally called the addProximityAlert method which takes in the latitude,longitude,radius,expiration time,Pending Intent)

Expiration time is in milliseconds & by setting it to -1 like i did tells the system that the alert never expires.


Now we need a Reciever to listen to the broadcast & do the further things

ProximityReciever.java

========================================================================
android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.widget.Toast;

/*This is the Reciever for the Brodcast sent, here our app will be notified if the User is 
* in the region specified by our proximity alert.You will have to register the reciever 
* with the same Intent you broadcasted in the previous Java file
 * @Author: Adnan A M 
 */


public class ProximityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
// The reciever gets the Context & the Intent that fired the broadcast as arg0 & agr1 
String k=LocationManager.KEY_PROXIMITY_ENTERING;
// Key for determining whether user is leaving or entering 
boolean state=arg1.getBooleanExtra(k, false);
//Gives whether the user is entering or leaving in boolean form
if(state){
// Call the Notification Service or anything else that you would like to do here
Toast.makeText(arg0, "Welcome to my Area", 600).show();
}else{
//Other custom Notification 
Toast.makeText(arg0, "Thank you for visiting my Area,come back again !!", 600).show();

}
}
}

========================================================================


What i did above:

1.Created a Reciever which listens for the broadcast
2.Proximity Alerts use both GPS & Network Provider.
3.Alerts are fired when the user is entering the defined area or leaving the area, so it becomes necessary to determine whether the user is entering the zone or leaving , it is done using KEY_PROXIMITY_ENTERING, this gives a key which is used to retrieve the info whether the user is entering or leaving
4. As shown i used a boolean variable state to store whether the user is entering or Leaving & if no value is recieved i set the default to false
5.Based on the value of state i have two different Toasts.


You need to add the following permissions in manifest as well :


<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>


Thats it ! You are all set to recieve a alert when you go in a 3kn range of the desired co ordinates !

I will consider writing a second version of this Tutorial extending the concept further & showing its exact in depth usage if needed.


Ok so people have been commenting & sending me queries on how to remove the Proximity alert , so here is how :


========================================================================


private void removeProximityAlert() {

String context = Context.LOCATION_SERVICE;
LocationManager locationManager = (LocationManager) getSystemService(context);

Intent anIntent = new Intent("com.adnan.proximityalert"); 
PendingIntent operation = 
PendingIntent.getBroadcast(getApplicationContext(), unique_id , anIntent, 0);
locationManager.removeProximityAlert(operation);
}


========================================================================

Hope this clears up things better !

Second thing which is most confusing is , what is this "com.adnan.proximityalert"?

Well , that is just something you need to declare , so that line in your code should look like this

"com.yourpackagename.proximityalert".


Please do comment your views about the tutorial & if you have any queries please feel free to drop a comment below !











14 comments:

  1. hi help me out ..
    i am on a project that uses multiple proximity alerts ..
    in a simple way i have n number of POI(point of interest) when i reach particular POI i should send a sms to predifined no that will be stored in DATABASE….
    How to implement this one give me an idea….im really exhausted by trying this one …

    ReplyDelete
    Replies
    1. Ok here is what i would do :

      1.On first startup of app create a SQLite DB with all the phone no

      2.Implement the Proximity alerts for all POI

      3.Once there is a POI reached, you generate a alarm or broadcast a particular message or name of the POI , based on that search the db and fetch the ph no and send the sms

      Hope this helps

      Delete
    2. hi
      thanks a lot it is very useful..
      but if i want to implement this code what can replace
      "com.adnan.proximityalert" with ??
      does it mean i should create activity let say name=proximityalert that is connected to ProximityReciever class or what ??

      Delete
    3. You just have to replace it with the package name you have given to your project & finally add proximityalert

      Like : com.yourpackagename.proximityalert

      Delete
  2. Hello sir, thanks for the simple but very effective tutorial. I've been wanting a tutorial like this for a long time now!
    I'm trying to implement the same proximity alert and intend to set an alarm when the user enters the location. Say I've created an activity that plays sound. Now should i provide the intent to that activity in ProximityReciever.java (in the if..else statement, where you've toasted the message) or in MainActivity.java. I don't understand what
    Intent i= new Intent("com.adnan.proximityalert");
    does in MainActivity.java??Please help sir!!

    ReplyDelete
  3. Yes you will have to provide the Intent to your activity in the if,else condition in ProximityReciever file !

    ReplyDelete
  4. Great tutorial! it's simply explain everything that i'm looking for.
    But my question is how to remove it?? I think the alert is still active even when i'm already uninstall the app. Thx

    ReplyDelete
    Replies
    1. To remove the Proximity alert you would do something like this:

      private void removeProximityAlert() {

      String context = Context.LOCATION_SERVICE;
      LocationManager locationManager = (LocationManager) getSystemService(context);

      Intent anIntent = new Intent("com.adnan.proximityalert");
      PendingIntent operation =
      PendingIntent.getBroadcast(getApplicationContext(), unique_id , anIntent, 0);
      locationManager.removeProximityAlert(operation);
      }

      Just call this function when you wish to remove the alert !

      Delete
  5. Hello..
    If we want to have two broadcast receiver in the same application then how would we refer the receivers for different activities??

    ReplyDelete
    Replies
    1. I am not sure i fully understand your query but i will try to answer it

      Basically if you have two receivers for different broadcasts then you will need to register the receiver to listen for different broadcasts

      One broadcast could be "somename"

      Other broadcast could be "someothername"

      Register the receiver to listen for a particular broadcast that way you can differentiate two diff broadcasts

      If you need more help let me know !

      Thanks

      Delete
  6. will this work if the app is not running...

    ReplyDelete
    Replies
    1. Yes it will work even if the app is not running in background

      Delete
  7. Hi, I have one doubt, can we force Proximity to use GPS or Network provider? Please help me.

    ReplyDelete
    Replies
    1. A brilliant question,sadly though I dont think that would be possible , just had a look over the documentation as well , take note of this "Before API version 17, this method could be used with ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION. From API version 17 and onwards, this method requires ACCESS_FINE_LOCATION permission." So they are making it compulsory to pass in GPS Permission.

      So currently there is no way of forcing it to use any particular provider.

      There is a Enhancement Feature requested for the same , go ahead and star it to make Google implement it.

      Link to Enhancement : https://code.google.com/p/android/issues/detail?id=33151

      Delete

UA-42774700-1 Twitter Bird Gadget