May 24, 2013

Volley: Easy, Fast Networking for Android - Example

Volley is a library that makes networking for Android apps easier and most importantly, faster. We'll give an overview of how it works, common patterns that work well with it, and a walkthrough of how you can easily load thumbnail images for your ListView from the network in parallel.

Volley can be powerful alternative of AsyncTask. As Android developers, we are spending lots of time to write AsyncTask for ListView and web service calls.  Recently I read awesome article about AsyncTask, I suggest all Android developers to read this article "Dark Side of AsyncTask" by +Fré Dumazy,  AsyncTask is redundant in every project. I hope many developer are agree with me, Thank to Volley framework now we can reduct effort,coding and time to write AsyncTasks.

This article illustrate simple example of Volley library. VolleyTest application fetch JSON feed from Yahoo Pipe and display in ListView.

Step 1: Download/Clone Volley library from git repo

 git clone https://android.googlesource.com/platform/frameworks/volley

Step 2: Create new project in *Android Studio named "VolleyTest"
*Note: This is my first project in Android Studio

Step 3: Copy Volley library source code in "VolleyTest" project, Copying source in our project is safe and easy that's why I copy source of Volley in VolleyTest project. 


Step 4: Add Internet permission in AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kpbird.volleytest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="14" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.kpbird.volleytest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

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

Step 5: Add ListView in activity_main.xml
<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <ListView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/listView"
            android:layout_alignParentTop="true" android:layout_alignParentLeft="true"/>
</RelativeLayout>

Step 6: Create new xml for List row named "row_listview.xml"
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="100dp">

    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Large Text"
            android:id="@+id/txtTitle" android:layout_gravity="left|center_vertical"/>
    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="Medium Text"
            android:id="@+id/txtDesc" android:layout_gravity="left|center_vertical" android:textColor="#929292"
            android:minLines="2" android:ellipsize="end" android:maxLines="2"/>
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:text="Small Text"
            android:id="@+id/txtDate" android:layout_gravity="left|center_vertical" android:textColor="#d6d6d6"/>
</LinearLayout>

Step 7: Add Following code in MainActivity.java file

There are three steps to make web call using Volley
1. Create new Queue Request object from Volley class

private RequestQueue mRequestQueue;
.
.
.
mRequestQueue =  Volley.newRequestQueue(this);

2. Create object of JsonObjectRequest and provide all details like url, http method, listeners for success and error
JsonObjectRequest jr = new JsonObjectRequest(Request.Method.GET,url,null,new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.i(TAG,response.toString());
                parseJSON(response);
                va.notifyDataSetChanged();
                pd.dismiss();
;            }
        },new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i(TAG,error.getMessage());
            }
        });

3. Add JsonObjectRequest to RequestQueue 
mRequestQueue.add(jr);

Following code has regular Adapter, Model class. I took everything in one java file for simplicity, 

Complete Source Code

package com.kpbird.volleytest;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;

public class MainActivity extends Activity {

    private String TAG = this.getClass().getSimpleName();
    private ListView lstView;
    private RequestQueue mRequestQueue;
    private ArrayList<NewsModel> arrNews ;
    private LayoutInflater lf;
    private VolleyAdapter va;
    private ProgressDialog pd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lf = LayoutInflater.from(this);


        arrNews = new ArrayList<NewsModel>();
        va = new VolleyAdapter();

