How do you rate this blog

Saturday, July 5, 2014

Consume WCF data service in Android


The basic need for any application is to send or receive data. So how do we make application read or write data in a mobile, the answer is Web services / WCF  / WCF REST Services / Web API.

In this post I am going use WCF data services. 

What is WCF Data Service?


    WCF data service is a component of .NET framework which helps you to expose the specific database object(s) as services over OData (Open data protocol). The

data exchange in this happens through Atom and JSON(Java Script Object Notification)

Setting up Environment:

1) Java should be installed in your machine. If you want to download Java go to the following Link
2) Eclipse should be present in the machine. This can be downloaded in the following Link
If there is any issue like
    a) Java not installed in your machine, please add the path where java is installed on your machine to the environment variable- PATH
    b) If you have an error saying jvm.dll not found, then please check the version of eclipse that you have and then the version of java that you have installed on the system. Given below are the combinations in which eclipse will work
    32 bit OS can have 32 bit eclipse and 32 bit java (pretty straight forward)
    64 bit OS can have 32 bit eclipse and 32 bit java only
    64 bit OS can have 64 bit eclipse and 64 bit java only
3) There are 2 ways to consume WCF data services
    a) OData4j
    b) restlet
   In this post I am going to use Odata4j. This can be downloaded through the Link
Now that we have the environment set up, lets get on with the app.

What should the app do?

1) The app should be able to connect to the WCF data service
2) Ability to access a table / entity which has been exposed over the service
3) Display it in the list view.


Now lets start off with the app by creating a new android app project in eclipse. Once created import the Odata4j jar file "odata4j-0.7.0-clientbundle.jar" which will

be present in the bundles folder of Odata4j download. To import you need to right click on the project > properties > libraries > Add external jar and select the file

mentioned above. Once done go to Order and Export tab and check the library file.

Step 1 - Android Manifest File: 
This application needs access to internet so go ahead and the following code to the android manifest file
    <uses-permission android:name="android.permission.INTERNET" />

Step 2 - Creation of Layout:

This application needs the following elements in the layout:
1) Button to call the service
2) List view to display the elements we want to display on the app

The layout will look like the code below:

<LinearLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >

 <Button
 android:id="@+id/callbtn"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="Connect to WCF" />

 <ListView
 android:id="@+id/wcflistview"
 android:layout_width="match_parent"
 android:layout_height="wrap_content" >
 </ListView>

</LinearLayout>


Step 3 - Accessing the web service:

We need a wcf data service from which we will access an entity, we have a service called as http://services.odata.org/Northwind/Northwind.svc/. To check what are the

entities exposed in the service use the following link http://services.odata.org/Northwind/Northwind.svc/$metadata. In this post I will use Categories. To see what

data is present in this entity use the uri http://services.odata.org/Northwind/Northwind.svc/Categories

The code for connecting is given below along with the comment as to why is it used

package com.service.wcfexample;

import java.util.ArrayList;
import java.util.List;

import org.odata4j.consumer.ODataConsumer;
import org.odata4j.core.OEntity;
import org.odata4j.jersey.consumer.ODataJerseyConsumer;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

public class Wcfserv extends Activity {
Button callbtn;
ListView wcflist;
ArrayList cat;
ArrayAdapter cat_adpt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wcfserv);
        callbtn=(Button) findViewById(R.id.callbtn);
        wcflist=(ListView) findViewById(R.id.wcflistview);
        cat=new ArrayList();
       
        callbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
            // TODO Auto- generated method stub
            new wcfService().execute();
                    }
                });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.wcfserv, menu);
        return true;
    }

    public class wcfService extends AsyncTask<Void, Void, ArrayList<String>>{

        @Override
        protected ArrayList<String> doInBackground(Void... arg0) {
            //To call the service
            ODataConsumer con = ODataJerseyConsumer.create("http://services.odata.org/Northwind/Northwind.svc");
            //List which will hold a particular entity from the consumer
            List<OEntity> myEntity = con.getEntities("Categories").execute().toList();
            //To add the elements of myEntity into a arraylist
            if (myEntity.size() > 0) {
                for (OEntity entity : myEntity) {
                    cat.add(entity.getProperty("CategoryID").getValue().toString()
                    + " - "
                    + entity.getProperty("CategoryName").getValue()
                    .toString());
                    }
                }
            return cat;
            }

            @Override
            protected void onPostExecute(ArrayList<String> result) {
            super.onPostExecute(result);
            //displaying the result
            cat_adpt = new ArrayAdapter<String>(Wcfserv.this,
            android.R.layout.simple_list_item_1, result);
            wcflist.setAdapter(cat_adpt);
           
        }
       
       
       
    }
   
   
}

