Thursday, 24 October 2013

VOICE RECOGNITION IN ANDROID

You may have heard about the “ Google Now Project” where you give the voice command and Android fetches result for you. It recognizes your voice and converts it into the text or takes the appropriate action. Have you ever thought how is it done? If your answer is voice recognition API, then you are absolutly right. Recently while playing with Android voice recognition APIs, I found some interesting stuffs. APIs are really easy to use with application.The application may not work on the Android Emulator because it doesn’t support voice recognition. But the same can work on the phone.

Features:
               Voice recognition feature can be achieved by RecognizerIntent. Create an Intent of type RecognizerIntent and pass the extra parameters and start activity for the result. It basically starts the recognizer prompt customized by your extra parameters. Internally voice recognition communicates with the server and gets the results. So you must provide the internet access permission for the application. Android Jelly Bean(API level 16) doesn’t require internet connection to perform voice recognition. Once the voice recognition is done, recognizer returns value in onActivityResult() method parameters.

So,lets start with the implementation of the Voice Recognization in android.

First create project by Eclipse > File> New Project>Android Application Project. Fill the required field, i.e Application Name, Project Name and Package. Now press the next button. 
Now let’s define the Activity class. This activity class, with the help of checkVoiceRecognition() method, will first check whether the Voice recognition is available or not. If voice recognition feature is not available, then toast a message and disable the button. Speak() method is defined here which gets called once the speak button is pressed. In this method we are creating RecognizerIntent and passing the extra parameters. The code has embedded comments which makes it easy to understand.

VoiceRecognitionActivity.java
 import java.util.ArrayList;  
 import java.util.List;  
 import android.app.Activity;  
 import android.app.SearchManager;  
 import android.content.Intent;  
 import android.content.pm.PackageManager;  
 import android.content.pm.ResolveInfo;  
 import android.os.Bundle;  
 import android.speech.RecognizerIntent;  
 import android.view.View;  
 import android.widget.AdapterView;  
 import android.widget.ArrayAdapter;  
 import android.widget.Button;  
 import android.widget.EditText;  
 import android.widget.ListView;  
 import android.widget.Spinner;  
 import android.widget.Toast;  
 public class VoiceRecognitionActivity extends Activity {  
  private static final int VOICE_RECOGNITION_REQUEST_CODE = 1001;  
  private EditText m_etTextHint;  
  private ListView m_lvTextMatches;  
  private Spinner m_spTextMatches;  
  private Button m_btnSpeak;  
  @Override  
  public void onCreate(Bundle savedInstanceState) {  
  super.onCreate(savedInstanceState);  
  setContentView(R.layout.activity_voice_recognition);  
  m_etTextHint = (EditText) findViewById(R.id.vr_etTextHint);  
  m_lvTextMatches = (ListView) findViewById(R.id.vr_lvTextMatches);  
  m_spTextMatches = (Spinner) findViewById(R.id.vr_spNoOfMatches);  
  m_btnSpeak = (Button) findViewById(R.id.vr_btnSpeak);  
  }  
  public void checkVoiceRecognition() {  
  // Check if voice recognition is present  
  PackageManager m_pmanger = getPackageManager();  
  List<ResolveInfo> m_activities = m_pmanger.queryIntentActivities(new Intent(  
   RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);  
  if (m_activities.size() == 0) {  
   m_btnSpeak.setEnabled(false);  
   Toast.makeText(this, "Voice recognizer not present",  
    Toast.LENGTH_SHORT).show();  
  }  
  }  
  public void speak(View p_view) {  
  Intent m_intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);  
  // Specify the calling package to identify your application  
  m_intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass()  
   .getPackage().getName());  
  // Display an hint to the user about what he should say.  
  m_intent.putExtra(RecognizerIntent.EXTRA_PROMPT, m_etTextHint.getText()  
   .toString());  
  // Given an hint to the recognizer about what the user is going to say  
  m_intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,  
   RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);  
  // If number of Matches is not selected then return show toast message  
  if (m_spTextMatches.getSelectedItemPosition() == AdapterView.INVALID_POSITION) {  
   Toast.makeText(this, "Please select No. of Matches from spinner",  
    Toast.LENGTH_SHORT).show();  
   return;  
  }  
  int m_noOfMatches = Integer.parseInt(m_spTextMatches.getSelectedItem()  
   .toString());  
  // Specify how many results you want to receive. The results will be  
  // sorted where the first result is the one with higher confidence.  
  m_intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, m_noOfMatches);  
  startActivityForResult(m_intent, VOICE_RECOGNITION_REQUEST_CODE);  
  }  
  @Override  
  protected void onActivityResult(int p_requestCode, int p_resultCode, Intent p_data) {  
 if (p_requestCode == VOICE_RECOGNITION_REQUEST_CODE)  
 //If Voice recognition is successful then it returns RESULT_OK  
  if(p_resultCode == RESULT_OK) {  
  ArrayList<String> m_textMatchList = p_data  
  .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);  
   if (!m_textMatchList.isEmpty()) {  
  // If first Match contains the 'search' word  
  // Then start web search.  
  if (m_textMatchList.get(0).contains("search")) {  
  String m_searchQuery = m_textMatchList.get(0).replace("search"," ");  
  Intent m_searchIntent = new Intent(Intent.ACTION_WEB_SEARCH);  
  m_searchIntent.putExtra(SearchManager.QUERY, m_searchQuery);  
       startActivity(m_searchIntent);  
   } else {  
  // populate the Matches  
  m_lvTextMatches.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,  
   m_textMatchList));  
    }  
   }  
   //Result code for various error.   
   }else if(p_resultCode == RecognizerIntent.RESULT_AUDIO_ERROR){  
   showToastMessage("Audio Error");  
   }else if(p_resultCode == RecognizerIntent.RESULT_CLIENT_ERROR){  
   showToastMessage("Client Error");  
   }else if(p_resultCode == RecognizerIntent.RESULT_NETWORK_ERROR){  
   showToastMessage("Network Error");  
   }else if(p_resultCode == RecognizerIntent.RESULT_NO_MATCH){  
   showToastMessage("No Match");  
   }else if(p_resultCode == RecognizerIntent.RESULT_SERVER_ERROR){  
   showToastMessage("Server Error");  
   }  
  super.onActivityResult(p_requestCode, p_resultCode, p_data);  
  }  
  void showToastMessage(String p_message){  
  Toast.makeText(this, p_message, Toast.LENGTH_SHORT).show();  
  }  
 }  

