Friday, June 14, 2013

Json parsing in BB 10

Generally, in many development technologies, we will be adding JSON api to project or provided by OS itself and parse the appropriate response using JSON API's. Here it is a different approach.
  1. Convert JSON response to QVariant using JsonDataAccess.
  2. Query the QVariant object for JSON children Nodes.
[
  {
    "id": "13",
    "en_description": "If leadership does not keep",
    "ar_description": "\u0625\u0646 \u0627",
    "date": "2012-09-28"
  },
  {
    "id": "14",
    "en_description": "The role of the leadership",
    "ar_description": "\u062f\u0648\u0631 \u0627",
    "date": "2012-09-28"
  }
]

In the above Json, I am likely to parse the data of "en_descreption" tag. The method to parse is shown below.

void Quotes::onUrlLoad(QString jsonResponse) {

    ArrayDataModel *arrayDataModel = new ArrayDataModel();

    //  Convert Json file into QTList objects.
    bb::data::JsonDataAccess ja;
    const QVariant jsonva = ja.loadFromBuffer(jsonResponse);
    const QList externalip = jsonva.toList();

    //  Iterate Json List and retrieve data, store it in ArraydataModel
    for (int index = 0; index < externalip.size(); index++) {

        QVariantMap map = externalip.at(index).toMap();
        QVariantMap::Iterator iterator = map.begin();
        while (iterator != map.end()) {
            //  Append "en_descreption" tag's value to the ArrayDataModel.
            if (!iterator.key().toStdString().compare("en_description")) {
                arrayDataModel->append(iterator.value().toString());
            }
            ++iterator;
        }   //  end while.
    }   //  end for

}

Above code does the following things 
  1. Loads Json string using JsonDataAcces.
  2. Converts the Json String to root QVariant object with the help of JsonDataAccess.
  3. Get the List of QVariant variables from the root QVariant variable . Note that as our JSON is an array hence we are using jsonva.toList(). Otherwise we have to use jsonva.toMap() as per documentation.
  4. Pull each QVariantMap from the list.
  5. Iterate the map for the values.
  6. Extract values with "en_description" and store it in ArrayDataModel.
That's it .. we are done with parsing and storing JSON data.

Wednesday, June 5, 2013

Navigation Mode's in Android Action Bars

Actions bar's can be represented in 3 different styles or formats

All these modes can be achieved using Sherlock as well as Native Action bar's. Native action bar's are supported from Android OS Version 3.0 and above.

Sherlock ActionBar with NavigationList

NavigationList is one more type of navigation in ActionBar's which serves the same functionality as tabs.

Let me show you how this look's like
Gmail App with Navigation list mode 
In the above pic, Upon click of Inbox, the navigation list appears.

If you are not familiar with the configuration of Sherlock Action Bar project please refer my previous post.

Comming back...To achieve List style of navigation mode, set the navigationmode of Action bar to ActionBar.NAVIGATION_MODE_LIST and pass the respective adapter for this list. The code is shown below.

/**
* Initialises the views and variables of the activity.
 */