Step 4- Run the application:
Now run the application and the screen will be as shown in the snapshot below:




Now Click on connect to WCF the output will as shown below:







Saturday, May 3, 2014

Changing the color of an app based on Light Sensor

Recently I got a strange requirement that the theme of the app should change based on the light conditions. So my initial approach was to inflate a new theme as and when the conditions change but that was a bad idea since it would be a very bad user experience since there would be a period where in the app would reinitialize, so I  stopped over engineering about the problem and used a simple approach of recoloring the layouts. In this post I will just go ahead and create a simple app which shows the current reading of brightness in terms of lux, if the brightness is below 10 lux the background becomes black and the text becomes white and if the brightness the logic is simple given below are steps :

1. Register the Light sensor if it is present.
2. Read the sensor value.
3. if the value is above 10 LUX then change the theme having black background and white text else have white background and black text.

Now that we know the logic lets go ahead and code this.

Step 1: Create a new project using andoroid 4.3 in my case I have called it as LightSensor
Step 2: Go to the LightSensor.java file within src folder of the project and lets implement the logic that we have discussed above.
   
    Step a: We need to see if the Light sensor is present or not and if present we need to register the light sensor to obtain readings. This can be done using the code below:
        if(curSensor!=null){
            SM.registerListener(this, curSensor, SM.SENSOR_DELAY_FASTEST);
           
        }
        else{
            Values=(TextView) findViewById(R.id.textView1);
            Values.setText("Unable to register sensor");
        }
    If you want to know in detail how to use light sensor then go my post given in this link LightSensor
   
    Step b: Now that we have registered we need to obtain the value, this is done using the code below on the onSensorChanged function which you have to override if you implement SensorEventListener.
       

        if(event.sensor.getType()==Sensor.TYPE_LIGHT){
            // to obtain the light sensor value
            Values.setText("Value= "+event.values[0]+" lux");
            LSVal=event.values[0];
            //to call the theme changer based on the light condition
            if(event.values[0] > 100){
                changeTheme(1);
                displays.setText("Good Light Conditions");
            }
            else{
                changeTheme(0);
                displays.setText("bad Light Conditions");       
            }
        }
       
Step 3: You have now completed the code for reading the light sensor value, now we need to write a simple code to change the layout based on the condition. I have used a parameter which helps me to find out which layout I should shift to when there is a change light condition, you can do it in a much better way, this is just for an example.

     public void changeTheme(int theme){
        if(theme==1){
            //Layout Background
            LL.setBackgroundColor(Color.WHITE);
            //Text Background
            Values.setBackgroundColor(Color.WHITE);
            Values.setTextColor(Color.BLACK);
            displays.setBackgroundColor(Color.WHITE);
            displays.setTextColor(Color.BLACK);
            sensorSetting.setBackgroundColor(Color.WHITE);
            sensorSetting.setTextColor(Color.BLACK);
            //Edit Text
            sensortresh.setBackgroundColor(Color.WHITE);
            sensortresh.setTextColor(Color.BLACK);           
        }
        else{
            //Layout Background
            LL.setBackgroundColor(Color.BLACK);
            //Text Background
            Values.setBackgroundColor(Color.BLACK);
            Values.setTextColor(Color.WHITE);
            displays.setBackgroundColor(Color.BLACK);
            displays.setTextColor(Color.WHITE);
            sensorSetting.setBackgroundColor(Color.BLACK);
            sensorSetting.setTextColor(Color.WHITE);
            //Edit Text
            sensortresh.setBackgroundColor(Color.BLACK);
            sensortresh.setTextColor(Color.WHITE);
        }
    }

    The above code changes the background and the text colors, you can modify the colors based on your need. You can do various things like if the light conditions are bad you can auto adjust the brightness of the screen (although this is already done by the phone). Given below is are screen shots of the app in different light conditions.

Good light Condition

Bad Light Condition

If you have a better way of doing the same please do let me know.