        lstView = (ListView) findViewById(R.id.listView);
        lstView.setAdapter(va);
        mRequestQueue =  Volley.newRequestQueue(this);
        String url = "http://pipes.yahooapis.com/pipes/pipe.run?_id=giWz8Vc33BG6rQEQo_NLYQ&_render=json";
        pd = ProgressDialog.show(this,"Please Wait...","Please Wait...");
        try{
            Thread.sleep(2000);
        }catch(Exception e){

            }
        JsonObjectRequest jr = new JsonObjectRequest(Request.Method.GET,url,null,new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.i(TAG,response.toString());
                parseJSON(response);
                va.notifyDataSetChanged();
                pd.dismiss();
;            }
        },new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i(TAG,error.getMessage());
            }
        });
        mRequestQueue.add(jr);



    }

    private void parseJSON(JSONObject json){
        try{
            JSONObject value = json.getJSONObject("value");
            JSONArray items = value.getJSONArray("items");
            for(int i=0;i<items.length();i++){

                    JSONObject item = items.getJSONObject(i);
                    NewsModel nm = new NewsModel();
                    nm.setTitle(item.optString("title"));
                    nm.setDescription(item.optString("description"));
                    nm.setLink(item.optString("link"));
                    nm.setPubDate(item.optString("pubDate"));
                    arrNews.add(nm);
            }
        }
        catch(Exception e){
            e.printStackTrace();
        }


    }


    class NewsModel{
        private String title;
        private String link;
        private String description;
        private String pubDate;

        void setTitle(String title) {
            this.title = title;
        }

        void setLink(String link) {
            this.link = link;
        }

        void setDescription(String description) {
            this.description = description;
        }

        void setPubDate(String pubDate) {
            this.pubDate = pubDate;
        }

        String getLink() {
            return link;
        }

        String getDescription() {
            return description;
        }

        String getPubDate() {
            return pubDate;
        }

        String getTitle() {

            return title;
        }
    }


    class VolleyAdapter extends BaseAdapter{

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

        @Override
        public Object getItem(int i) {
            return arrNews.get(i);
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            ViewHolder vh ;
           if(view == null){
               vh = new ViewHolder();
               view = lf.inflate(R.layout.row_listview,null);
               vh.tvTitle = (TextView) view.findViewById(R.id.txtTitle);
               vh.tvDesc = (TextView) view.findViewById(R.id.txtDesc);
               vh.tvDate = (TextView) view.findViewById(R.id.txtDate);
               view.setTag(vh);
          }
            else{
               vh = (ViewHolder) view.getTag();
           }

            NewsModel nm = arrNews.get(i);
            vh.tvTitle.setText(nm.getTitle());
            vh.tvDesc.setText(nm.getDescription());
            vh.tvDate.setText(nm.getPubDate());
            return view;
        }

         class  ViewHolder{
            TextView tvTitle;
             TextView tvDesc;
             TextView tvDate;

        }

    }
}

Download Source Code from Github.com https://github.com/kpbird/volley-example
continue reading Volley: Easy, Fast Networking for Android - Example

May 20, 2013

List of Mobile Backend-as-a-Service Providers

Image source : http://www.kinvey.com/images/feature-icons/feature-icon-data.png