activity_voice_recognition.xml
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:tools="http://schemas.android.com/tools"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   android:orientation="vertical" >  
   <EditText  
     android:id="@+id/vr_etTextHint"  
     android:gravity="top"  
     android:inputType="textMultiLine"  
     android:lines="1"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"   
     android:hint="@string/lbl_SearchHint"/>  
   <Button  
     android:id="@+id/vr_btnSpeak"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:onClick="speak"  
     android:padding="@dimen/padding_medium"  
     android:text="@string/lbl_btnSpeak"  
     tools:context=".VoiceRecognitionActivity" />  
   <Spinner  
     android:id="@+id/vr_spNoOfMatches"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:entries="@array/saNoOfMatches"  
     android:prompt="@string/lbl_sNoOfMatches"/>  
   <TextView  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:text="@string/lbl_tvTextMatches"  
     android:textStyle="bold" />  
   <ListView  
     android:id="@+id/vr_lvTextMatches"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content" />  
 </LinearLayout>  

Now add the string constants in string.xml. This file should look similar to the one shown below.

string.xml
 <resources>  
   <string name="app_name">VoiceRecognitionExample</string>  
   <string name="btSpeak">Speak</string>  
   <string name="menu_settings">Settings</string>  
   <string name="title_activity_voice_recognition">Voice Recognition</string>  
   <string name="tvTextMatches">Text Matches</string>  
   <string name="sNoOfMatches">No of Matches</string>  
   <string name="etSearchHint">Speech hint here</string>  
   <string-array name="saNoOfMatches">  
     <item>1</item>  
     <item>2</item>  
     <item>3</item>  
     <item>4</item>  
     <item>5</item>  
     <item>6</item>  
     <item>7</item>  
     <item>8</item>  
     <item>9</item>  
     <item>10</item>  
   </string-array>  
 </resources>  