Sunday, December 29, 2013

Light Sensor

This post is about detecting ambient lighting in which the device is present. This is done using the light sensor present in the device. The light sensor measures the light in terms of LUX. So how do you get the value of Light sensor? Given below is the logical flow to obtain the light sensor value:

1) Check if there is light sensor present on the android device.
2) Register the listener for the sensor.
3) Obtain the value from the registered sensor.


 Now lets go about building the application, we need to get the layout in place first. So we will go ahead add a linear layout and 2 text fields one as a label and the other which displays the value. The layout code will look in the image below.


Once the layout is ready, we will go ahead and apply the logic which we discussed above. Lets go step by step assuming you know how to create a project,

1) Check if there is light sensor present on the android device:
    Almost all android devices will have light sensor present, but just to make sure we handle this in our code. The code given below will help you to check if the

sensor is present or not. You need implement SensorEventListener in the class, which inturn makes you write onResume, onPause, onAccuracyChanged, onSensorChanged

methods.

        //declare Sensor Manager and Sensor       
        private SensorManager SM=null;
        private Sensor curSensor=null;

        //to check Light sensor
        SM=(SensorManager) this.getSystemService(SENSOR_SERVICE);
        curSensor=SM.getDefaultSensor(Sensor.TYPE_LIGHT);
       
        //if the curSensor returns null then this means that there is no Light Sensor present in the system.
        if(curSensor==null){
            Values.setText("unable to find the sensor in the device");
        }
        else{
            Values.setText("Light sensor is present in the device");
        }

2) Register the listener for the sensor:
     If we know that the light sensor is present in the device then we will go ahead and register the listener to that sensor. This is done using the code below:
    SM.registerListener(this, curSensor, SM.SENSOR_DELAY_FASTEST);
    where SM refers to Sensor Manager, curSensor refers to Light Sensor. There are 4 differents rates at which sensor data can be obtained
    1) SENSOR_DELAY_FASTEST :This is used when you want the data as soon as possible.
    2) SENSOR_DELAY_GAME    :This one provides at a rate which is suitable for games.
    3) SENSOR_DELAY_NORMAL    :This is the default rate.
    4) SENSOR_DELAY_UI    :This provides at a rate which is suitable for user interface.

Now that we know how to register the user we can merge step 1 and 2 and write detection and registering in one shot and the code will look like:

        //declare Sensor Manager and Sensor       
        private SensorManager SM=null;
        private Sensor curSensor=null;

        //to check Light sensor
        SM=(SensorManager) this.getSystemService(SENSOR_SERVICE);
        curSensor=SM.getDefaultSensor(Sensor.TYPE_LIGHT);
       
        //if the curSensor returns null then this means that there is no Light Sensor present in the system.
        if(curSensor!=null){
            SM.registerListener(this, curSensor, SM.SENSOR_DELAY_FASTEST);

        }
        else{
            Values.setText("unable to find the sensor in the device");
        }

3) Obtain the value from the registered sensor:
        Once the sensor listener is registered we need to go ahead and extract the value from the sensor. This is done using the code below

        if(event.sensor.getType()==Sensor.TYPE_LIGHT){
           
            Values.setText("Value= "+event.values[0]+" lux");
        }

        This code needs to be added in the onSensorChanged method.
Now your application is almost ready, but we need to add few more code for the application to function properly. In the onResume you need to check for the sensor and

add register the listener again, so go ahead and add the below code to the onResume() function.

        super.onResume();
        if(curSensor!=null){
            SM.registerListener(this, curSensor, SM.SENSOR_DELAY_FASTEST);
           
        }
        else{
            Values=(TextView) findViewById(R.id.textView1);
            Values.setText("Unable to register sensor");
        }

When application is paused then go ahead and un register the listener, this you can do by adding the below code to the onPause() function
        SM.unregisterListener(this);

Once you complete this generate an apk and run it on your device. A sample output of the application is given below.

Thursday, August 16, 2012

Bluetooth - Scan for devices


In this post I have created a simple application which searches for and displays a list of all the devices which have their Bluetooth turned on.
                The logic for the following is –
1)      Create a Bluetooth adapter.
2)      Create a Listview to store all the devices which have been discovered.
3)      See if the device has Bluetooth capability and turn it on if it is not enabled.
4)      Search for devices and get the names