Mobile Backend-as-a-Service Providers(MBaaS) - Close Source
  1. Appcelerator Cloud [http://www.appcelerator.com/cloud/]
  2. Parse [https://www.parse.com/]
  3. Kinvey [http://www.kinvey.com/]
  4. StackMob [https://www.stackmob.com/]
  5. Applicasa [http://www.applicasa.com/]
  6. Anypresence [http://www.anypresence.com/]
  7. Appacitive [http://appacitive.com/]
  8. Cloudmine [https://cloudmine.me/]
  9. Scottyapp [http://scottyapp.com/]
  10. API-O-Mat [http://www.apiomat.com/]
  11. APP42 CloudAPI [http://api.shephertz.com/]
  12. Kii [http://www.kii.com/en/technology/kiicloud]
  13. Kumulos [http://www.kumulos.com/]
  14. Feedhenry [http://www.feedhenry.com/]
  15. API Engine [https://apiengine.io/features]
  16. Quickblox [http://quickblox.com/]
  17. KidoZen [http://www.kidozen.com/]
Mobile Backend-as-a-Service Providers(MBaaS) - Open Source
continue reading List of Mobile Backend-as-a-Service Providers

Android shell command : pm - package manager



Use PM command 
1. open terminal
2. Go to <Android SDK directory>/platform-tools
3. execute following command

adb shell pm

Use Android package manager pm
usage: pm [list|path|install|uninstall]
       pm list packages [-f]
       pm list permission-groups
       pm list permissions [-g] [-f] [-d] [-u] [GROUP]
       pm list instrumentation [-f] [TARGET-PACKAGE]
       pm list features
       pm path PACKAGE
       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH
       pm uninstall [-k] PACKAGE
       pm enable PACKAGE_OR_COMPONENT
       pm disable PACKAGE_OR_COMPONENT
       pm setInstallLocation [0/auto] [1/internal] [2/external]

Examples

Install the package com.twitter.android-1.apk from the SD card
pm install /sdcard/com.twitter.android-1.apk
List installed packages that contain the term twitter
pm list packages | grep twitter
Show the install directory of the twitter package
pm path com.twitter.android

Processes

top
Lists all running processes / apps with live updates showing CPU usage, PID,...
ps
Lists all running processes / apps and allows filtering using grep

Examples

ps | grep apps
Lists all running apps on your phone

Mounting

mount -o rw,remount -t "filesystem" "Device" "Mount Point"
Allows you to remount your partitions for write access or to mount images.

Examples

Write access for the root filesystem
mount -o rw,remount -t rootfs /
Write access for your /system partition
mount -o rw,remount -t yaffs2 /dev/block/mtdblock4 /system
Write access for /system using busybox
busybox mount -o remount,rw /system
Mount the contents of myimage.img, viewable in the folder myimage
mount -o loop /sdcard/myimage.img myimage

Other

getprop can show interesting details from the device configuration, such as DNS servers, gateways, GSM details, running services, build parameters, version info etc.

Command Help


ind352:platform-tools indianic$ adb shell pm
usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]
       pm list permission-groups
       pm list permissions [-g] [-f] [-d] [-u] [GROUP]
       pm list instrumentation [-f] [TARGET-PACKAGE]
       pm list features
       pm list libraries
       pm list users
       pm path PACKAGE
       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]
                  [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]
                  [--originating-uri <URI>] [--referrer <URI>] PATH
       pm uninstall [-k] PACKAGE
       pm clear [--user USER_ID] PACKAGE
       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT
       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT
       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT
       pm grant PACKAGE PERMISSION
       pm revoke PACKAGE PERMISSION
       pm set-install-location [0/auto] [1/internal] [2/external]
       pm get-install-location
       pm set-permission-enforced PERMISSION [true|false]
       pm trim-caches DESIRED_FREE_SPACE
       pm create-user USER_NAME
       pm remove-user USER_ID
       pm get-max-users

pm list packages: prints all packages, optionally only
  those whose package name contains the text in FILTER.  Options:
    -f: see their associated file.
    -d: filter to only show disbled packages.
    -e: filter to only show enabled packages.
    -s: filter to only show system packages.
    -3: filter to only show third party packages.
    -i: see the installer for the packages.
    -u: also include uninstalled packages.

pm list permission-groups: prints all known permission groups.

pm list permissions: prints all known permissions, optionally only
  those in GROUP.  Options:
    -g: organize by group.
    -f: print all information.
    -s: short summary.
    -d: only list dangerous permissions.
    -u: list only the permissions users will see.

pm list instrumentation: use to list all test packages; optionally
  supply <TARGET-PACKAGE> to list the test packages for a particular
  application.  Options:
    -f: list the .apk file for the test package.

pm list features: prints all features of the system.

pm list users: prints all users on the system.

pm path: print the path to the .apk of the given PACKAGE.

pm install: installs a package to the system.  Options:
    -l: install the package with FORWARD_LOCK.
    -r: reinstall an exisiting app, keeping its data.
    -t: allow test .apks to be installed.
    -i: specify the installer package name.
    -s: install package on sdcard.
    -f: install package on internal flash.
    -d: allow version code downgrade.

pm uninstall: removes a package from the system. Options:
    -k: keep the data and cache directories around after package removal.

pm clear: deletes all data associated with a package.

pm enable, disable, disable-user: these commands change the enabled state
  of a given package or component (written as "package/class").

pm grant, revoke: these commands either grant or revoke permissions
  to applications.  Only optional permissions the application has
  declared can be granted or revoked.

pm get-install-location: returns the current install location.
    0 [auto]: Let system decide the best location
    1 [internal]: Install on internal device storage
    2 [external]: Install on external media

pm set-install-location: changes the default install location.
  NOTE: this is only intended for debugging; using this can cause
  applications to break and other undersireable behavior.
    0 [auto]: Let system decide the best location
    1 [internal]: Install on internal device storage
    2 [external]: Install on external media

pm trim-caches: trim cache files to reach the given free space.

pm create-user: create a new user with the given USER_NAME,
  printing the new user identifier of the user.

pm remove-user: remove the user with the given USER_IDENTIFIER,
  deleting all data associated with that user
Source : http://android.stackexchange.com/questions/11052/what-useful-android-shell-commands-do-you-know


continue reading Android shell command : pm - package manager

May 10, 2013

Tips: Android design pattern

Design Pattern, design pattern is a general reusable solution to a commonly occurring problem, In case of Android, I personally feel that existing design patterns like MVC, Abstract Factory,Singleton,etc. are not fit with the Android. Most of design patterns was evolved before the era of Android/Mobile. I think that code should be simple and optimise, does not matter which design pattern you are using. 

In this article I am going to explain few rules/pattern which I am following in my projects.



1. Package Structure
         src 
             com.client.app                   - contain Application class only
             com.client.app.views           - contain all activities
             com.client.app.fragments    - contain all fragments
             com.client.app.webservice   - contain all web services
             com.client.app.adapters      - contain all adapters
             com.client.app.db              - contain all db related classes
             com.client.app.models        - contain all models
             com.client.app.utils            - contain utility/misc classes
             com.client.app.widgets        - contain extended/custom views
             com.client.app.services       - contain all services
             com.client.app.animation     - contain all animations

2. Naming convention for Xml files

  • activity_<ACTIVITY NAME>.xml - for all activities
  • dialog_<DIALOG NAME>.xml  - for all custom dialogs
  • row_<LIST_NAME>.xml - for custom row for listview
  • fragment_<FRAGMENT_NAME>.xml - for all fragments
3. Naming convention for component/widget in xml files.

  • all component for x activity must be start with activity name
  • all component should have prefix or short name like btn for button
  • For example,name for login activity component should be like following.
    • activity_login_btn_login
    • activity_login_et_username
    • activity_login_et_password
  • Short name of major components
    • Button - btn
    • EditText - et
    • TextView - tv
    • Checkbox - chk
    • RadioButton - rb
    • ToggleButton - tb
    • Spinner - spn 
    • Menu - mnu
    • ListView - lv
    • GalleryView - gv
    • LinearLayout -ll
    • RelativeLayout - rl
4.  Reference links related to Android design pattern / architecture




           

continue reading Tips: Android design pattern

May 6, 2013

Tips to speedup Eclipse IDE

1. Disable Validation : Open Preferences, search validation, select general->validation, disable all validation, click on apply and ok button.


2. Disable Startup Items : Open Preferences, search startup, select general->startup and shutdown, disable plug-ins which you don't require on startup, click on apply and ok button.  


3. Disable Spell check : Open preferences, search spell, select general->Editors->Text Editors->Spelling, uncheck enable spell checking, click apply and ok button.

4. Close inactive/ non-working projects
5. Change/create new workspace after 10 or 15 projects
6. Increase Heap size : http://wiki.eclipse.org/FAQ_How_do_I_increase_the_heap_size_available_to_Eclipse%3F
7.  Disable Build Automatically 
8. Remove Unwanted Plug-ins
  
continue reading Tips to speedup Eclipse IDE