Here is the Android manifest file. You can see that INTERNET permission has been provided to the application because of the voice recognizer’s need to send the query to the server and get the result.
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
   package="com.rakesh.voicerecognitionexample"  
   android:versionCode="1"  
   android:versionName="1.0" >  
   <uses-sdk  
     android:minSdkVersion="8"  
     android:targetSdkVersion="15" />  
   <!-- Permissions -->  
  <uses-permission android:name="android.permission.INTERNET" />  
   <application  
     android:icon="@drawable/ic_launcher"  
     android:label="@string/app_name"  
     android:theme="@style/AppTheme" >  
     <activity  
       android:name=".VoiceRecognitionActivity"  
       android:label="@string/title_activity_voice_recognition" >  
       <intent-filter>  
       <action android:name="android.intent.action.MAIN" />  
    <category android:name="android.intent.category.LAUNCHER" />  
       </intent-filter>  
     </activity>  
   </application>  
 </manifest>  

Once you are done with coding then connect the phone with your system and hit the run button on Eclipse IDE. Eclipse will install and launch the application. You will see the following screens on your device screen.

Wednesday, 23 October 2013

Simple Facebook SDK for Android which wraps original Facebook SDK 3.5

Hello Friends ,

Today i am going to show you the library which is named "SimpleFacebook Library" which contains the functionality of  Sharing,Inviting Friends ,Publishing , Post Feeds ,get Profile Details, Get Selected Friends List, Send invitation to Friends, get Album List  etc.. 

This library  include the Facebook SDK 3.5 which  makes the life much easier by coding less code for being able to login, publish feeds and open graph stories, invite friends and more.

Here are the Features supported by SimpleFacebook Library:

Features
  • Login
  • Logout
  • Publish feed
  • Publish story (open graph)
  • Publish photo
  • Invite friend/s
    • Invite all friends
    • Invite suggested friends
    • Invite one friend
  • Get profile
  • Get friends
  • Get albums
  • Based on latest Facebook SDK
  • Permission strings are predefined
  • No need to use LoginButton view for being able to login/logout. You can use any View.
  • No need to care for correct login with READ and PUBLISH permissions. Just mention the permissions you need and this library will care for the rest.

This library has reduced the login process of facebook using sdk. Using Facebook SDK we were calling the facebook login button to request for login. Now, You can call login(Activity) method on click of any View and you don't need to use LoginButton.

You just need to create the SimpleFacebook class instance in your activity's onResume() method and using instance call the login method of it as below:

Login:


mSimpleFacebook.login(onLoginListener);

Same way the logout functionality has also became simpler. To logout from Facebook you just have to call the logout method as below:

Logout:

 mSimpleFacebook.logout(onLogoutListener);

Project Configuration

First of all you need to download the Facebook SDK 3.5  or Download SDK  Which will provide all the latest classes which are used in SimpleFacebook library.

Steps:

  • After downloading the Facebook SDK just import the FB library in your workspace. 
  • Also import the SimpleFacebook library and SimpleFacebookSample in your workspace.
  • Once you have imported the SimpleFacebook Library in your workspace you need to Add reference fromSimple Facebook project toFacebookSDK project.

  • Now, you can add reference from your app to Simple Facebook project.
  • Update the manifest.xml of your application and add lines:


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

<activity
    android:name="com.facebook.LoginActivity"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Translucent.NoTitleBar" />
  • In your Application or Activity class you need to define the list of permissions which you are going to use to access the details from Facebook.
  • Define and select permissions you need:     
Permissions[] permissions = new Permissions[] {
    Permissions.USER_PHOTOS,
    Permissions.EMAIL,
    Permissions.PUBLISH_ACTION
};
  • Build and define the configuration by putting app_idnamespace andpermissions:
    SimpleFacebookConfiguration configuration = new SimpleFacebookConfiguration.Builder()
        .setAppId("***************")
        .setNamespace("<namespace>")
        .setPermissions(permissions)
        .build();
    
  • And, set this configuration:
    SimpleFacebook.setConfiguration(configuration);  
    
    There is no need to set the configuration in any activity, it should be done just once.
      After defining the Facebook Configuration you can start implementation as below:


  1. onResume()

       First of all in your each Activity where you want to use the SimpleFacebook library ,you just need to          create the instance of  SimpleFacebook Class in you activity's onResume() method.