Now lets start creating this simple application, this application requires access to the Bluetooth in the device so provide access to Bluetooth in the manifest file as shown below.

Then create the layout as shown below





The code for the same is as shown below 



Then implement the logic as described earlier,
1)      Declaring the bluetooth adapter
BluetoothAdapter BA = BluetoothAdapter.getDefaultAdapter();

2)      Creating the listview which stores all the device names in an array adapter
BTadapter=new ArrayAdapter <String>(BluetoothDemoActivity.this,android.R.layout.simple_list_item_1);

3)      Then we need to check if the device has bluetooth capability, if the device has bluetooth check if it is enabled and if it is not request the user to turn on the Bluetooth as shown in the code below

private void findBluetoothState() {
                               
                                if(BA==null){
                                                BTState.setText("Bluetooth service not available in the device");
                                }
                                else{
                                                if(BA.isEnabled()){
                                                                if(BA.isDiscovering()){
                                                                                BTState.setText("Finding Devices");
                                                                }
                                                                else{
                                                                                BTState.setText("Bluetooth is Enabled");
                                                                                BTState.setEnabled(true);
                                                                }
                                                }
                                                else{
                                                                BTState.setText("Bluetooth is not enabled");
                                                                Intent startBT=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                                                startActivityForResult(startBT,REQUEST_ENABLE_BLUETOOTH);
                                                }
                                }
                               
                }

4)      Next search for devices and get the devices which have their bluetooth turned on.
                private final BroadcastReceiver BR=new BroadcastReceiver(){
                                @Override
                                public void onReceive(Context context, Intent intent) {
                                                String act=intent.getAction();
                                                if(BluetoothDevice.ACTION_FOUND.equals(act)){
                                                                BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                                                BTadapter.add(device.getName()+" - "+device.getAddress());
                                                                BTadapter.notifyDataSetChanged();
                                                }
                                }
                };
The code will look as shown in the image below – 



When you start the app and it finds that the Bluetooth is not enabled then you will get a screen shot as shown below.



Once you provide permission for it to turn on the Bluetooth and click on scan for devices then you will get the list of devices along with the MAC address as shown in the image below.



Tuesday, August 7, 2012

To get Latitude and Longitude of Current Location


This post explains how to get the current location using GPS. In this post the app will display your current latitude and longitude if it can access the network.

The logic for this is -
1)      Provide the app access to GPS in the device.
2)      Get location manager, which enables the device to get periodic location updates of the device.
3)      Then select the best provider based on the criteria.
4)      Then obtain the latitude and longitude if there is a provider.

Based on the logic mentioned above lets code the application –

1)      In the android manifest file provide access to the GPS using code as shown in the snapshot given below.

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

The code will look as shown below in the snapshot



2)      Get the location manager – 

LocationManager LC=(LocationManager) getSystemService(Context.LOCATION_SERVICE);

The above code creates a location manager to get the location updates.

3)      Select the best provider based on the criteria –
Criteria criteria=new Criteria();
provider=LC.getBestProvider(criteria, false);
        Location loc=LC.getLastKnownLocation(provider);
4)      Obtain the latitude and longitude –

@Override
        public void onLocationChanged(Location location) {
                        intlat=(int) (location.getLatitude());
                        intlon=(int) (location.getLongitude());
                        latitudeval.setText(String.valueOf(lat));
                        longitudeval.setText(String.valueOf(lon));
        }

The code will look as shown below.



Create an APK file out of it and install on your mobile and run the application. The output will be as shown in the snapshot shown below.


Thursday, May 24, 2012

Simple SMS - Receive Feature


    In the previous post I had told about the method to send sms, in this post I will tell about how to receive SMS and how to test out the application.