private void init() {

    //  initialise ActionBar
    mActionBar = getSupportActionBar();
    mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
        
    //  Initialise Array Adapter.
    final ArrayAdapter arrayAdapter = new ArrayAdapter(this,
         android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
    arrayAdapter.add("Login");
    arrayAdapter.add("Elections");
    arrayAdapter.add("Maintainance");
    arrayAdapter.add("Results");
        
    //  Set array adapter to navigation list, implement a listener for the list.
            mActionBar.setListNavigationCallbacks(arrayAdapter, new OnNavigationListener() {
            @Override
            public boolean onNavigationItemSelected(int arg0, long arg1) {
                Toast.makeText(SherlockListActionBarActivity.this, arrayAdapter.getItem(arg0), Toast.LENGTH_SHORT).show();
                return false;
            }
        });
}

The above method should be called from onCreate() method of your SherlockActivity.

This method defines ActionBar, Prepares the Adapter for NavigationList, sets call back for Navigation List item click.

Related topics:

Tuesday, June 4, 2013

Android Sherlock Action Bars with Tab's

Action bar's provide a functionality to integrate tabs.

As mentioned in my previous post I'm just recapping how to configure Sherlock API with our project. 

Steps to implement Sherlock action bar include.
  • Download Sherlock source.
  • UnZip the source and find "actionbarsherlock" folder, which is the library project for implementing Sherlock ActionBar.
  • Import the library project into the workspace.
  • Create a new Android Project.
  • Click on properties of the project and add "actionbarsherlock" as library project.

  • Extend your class with SherlockActivity        
public class SherlockAtionBar extends SherlockActivity
  • Override onCreate and setTheme as one of the sherlock theme before calling super.onCreate()
Now, we are almost ready to implement our tabbed action bar.

Here I would like to use a ViewPager, Fragments along with Tab's.  Add tabs to ActionBar, intialiase FragmentPagerAdapter, set FragmentPagerAdapter to ViewPager, integrate tab clicks with viewpager.

The complete activity looks like

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.ActionBar.TabListener;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.vl.actionbar.LoginFragment;
import com.vl.actionbar.R;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewParent;

import java.util.ArrayList;

/**
 * Sherlock Action Bar to demonstrate Tabs behavior
 * 
 * @author shpolavarapu
 * 
 */
public class SherlockTabsActionBarActivity extends SherlockFragmentActivity {

    private ViewPager mViewPager;
    private ActionBar mSupportActionBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.Theme_Sherlock_Light_DarkActionBar);
        super.onCreate(savedInstanceState);
        
        init();
    }

    /**
     * Initialises the Views and variables for this activity.
     */
    private void init() {
        
        //  Initialise and set viewpager to the activity.
        mViewPager = new ViewPager(this);
        mViewPager.setId(1232);
        setContentView(mViewPager);
        
        //  Init and set ActionBar Properties.
        mSupportActionBar = getSupportActionBar();
        mSupportActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        
        //  Initialise Adapter for the view pager.
        SherlockTabAdapter adapter = new SherlockTabAdapter();
        ArrayList<Bundle> bundleAL = new ArrayList<Bundle>();
        String texts[] = {"Login", "Elections", "Polling", "Results"};
        for(int index = 0; index < texts.length; index++)
        {
            //  Prepare Bundle object for each tab.
            Bundle bundle = new Bundle();
            bundle.putString("text", texts[index]);
            bundleAL.add(bundle);
            
            //  Add tabs for the action bar.
            ActionBar.Tab tab = mSupportActionBar.newTab().setText(texts[index])
                    .setTabListener(adapter);
            mSupportActionBar.addTab(tab);
        }
        
        adapter.setBundle(bundleAL);
        mViewPager.setAdapter(adapter);
        mViewPager.setOnPageChangeListener(adapter);
    }




    /**
     * Adapter for setting the content for the tab click's.
     * 
     * @author shpolavarapu
     * 
     */
    private class SherlockTabAdapter extends FragmentPagerAdapter implements ActionBar.TabListener,
            ViewPager.OnPageChangeListener {

        private ArrayList<Bundle> mBundleAL;
        
        public SherlockTabAdapter() {
            super(getSupportFragmentManager());
        }
        
        /**
         * ArrayList of bundle's to pass as Arguments to Fragment.
         * @param bundleAL  ArrayList of bundle's
         */
        void setBundle(ArrayList<Bundle> bundleAL) {
            mBundleAL = bundleAL;
        }
        @Override
        public void onPageScrollStateChanged(int position) {
            
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageSelected(int position) {
            //  Change the tab selection upon page selection.
            mSupportActionBar.setSelectedNavigationItem(position);
        }

        @Override
        public void onTabReselected(Tab arg0, FragmentTransaction arg1) {

        }

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction arg1) {
            //  On Tab selection change the View Pager's Current item position. 
            mViewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {

        }

        @Override
        public Fragment getItem(int pos) {
            return Fragment.instantiate(SherlockTabsActionBarActivity.this, LoginFragment.class.getName(), mBundleAL.get(pos));
        }

        @Override
        public int getCount() {
            return mBundleAL.size();
        }

    }

}