@Override
public void onResume()
{
    super.onResume();
    mSimpleFacebook = SimpleFacebook.getInstance(this);
}
   
   2. onActivityResult()

      In your onActivityResult method add the below line:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    mSimpleFacebook.onActivityResult(this, requestCode, resultCode, data); 
    super.onActivityResult(requestCode, resultCode, data);
} 

Now, i am going to show you How to implement the login functionality using library. 
After successfully following the above all steps you need to implement the LoginListener interface in your activity which you can call directly on button click or from anywhere from any event.


// login listener
OnLoginListener onLoginListener = new SimpleFacebook.OnLoginListener()
{

    @Override
    public void onFail(String reason)
    {
        Log.w(TAG, reason);
    }

    @Override
    public void onException(Throwable throwable)
    {
        Log.e(TAG, "Bad thing happened", throwable);
    }

    @Override
    public void onThinking()
    {
        // show progress bar or something to the user while login is happening
        Log.i(TAG, "In progress");
    }

    @Override
    public void onLogin()
    {
        // change the state of the button or do whatever you want
        Log.i(TAG, "Logged in");
    }

    @Override
    public void onNotAcceptingPermissions()
    {
        Log.w(TAG, "User didn't accept read permissions");
    }

};
mButtonLogin.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View arg0) {
      mSimpleFacebook.login(onLoginListener);
   }
  });

This will open the Facebook login dialog from where you can login into facebook application and after login sucessfully it will redirect you to  your application again.

Same for the logout from Facebook you need to implement the LogoutListener as below:
Set OnLogoutListener and call for logout(OnLogoutListener) to disconnect from facebook.

// logout listener
OnLogoutListener onLogoutListener = new SimpleFacebook.OnLogoutListener()
{

    @Override
    public void onFail(String reason)
    {
        Log.w(TAG, reason);
    }

    @Override
    public void onException(Throwable throwable)
    {
        Log.e(TAG, "Bad thing happened", throwable);
    }

    @Override
    public void onThinking()
    {
        // show progress bar or something to the user while login is happening
        Log.i(TAG, "In progress");
    }

    @Override
    public void onLogout()
    {
        Log.i(TAG, "You are logged out");
    }

};
mButtonLogout.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View arg0) {
                        mSimpleFacebook.logout(onLogoutListener);
   }
  });

Now i am going  to show you how you can publish your post on Facebook.


To publish feed on facebook there is onPublishListener which you just need to implement. Also the Feed class which you can use to add the details of feeds. 

Set OnPublishListener and call for publish(Feed, OnPublishListener).

Basic properties

  • message - The message of the user
  • name - The name of the link attachment
  • caption - The caption of the link (appears beneath the link name)
  • description - The description of the link (appears beneath the link caption)
  • picture - The URL of a picture attached to this post. The picture must be at least 200px by 200px
  • link - The link attached to this post
  • properties - The key/value pairs which will appear in the stream attachment beneath the description
  • actions - One action link which will appear next to the 'Comment' and 'Like' link under posts
// create publish listener
OnPublishListener onPublishListener = new SimpleFacebook.OnPublishListener()
{

    @Override
    public void onFail(String reason)
    {
        // insure that you are logged in before publishing
        Log.w(TAG, reason);
    }

    @Override
    public void onException(Throwable throwable)
    {
        Log.e(TAG, "Bad thing happened", throwable);
    }

    @Override
    public void onThinking()
    {
        // show progress bar or something to the user while publishing
        Log.i(TAG, "In progress");
    }

    @Override
    public void onComplete(String postId)
    {
        Log.i(TAG, "Published successfully. The new post id = " + postId);
    }
};

// build feed
Feed feed = new Feed.Builder()
    .setMessage("Clone it out...")
    .setName("Simple Facebook for Android")
    .setCaption("Code less, do the same.")
    .setDescription("The Simple Facebook library project makes the life much easier by coding less code for being able to login, publish feeds and open graph stories, invite friends and more.")
    .setPicture("https://raw.github.com/sromku/android-simple-facebook/master/Refs/android_facebook_sdk_logo.png")
    .setLink("https://github.com/sromku/android-simple-facebook")
    .build();
      
 // click on button and publish
   mButtonPublishFeed.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
                          mSimpleFacebook.publish(feed, onPublishListener);
   }
  });


For more detail implementation check Demo 

Enjoy.

Thanks.