We will use the same application which we used for sending SMS, here we will add one more class called Rec which will extend BroadcastReceiver have code to receive application.  Once you do this you need to implement onRecieve method as shown below and write an intent filter which will allow it to receive SMS.
/*to obtain the message*/        
public void onReceive(Context C, Intent I) {
                               
                                Bundle B=I.getExtras();
                                SmsMessage[] msgs=null;
                                String sms_str="";
/* Receive SMS and display*/                                   
                                if(B !=null){
                Object[] pdus=(Object[]) B.get("pdus");
                msgs=new SmsMessage[pdus.length];
                for(int i=0;i<msgs.length;i++){
/*To convert the sms which is in PDU format*/
                msgs[i]=SmsMessage.createFromPdu((byte[])pdus[i]);
/*To display the number from which the message was sent*/
                sms_str+="Recieved SMS From : "+msgs[i].getOriginatingAddress() +" : ";
                sms_str+=msgs[i].getMessageBody().toString()+"\n";
                                                }
                Toast.makeText(C, sms_str, Toast.LENGTH_LONG).show();
                                }
The code for receive class will look like in the snapshot given below.



Now we need to modify the manifest.xml file to include the following

<receiver android:name=".Rec">
     <intent-filter>
           <action android:name="android.provider.Telephony.SMS_RECEIVED" />
     </intent-filter>
</receiver>

Which will display the message in the application and will display it as a Toast.
Also include the below code so that the application has the access to receive sms.
<uses-permission android:name="android.permission.RECEIVE_SMS">
    </uses-permission>
So the manifest file will look like in the image given below.



Once these are done the application is ready to receive the SMS. So now the question is how to test it. Inorder to do test if the application receives the the eclipse has a DDMS perspective which allows you to send voice or sms to the emulator. To access DDMS you can refer to the following link DDMS Link. Now type in the emulator number in this case it is 5554 and send as SMS as shown in the snapshot below. 



Once you click on Send button in DDMS you can see that the SMS is received in the application as shown in the snapshot shown below.


Saturday, May 5, 2012

Simple SMS - Send feature


SMS is the most used and one of the most popular features in the mobile phone. In this post I have explained a simple custom sms app which uses the API’s provided by android.

                In this app I will create a text box which will take only numbers and one more text box where in you can type in your message. Once these are done the user can click on the send button which will send the sms to the phone number mentioned.
So lets get started with the creation of the application-
Step 1 – Modification of AndroidManifest.xml file
                Since this application sends SMS we need to provide the application rights to access the SMS service in the mobile device. So we need to add the code below in the “androidmanifest.xml” file
<uses-permission android:name="android.permission.SEND_SMS">    </uses-permission>
The manifest file would like in the snapshot shown below.



Step 2 – Layout Creation
                The layout for this is kept very simple wherein we have one editable text box for phone number and other for message. The layout will be as shown in the snapshot given below.



Step 3 – Code to send SMS
                Open the java file in src folder, as you can see you already have basic code already setup for you. So we need to just implement the send sms functionality in this. Declare the buttons and editable text boxes and bind them to the respective controls in the UI as shown in the code below –
    Button send;
    EditText ph_num;
    EditText message;

/*bind the variables to the controls used in the UI*/
        send=(Button) findViewById(R.id.button1);
        ph_num=(EditText) findViewById(R.id.editText1);
        message=(EditText) findViewById(R.id.editText2);
       
Then implement the send SMS functionality when you click the Send SMS button, the code for which is given below.

send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*to convert the phone number and the message to string format*/
                String phone_num=ph_num.getText().toString();
                String sms=message.getText().toString();
/*we will go to send sms functionality only if there is message and phone number*/
                if(phone_num.length()>0 && sms.length() > 0)
                                send_sms(phone_num,sms);
                else
Toast.makeText(getBaseContext(), "Please enter both phone number and message", Toast.LENGTH_LONG).show();
                                                }
                                });

Now we will code the Send SMS functionality –
Inorder to send SMS android provides SmsManager, but this object cant be instantiated directly hence we need to make use of Pending Intent. A Pending Intent is a token that is provided to a foreign application which gives it right to use the applications permission to execute a predefined code in the application. This is done as per the code shown below
public void send_sms(String phone, String msg){
PendingIntent SMS_Sent=PendingIntent.getActivity(this, 0, new Intent(this,AndroidSMSActivity.class), 0);
                 SmsManager sms=SmsManager.getDefault();
                 sms.sendTextMessage(phone, null, msg, SMS_Sent, null);
                Toast.makeText(this, "SMS Sent", Toast.LENGTH_LONG).show();
    }
At the end we add a Toast to notify the user that the SMS has been sent. The code will be as shown below in the snapshot.


Now run the application through the emulator, although it doesnt send sms to any mobile device and the result will be as shown in the snapshot below. 



I will explain how to test out the application using 2 emulators in the post where I will explain how to receive SMS. Hope this was useful to you.