The LoginFragment is posted below.

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class LoginFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        
        View view = inflater.inflate(R.layout.login, null);
        if(getArguments() != null)
        {
            String text = getArguments().getString("text");
            ((TextView)view.findViewById(R.id.tv_login)).setText(text);
        }
        return view;
    }
}

login Layout is posted below :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical" >

     <TextView
        android:id="@+id/tv_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Login" />


</LinearLayout>

Output :


Overview:

 Create Tabs and ArrayList of Bundle data which contain name of the tab. Create a ViewPager and set the FragmentPagerAdaper to it. The Adapter also listens TabClick and ViewPager PageChange. On TabClick, Login Fragment with the bundle data as arguments is instantiated  and supplied to viewpager.

Don't forget to add NavigationMode as ActionBar.NAVIGATION_MODE_TABS. Native Action Bar's implementation with tabs can also use the same code with minor changes,

Related topics : 

Android Action Bar MenuItem's using Sherlock API

Android introduced Action bar's in API level 11 i.e in HoneyComb 3.0. Native implementation is posted here.  There is no backward compatibility as of now. This leads to our point of discussion.

In some cases where our action bar needs to be compatible from Android SDK version 2.1. In such cases we can go with Sherlock API.

Steps to implement Sherlock action bar include.
  • Download Sherlock source.
  • UnZip the source and find "actionbarsherlock" folder, which is the library project for implementing Sherlock ActionBar.
  • Import the library project into the workspace.
  • Create a new Android Project.
  • Click on properties of the project and add "actionbarsherlock" as library project.


Now, we are ready to implement our action bar.

1) Extend your class with SherlockActivity
            
public class SherlockAtionBar extends SherlockActivity

2) Override onCreate and setTheme as one of the sherlock theme before calling super.onCreate()

@Override
protected void onCreate(Bundle savedInstanceState) {
    setTheme(R.style.Theme_Sherlock);   
    super.onCreate(savedInstanceState);
    setContentView(R.layout.login);
}

3) Override onCreateOptionsMenu()


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Collapsible Action Item
    menu.add("Search").setIcon(R.drawable.ic_search)
                      .setActionView(R.layout.collapsible_edittext)  
                          .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | 
                                  MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);

    // OverFlow menu in actionbar.
    SubMenu submenu = menu.addSubMenu("");
    submenu.setIcon( R.drawable.abs__ic_menu_moreoverflow_normal_holo_dark);

    submenu.add(1, 0, 1, "Cut");
    submenu.add(1, 1, 2, "Copy");
    submenu.add(1, 2, 3, "Paste");
    submenu.getItem(). setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS|
                         MenuItem.SHOW_AS_ACTION_WITH_TEXT);
    // end overflow menu

   return true;
}


My collapsible_edittext layout looks like


<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="Search"/>


That's it ..... our action bar with menu items and action view is ready. Snapshot of output is shown below.
 
Sherlock action bar with Action view, menu item's and sub menu item's

 I will now explain code in OnCreateMenuOptions(). First with the submenu thing.

If we add menu items to Menu directly using Menu.add(), Actionbar will have different UI for different OS versions of Android. For 3.0 and above it will be shown as overflow menu like in the above picture. For Android OS version's less than 3.0, action bar's overflow type of menu is overrided by the default menu's(at the bottom). I think you got my point... For consistent behaviour of overflow menu's, we have to use SubMenu instead of Menu. Don't forget to add setShowAction() property for the sub menu item. This property will change the style of the menu's to overflow.

We also have some default things for an activity such as Search. Considering these functionalities,  concept of ActionViews is introduced. In the above discussed OnCreateMenuOptions(), we have added search menu item to Menu and provided collapsible_edittext layout for the ActionView. Upon click of search Menu Item the layout appears on the top of action bar like ..

Sherlock ActionBar with Action View.
As per our layout edit text appears with hint as Search.

Split ActionBar :

 We can split the action bar based on the space availability. Just add a tag android:uiOptions = "splitActionBarWhenNarrow".

Observe the change in the below output by using this tag.

Split action bar in Android Phone
The split behavior is different in large screens. See the below output in Nexus 10 device.


From this observation, we can judge that split behavior comes into act when there is no real estate to display on action bar .

Related topics : 

Sunday, June 2, 2013

Android Http Live Streaming(HLS)

Http Live streaming(HLS) allows applications to stream the media content of servers. If you would like to follow HLS standards, the content type of the media should be in the format of m3u8. m3u8 file is a meta data container for the media information to play. As m3u8 is supported by Android 3.1 and above, if we provide m3u8 URL's the streaming will be automatically done by the Media Player or VideoView  object.

VideoView videoView = (VideoView) findViewById(R.id.videoView);
String httpLiveUrl = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
videoView.setVideoURI(Uri.parse(httpLiveUrl)); 
videoView.setMediaController(new MediaController(this));
videoView.requestFocus();
videoView.start();

Some of the working urls include

http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8
http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8

To support Android versions 2.1 and above use third party vitamo player.

Saturday, June 1, 2013

Andoroid Action Bar Menu items

ActionBar is a header sort of thing with number of powerful options to play with the application.
Let us come to a conclusion why to go for an action bar?

We will be having some options in our activity like.. popping a Menu, search in the activity, Tabs, title, app icon  etc. Think, if there is a mechanism where we can handle all these tasks in a single view sort of thing.. Yes .. this can be achieved by action bars.

The above pic represents action bar in Google Play App.

Before learning the tabbed behavior, we will go through the integration of menu items with Actionbars. The new menu items with action bar looks like :


Three vertical dots represent the Menu, Upon Click menu items will be populated.

Coming to implementation, there are no changes compared to implementation of menu in previous versions.
  1. Define menu options in xml.
  2. Inflate them and add it to the menu in OnCreateOptionsMenu method.
My menu action_items.xml look like.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/refresh"
        android:icon="@drawable/refresh"
         
        android:title="Refresh"/>
    <item
        android:id="@+id/inbox"
        android:icon="@drawable/email"
        android:title="Inbox"/>

    <item
        android:id="@+id/compose"
        android:title="Compose"/>

</menu>

Now, Override OnCreateOptionsMenu() and inflate menu. This piece of code is shown below.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.action_items, menu);
    return true;
}

We are having number of options to arrange menu within this action bar itself. We can display icons for these menu items.For displaying menu icons provide another tag android:showAsAction="ifRoom". This will show the menu item's icon, if there is sufficient room on the ActionBar. This output wil be like


My action_items.xml look like

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/refresh"
        android:icon="@drawable/refresh"
        android:showAsAction="ifRoom"
        android:title="Refresh"/>
    <item
        android:id="@+id/inbox"
        android:icon="@drawable/email"
        android:showAsAction="ifRoom"
        android:title="Inbox"/>
    <item
        android:id="@+id/compose"
        android:title="Compose"/>

</menu>


Observe showAsAction tag.

We can split the action bar's to the bottom of the screen when screen is narrow. This can be achieved by adding a tag in manifest file. Add android:uiOptions="splitActionBarWhenNarrow" tag in the Activity of manifest file. The output will be looking like.




With the uiOptions tag in Manifest file, the complete menu is pushed to bottom. In landscape, considering the real estate available, these UI changes wont be reflected. Menu will be placed on the top in landscape mode.

In Some of the devices, where the menu hard key is present, the menu options with 3 dots will not be shown. The default behavior of the device will override the action bar behavior. In such cases, if you strictly want the action bar behavior, call the below method in onCreate() method of your activity.

private void getOverflowMenu() {

     try {
        ViewConfiguration config = ViewConfiguration.get(this);
        Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
        if(menuKeyField != null) {
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

For the backward compatibility of Action Bar's, refer to the topic ActionBar's with Sherlock API

Related topics :