Quantcast
Channel: The Code of a Ninja
Viewing all 100 articles
Browse latest View live

FbAlbumPreview jQuery Plugin

$
0
0
Hi there guys! Today I want to share with you a jQuery plugin that I made. This jQuery plugin will enable your users to preview your web albums instantly. My inspiration here is the Facebook albums, if you have a Facebook account (I’m sure you have, haha!) and wanted to view the list of albums, you can experience this functionality:


For me, above is a very simple Facebook feature and yet, it’s awesome. It is very convenient for a user to have an album preview just by doing a hover.

If you want the live preview or download the code of my plugin:

 

Here’s our index.html code:

<html>
    <head>
        <title>FB Album Preview jQuery Plugin by http://codeofaninja.com/</title>
        <!-- add some styles -->
        <linkrel='stylesheet'type='text/css'href='css/style.css'/>
       
    </head>
<body>
<h3>
    Demo of FB Album Preview jQuery Plugin by <ahref='http://codeofaninja.com/'>The Code Of A Ninja</a>
</h3>

<!--
    -You can generate all these HTML and JS codes using your server side script
    -The number of photos or thumbnails to be previewed depends on you
-->
<divid='mainContent'>

    <!-- album # 1 -->
    <divclass='albumDetails'>
        <divclass="fbAlbum">
            <!-- the first image is the album cover photo -->
            <imgclass="active"src="images/1.jpg"/>
            <imgsrc="images/2.jpg"/>
            <imgsrc="images/3.jpg"/>
            <imgsrc="images/4.jpg"/>
            <imgsrc="images/5.jpg"/>
        </div>
        <divclass='albumTitle'><ahref=''>Profile Picture</a></div>
        <divclass='photosNum'>5 photos</div>
    </div>
   
    <!-- album # 2 -->
    <divclass='albumDetails'>
        <divclass="fbAlbum">
            <!-- the first image is the album cover photo -->
            <imgclass="active"src="images/6.jpg"/>
            <imgsrc="images/7.jpg"/>
            <imgsrc="images/8.jpg"/>
        </div>
        <divclass='albumTitle'><ahref=''>Mobile Uploads</a></div>
        <divclass='photosNum'>3 photos</div>
    </div>
   
    <!-- album # 3 -->
    <divclass='albumDetails'>
        <divclass="fbAlbum">
            <!-- the first image is the album cover photo -->
            <imgclass="active"src="images/9.jpg"/>
            <imgsrc="images/10.jpg"/>
            <imgsrc="images/11.jpg"/>
            <imgsrc="images/12.jpg"/>
        </div>
        <divclass='albumTitle'><ahref=''>Wall Photos</a></div>
        <divclass='photosNum'>4 photos</div>
    </div>
   
</div>

<!-- include jQuery library and our FB album preview plugin -->
<scriptsrc="js/jquery.min.js"></script>
<scriptsrc="js/fb.album.preview.js"></script>

<!-- this is how we're gonna use the plugin -->
<scripttype='text/javascript'>
$(document).ready(function(){
    // since all albums images container are under the class 'fbAlbum',
    // that's what we are gonna user as the selector
    $('.fbAlbum').FbAlbumPreview();
});
</script>

</body>
</html>

Our CSS code:

body{
    font-family:'helvetica neue', helvetica, arial,sans-serif;
}

.fbAlbum{
    position:relative;
    width:206px;
    height:206px;
    cursor:pointer;
}

.fbAlbum IMG {
    position:absolute;
    top:0;
    left:0;
    z-index:8;
    width:206px;
    height:206px;
}

.fbAlbum IMG.active{
    z-index:10;
}

.fbAlbum IMG.last-active{
    z-index:9;
}
           
.albumDetails{
    float:left;       
    width:206px;
    height:270px;
    margin:20px;
}

.albumTitle{
    font-family:'helvetica neue', helvetica, arial,sans-serif;
    white-space:nowrap;
    font-weight:bold;
    font-size:14px;
    padding:10px05px0;
    text-align:center;
   
}

.albumTitle a{
    text-decoration:none;
    color:#3B5998;
}

.albumTitle a:hover{
    text-decoration:underline;
}

.photosNum{
    color:gray;
    line-height:19px;
    font-size:11px;
    text-align:center;
    font-family:'lucida grande', tahoma, verdana, arial,sans-serif;
}

#mainContent{
    width:750px;
    margin:0auto;
    margin-top:100px;
}

.clearb{
    clear:both;
}

Customization code: Yes, you can supply values to customize the view and fade speed effect of this plugin. The default is viewSpeed = 1000 and fadeSpeed = 500. viewSpeed should always be greater than fadeSpeed.


    $('.fbAlbum').FbAlbumPreview({
        viewSpeed:800,
        fadeSpeed:400
    });

viewSpeed - refers to how long the user can take a look at the thumbnail image
fadeSpeed - how long the transition (fade effect) from one image to another will take place

FbAlbumPreview jQuery plugin Code (compressed)

(function(a){a.fn.FbAlbumPreview=function(b){var c=a.extend({viewSpeed:1e3,fadeSpeed:500},b);return this.each(function(){var b;var d=c.fadeSpeed;var e=false;a(this).hover(function(){var f=a(this);b=setInterval(function(){f.find("IMG").show();var a=f.find("IMG.active");if(a.length==0){a=f.find("IMG:last")}var b=a.next().length?a.next():f.find("IMG:first");a.addClass("last-active");b.css({opacity:0}).addClass("active").animate({opacity:1},d,function(){a.removeClass("active last-active");e=true})},c.viewSpeed)},function(){clearInterval(b);if(e==true){var c=a(this);c.find("img").hide();c.find("IMG.active").removeClass("active");var f=c.find("IMG:first").fadeOut(d).fadeIn(d).addClass("active");e=false}})})}})(jQuery)

Android SharedPreferencesManager Class

$
0
0
Today I'm going to talk about how I manage Android SharedPreferences in my application. Not a long time ago, I posted about SharedPreferences, so you can take a look back if you don't have any idea yet about SharedPreferences.

I basically used the setter and getter methods, which has been regarded as "evil" by many developers. I'm just a self thought programmer, I'm open to any suggestions by you guys especially if you are an advanced developer or knows a better implementation.

I feel convenient using this class, you can instantly write and read your SharedPreference values, especially if you choose to store several SharedPref values for your app. You just have to pass the context and then bam! You can use it even for a non-activity class.

How To Use?


Just the common way, instantiate:

    // make it a member variable
    SharedPreferencesManager SharedPrefMgr;
   
    @Override
    publicvoid onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // create an instance
        SharedPrefMgr =new SharedPreferencesManager(this);
       
        // ...

Write:

//just an example
String username ="ninjazhai";
SharedPrefMgr.setUsername(username);

Read:

String curr_username = SharedPrefMgr.getUsername();

SharedPreferencesManager Class


Just an example of my SharefPreferencesManager Class.

importandroid.content.Context;
importandroid.content.SharedPreferences;


publicclass SharedPreferencesManager {

    Context mContext;

    SharedPreferences settings;
    SharedPreferences.Editor editor;

    public SharedPreferencesManager(Context mContext){

        settings = mContext.getSharedPreferences("my_shared_prefs", 0);
        editor = settings.edit();

    }

    // ----- firstname -----
    publicString getFirstname(){
        return settings.getString("firstname", null);
    }

    publicvoid setFirstname(String firstname){
        editor.putString("firstname", firstname);
        editor.commit();
    }
   
    // ----- lastname -----
    publicString getLastname(){
        return settings.getString("lastname", null);
    }

    publicvoid setLastname(String lastname){
        editor.putString("lastname", lastname);
        editor.commit();
    }
   
    // ----- username -----
    publicString getUsername(){
        return settings.getString("username", null);
    }

    publicvoid setUsername(String username){
        editor.putString("username", username);
        editor.commit();
    }
   
    // ----- folder name -----
    publicString getFolderName(){
        return settings.getString("folder_name", null);
    }

    publicvoid setFolderName(String folder_name){
        editor.putString("folder_name", folder_name);
        editor.commit();
    }
   
   
    // ----- debug mode -----
    publicboolean getDebugMode(){
        return settings.getBoolean("debug_mode", false);
    }

    publicvoid setDebugMode(boolean debug_mode){
        editor.putBoolean("debug_mode", debug_mode);
        editor.commit();
    }
   
    // ... you can add more here ...
   
}

Instant Android Webview Code

$
0
0
Hi guys! Today I want to share a class I created to help me whenever I have a WebView activity in my app. I simply call it a WebView helper class. The main benefit of having a class like this for your web views is that, you won't have to specify the same code over and over again for each of your web view activities. You are re-using the web view code that shortens and make our code look cleaner. You can just use one settings for all your web views, and at the same time, you can add any JavaScript interfaces and specify the URL to be loaded.

What loading pages will look like.

How to use? 

For the sake of starting android programmers, I will include the whole code of our MainActivity:

packagecom.codeofaninja.app;
importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.view.Menu;
importandroid.webkit.WebView;

publicclass MainActivity extends Activity {

     WebView web;
   
    @Override
    publicvoid onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
     
        // initialize our helper class
        // then call the webview() methods with our context as parameter (MainActivity.this)
        web =new WebViewHelper().webview(MainActivity.this);
     
        // specify the url we want to load
        web.loadUrl("http://codeofaninja.com/");
     
        // you can add JavaScript interface like this:
        // web.addJavascriptInterface(new YourJsInterfaceClass(), "Android");

        // set web as content view
        setContentView(web);
     
    }
 
}

Our WebViewHelper.java code:

packagecode.of.a.ninja.Utils;

importandroid.app.ProgressDialog;
importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.webkit.WebChromeClient;
importandroid.webkit.WebSettings;
importandroid.webkit.WebView;
importandroid.webkit.WebViewClient;
importandroid.webkit.WebSettings.RenderPriority;
importandroid.widget.Toast;

publicclass WebViewHelper {

    private ProgressDialog mProgressDialog;

    //make it final so it will be accessible to setWebViewClient
    public WebView webview(finalContext mContext){

        // progress dialog
        mProgressDialog =new ProgressDialog(mContext);

        // new webview
        WebView web =new WebView(mContext);

        // web settings
        WebSettings webSettings = web.getSettings();

        // false
        webSettings.setSavePassword(false);
        webSettings.setSaveFormData(false);
        webSettings.setAppCacheEnabled(false);

        // true
        webSettings.setJavaScriptEnabled(true);
        webSettings.setSupportZoom(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setUseWideViewPort(true);

        // other
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        webSettings.setRenderPriority(RenderPriority.HIGH);

        web.setWebChromeClient(new WebChromeClient(){
            publicvoid onProgressChanged(WebView view, int progress){
                //show the user progress percentage
                mProgressDialog.setMessage("Loading... "+ progress +"%");
            }
        });

        web.setWebViewClient(new WebViewClient(){

            publicvoid onReceivedError(WebView view, int errorCode,
                    String description, String failingUrl){

                //if there's an error loading the page, make a toast
                Toast.makeText(mContext, description +".", Toast.LENGTH_SHORT)
                        .show();

            }

            publicvoid onPageFinished(WebView view, String url){
                //after loading page, remove loading page
                mProgressDialog.dismiss();
            }

            @Override
            publicvoid onPageStarted(WebView view, String url, Bitmap favicon){
                // TODO Auto-generated method stub
                super.onPageStarted(view, url, favicon);

                //on page started, show loading page
                mProgressDialog.setCancelable(false);
                mProgressDialog.setMessage("Loading...");
                mProgressDialog.show();

            }

        });

        // return the web view
        return web;
    }
}

That's it! Enjoy using our web view helper class!

Android Camera Code

$
0
0
Today we are going to do a code that can enable your android application to capture images using the device camera. In this example code, we will have:
  1. A "Take Picture" button on our main activity, when the user clicks it, the device camera will be shown that will enable your user the take a picture.
  2. After taking a picture, the preview of the image will be shown with options to "Save" or "Discard" the image. 
  3. If the user tapped "Save", the image will be saved on the directory we specified in our code, else, if the user tapped "Discard", the device camera will be shown again.
  4. If the user saved the image, he will be asked if he wants to take another picture.
Using Device Camera To Get Pictures For Your App

You may download the code here:


Our MainActivity.java code - This activity will show our "Take Picture" button.

packagecom.example.camerahelper;

importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.view.View;

publicclass MainActivity extends Activity {

    Context mContext;

    @Override
    publicvoid onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContext = MainActivity.this;

        View.OnClickListener handler =newView.OnClickListener(){
            publicvoid onClick(View v){

                switch(v.getId()){

                case R.id.takePicture:
                    // go to camera activity
                    Intent nextActivity =new Intent(mContext,
                            CameraActivity.class);
                    startActivity(nextActivity);
                    break;

                }
            }
        };

        findViewById(R.id.takePicture).setOnClickListener(handler);

    }

}

Our res/layout/activity_main.xml - The XML layout file for our MainActivity.

<?xmlversion="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/widget29"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">

    <Button
       android:id="@+id/takePicture"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_centerHorizontal="true"
       android:layout_centerVertical="true"
       android:text="@string/take_picture"/>

</RelativeLayout>

Our CameraActivity.java - This code does almost all the operations from starting the device camera to saving the image to specified directory.

packagecom.example.camerahelper;

importjava.io.File;

importandroid.app.Activity;
importandroid.app.AlertDialog;
importandroid.content.DialogInterface;
importandroid.content.DialogInterface.OnClickListener;
importandroid.content.Intent;
importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.provider.MediaStore;
importandroid.util.Log;
importandroid.widget.Toast;

publicclass CameraActivity extends Activity {

    privatestaticfinalString LOG_TAG ="CameraActivity.java";
    privatestaticfinalint IMAGE_CAPTURE =0;

    /** Called when the activity is first created. */
    @Override
    publicvoid onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);

        try{

            // intent to start device camera
            Intent intent =new Intent("android.media.action.IMAGE_CAPTURE");

            // you can also create your own filename or path
            String fileName ="codeofaninja_app";

            // where do you want to save the images
            String path =Environment.getExternalStorageDirectory()+"/"
                    + fileName +".jpg";

            File file =newFile(path);

            // if the file name already exists, append __x on the file name
            int x =2;
            while(file.exists()){

                path =Environment.getExternalStorageDirectory()+"/"
                        + fileName +"__"+ x +".jpg";
                file =newFile(path);

                x++;
            }

            Uri outputFileUri = Uri.fromFile(file);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

            // 0, this code will be returned in onActivityResult() when the
            // activity exits.
            startActivityForResult(intent, 0);

        }catch(NullPointerException e){
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }

    }

    // activity exits
    protectedvoid onActivityResult(int requestCode, int resultCode, Intent data){
        try{
            if(requestCode == IMAGE_CAPTURE){
                if(resultCode == RESULT_OK){

                    Log.v(LOG_TAG, "Picture taken.");

                    // delete last image from dcim
                    if(!deleteLastSavedDcimImage()){
                        Log.v(LOG_TAG,"Unable to delete last saved image in /Camera/DCIM/");
                    }

                    // ask if the user want's to take another picture
                    takeAnother();

                }else{
                    // you can specify any message here
                    // or just remove it
                    Toast.makeText(getBaseContext(),
                            "Error: Result code is not RESULT_OK.",
                            Toast.LENGTH_SHORT).show();

                }
            }else{
                // you can specify any message here
                // or just remove it
                Toast.makeText(getBaseContext(),
                        "Error: Request code is not IMAGE_CAPTURE.",
                        Toast.LENGTH_SHORT).show();
            }

        }catch(NullPointerException e){
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    @Override
    publicvoid onBackPressed(){
        CameraActivity.this.finish();
    }

    publicvoid takeAnother(){
        try{

            new AlertDialog.Builder(this).setTitle("The Code Of A Ninja")
                    .setMessage("Do you want to take another picture?")
                    .setPositiveButton("YES", new OnClickListener(){
                        publicvoid onClick(DialogInterface arg0, int arg1){
                            arg0.dismiss();

                            Intent nextActivity =new Intent(
                                    CameraActivity.this, CameraActivity.class);
                            CameraActivity.this.finish();
                            startActivity(nextActivity);

                        }
                    })

                    .setNegativeButton("NO", new OnClickListener(){
                        publicvoid onClick(DialogInterface arg0, int arg1){

                            arg0.dismiss();

                            Toast.makeText(CameraActivity.this,
                                    "Done taking picture.", Toast.LENGTH_LONG)
                                    .show();

                            // go to main activity
                            CameraActivity.this.finish();

                        }
                    }).show();

        }catch(NullPointerException e){
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    // since our code also saves the taken images to DCIM/Camera folder of the
    // device, we have to delete it there so that the image will be saved
    // only to the directory we have specified.
    privateboolean deleteLastSavedDcimImage(){

        Log.v(LOG_TAG, "Deleting late image from DCIM.");

        boolean success =false;

        try{

            // list the images in the device /DCIM/Camera directory
            File[] images =newFile(Environment.getExternalStorageDirectory()
                    +"/DCIM/Camera").listFiles();
            File lastSavedImage = images[0];
            int imagesLen = images.length;
           
            //loop and check for the last modified image to get the last save image
            for(int i =1; i < imagesLen;++i){
                if(images[i].lastModified()> lastSavedImage.lastModified()){
                    lastSavedImage = images[i];
                }
            }

            //then delete the last saved image
            success =newFile(lastSavedImage.toString()).delete();

        }catch(NullPointerException e){
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }

        return success;
    }
}

Our res/layout/camera.xml code - XML I used for our CameraActivity.java activity

<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical">

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

</LinearLayout>

The AndroidManifest.xml code - This will give us permission to use the device camera hardware.

<manifestxmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.camerahelper"
   android:versionCode="1"
   android:versionName="1.0">

    <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permissionandroid:name="android.permission.CAMERA"/>

    <uses-featureandroid:name="android.hardware.camera"/>
    <uses-featureandroid:name="android.hardware.camera.autofocus"/>

    <uses-sdk
       android:minSdkVersion="8"
       android:targetSdkVersion="15"/>

    <application
       android:icon="@drawable/ic_launcher"
       android:label="@string/app_name"
       android:theme="@style/AppTheme">
        <activity
           android:name=".MainActivity"
           android:label="@string/title_activity_main">
            <intent-filter>
                <actionandroid:name="android.intent.action.MAIN"/>

                <categoryandroid:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activityandroid:name=".CameraActivity">
        </activity>
    </application>

</manifest>

Some output screenshots:




JavaScript Array CRUD Example

$
0
0
Our code for today will give us example on how to Create, Read, Update and Delete (CRUD) items in a JavaScript array. This technique will give you full control over the fields and values of each array item. Example use of this code is when you have long rows of input elements and wanted to detect only the elements with inputted values, get their id, value and other related information. You won't have to loop through all the input elements to check if there are inputted values. This is because, you can instantly add an item to the array if the value was inputted, edit it when the value were changed, delete it when the value were removed and then read it for posting or later use. We can achieve better performance. Here is a video demo:



CRUD

Our index.php code - here you can see the our JavaScript CRUD functions (with some jQuery help) and sample HTML.

<html>
    <head>
        <title>JS Array CRUD - http://codeofaninja.com</title>
    </head>
   
<body>

<!--
    -example row of items
    -id is the item number
    -common classname
-->
Item1<input type='text' id='1'class='item'/><br />
Item2<input type='text' id='2'class='item'/><br />
Item3<input type='text' id='3'class='item'/><br />
Item4<input type='text' id='4'class='item'/><br />
Item5<input type='text' id='5'class='item'/><br />

<br />
<br />

<!-- display the operations here -->
<b>Actions:</b>
<div id='status'></div>

<br />

<!-- display the array length and items -->
<b>All Items:</b>
<div id='results'></div>

<!-- include the jquery -->
<script type='text/javascript' src='jquery.min.js'></script>

<script type='text/javascript'>
    // initialize array as global variable
    var items =[];
   
    $(document).ready(function(){
   
        //we use the jquery blur event
        $('.item').blur(function(){
       
            //in this example, the item id is the id attribute of the element
            var item_id = $(this).attr('id');
           
            //item value is the inputtedvalue
            var item_value = $(this).val();
           
            //then process the item
            process_item(item_id,item_value);
        });
       
    });
   
    // ------------ functions [START] ------------

    // process item, usually based in item id
    function process_item(item_id,item_value){
       
        if(item_value==""){
            //if item value is empty, delete from the array
            delete_item(item_id);
        }elseif(checkIfExists(item_id)){
            //search if item_id exists in the array
            //if item exists, edit it
            edit(item_id,item_value);
        }elseif(!checkIfExists(item_id)){
            //if item does not exist, add it
            add(item_id,item_value);
        }
       
        //read the items
        showAllItems();
    }
   
    // ADD
    function add(item_id,item_value){
        items.push({
            "item_id": item_id,
            "item_value": item_value
        });
        $("#status").text("Successfully added.");
    }

    // EDIT
    function edit(item_id,item_value){
       
        //delete first
        items.remove("item_id", item_id);
       
        //then add again
        items.push({
            "item_id": item_id,
            "item_value": item_value
        });
        $("#status").text("successfully edited.");
           
    }
   
    // DELETE
    function delete_item(item_id){
        items.remove("item_id", item_id);
        $("#status").text("Successfully deleted.");
    }
   
    // READ
    function showAllItems(){
       
        //clear results text
        $("#results").text("");
       
        var arr_len = items.length;
       
        // display also the array length
        $("#results").append("Array len: "+ arr_len+"<br />");
       
        //loop through the array to read the items
        for(var x=0; x<arr_len; x++){
            var item_id = items[x]['item_id'];
            var item_value = items[x]['item_value'];
           
            //append to results div to display
            $("#results").append("item_id: "+ item_id +" >>> item_value: "+ item_value +"<br />");
        }
    }
   
    function checkIfExists(check_item_id){
       
        //get the array length first
        var arr_len = items.length;
       
        //search the array
        //there might be another way
        for(var x=0; x<arr_len; x++){
            var item_id = items[x]['item_id'];
            var item_value = items[x]['item_value'];
           
            if(check_item_id==item_id){
                //it means the item exists
                returntrue;
            }
        }
       
        returnfalse;
    }
   
    //needs a remove function
    Array.prototype.remove=function(name, value){
        array =this;
        var rest = $.grep(this,function(item){
            return(item[name]!= value); 
        });

        array.length= rest.length;
        $.each(rest,function(n, obj){
            array[n]= obj;
        });
    };
    // ------------ functions [END] ------------
</script>

</body>
</html>

Convert to JSON

You can also convert the array to a JSON this way:

Add the json2.js file from here.

<script type='text/javascript' src='json2.js'></script>

...and do this

var json_str= JSON.stringify(items);

Posting the Array

If you want to post the resulting array..

1. Prepare the PHP file that will receive the post value. I created get_post.php with the code:

<?php
//just to display raw values
echo"<pre>";
    print_r($_POST);
echo"</pre>";

//access the values
foreach($_POST['items']as$item){
    echo$item['item_id'].":".$item['item_value']."<br />";
}
?>

2. Add a button and a new div area to our index.php

The button:

<input type='button' value='Post Array' id='post'/>

Div area where we can see the posted values..

<!-- display the posted items value -->
<b>Posted Items:</b>
<div id='postedItems'></div>

3. Clicking the post array button will show the posted value to postedItems div.

$('#post').click(function(){
    $.ajax({
        url:"get_post.php",
        data:{'items': items},
        type:'post',
        success:function(data){
            $('#postedItems').append(data);
        }
    });
});

The value posted to get_post.php look like this:

Array
(
    [items]=>Array
        (
            [0]=>Array
                (
                    [item_id]=>1
                    [item_value]=> john
                )

            [1]=>Array
                (
                    [item_id]=>3
                    [item_value]=> michael
                )

        )

)

If you want to download the code or see the live demo:

Android libphonenumber Example

$
0
0
Today I want to show you a simple example code on how to use a very useful library called libphonenumber, a phone number handling library from Google. It can validate the correct number format for your country. In this example we're using PH (Philippines) as country code. It is optimized for running on smartphones, and is used by the Android framework since 4.0 (Ice Cream Sandwich). Phone number validation is essential for your app so that you can get useful and sound phone numbers from your loyal users. Any verification code, messages or greetings that you want to send them will have lower chances of being missed.

Example of a valid cellphone number.

You can download the code here:

Online demo here.

Step 1

Download the latest JAR file here. As of this writing, I got libphonenumber-5.2v1.5.jar

Step 2

Copy the JAR file in the libs folder of your project.

Android libphonenumber Example
Click to enlarge

Step 3

Add the JAR on your project. Go to Properties > Java Build Path > Libraries Tab > Click Add Jars.. Button > Browse the JAR file on you libs and click OK. This is what it should look like:

Click to enlarge.

Step 4

Our sample XML layout file (activity_main.xml) will have the following code:

<RelativeLayoutxmlns: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">

    <EditText
       android:id="@+id/phoneNumberEditText"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_alignParentTop="true"
       android:ems="10"
       android:inputType="phone">

        <requestFocus/>
    </EditText>

    <Button
       android:id="@+id/validateButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_below="@+id/phoneNumberEditText"
       android:text="Validate Phone Number"/>

</RelativeLayout>

Step 5

Our main activity will have the following code:

packagecom.example.libphonenumber;

importcom.google.i18n.phonenumbers.NumberParseException;
importcom.google.i18n.phonenumbers.PhoneNumberUtil;
importcom.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
importcom.google.i18n.phonenumbers.Phonenumber.PhoneNumber;

importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.view.View;
importandroid.widget.EditText;
importandroid.widget.Toast;

publicclass MainActivity extends Activity {

    @Override
    publicvoid onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try{
            // so that we can get the inputted phone number
            final EditText et =(EditText) findViewById(R.id.phoneNumberEditText);

            View.OnClickListener handler =newView.OnClickListener(){
                publicvoid onClick(View v){
                   
                    switch(v.getId()){

                    // clicking the validate button
                    case R.id.validateButton:

                        // get the inputted phone number
                        String phoneNumber = et.getText().toString();
                       
                        // On our country, people are used to typing 7 (landline) or 11 (cellphone) digit numbers
                        // To make it 7 digit numbers valid, I have to prepend "02"
                        if(phoneNumber.length()==7){
                            phoneNumber ="02"+ phoneNumber;
                        }

                        // Use the library's functions
                        PhoneNumberUtil phoneUtil = PhoneNumberUtil
                                .getInstance();
                        PhoneNumber phNumberProto =null;

                        try{

                            // I set the default region to PH (Philippines)
                            // You can find your country code here http://www.iso.org/iso/country_names_and_code_elements
                            phNumberProto = phoneUtil.parse(phoneNumber, "PH");

                        }catch(NumberParseException e){
                            // if there's any error
                            System.err
                                    .println("NumberParseException was thrown: "
                                            + e.toString());
                        }

                        // check if the number is valid
                        boolean isValid = phoneUtil
                                .isValidNumber(phNumberProto);

                        if(isValid){

                            // get the valid number's international format
                            String internationalFormat = phoneUtil.format(
                                    phNumberProto,
                                    PhoneNumberFormat.INTERNATIONAL);

                            Toast.makeText(
                                    getBaseContext(),
                                    "Phone number VALID: "+ internationalFormat,
                                    Toast.LENGTH_SHORT).show();

                        }else{

                            // prompt the user when the number is invalid
                            Toast.makeText(
                                    getBaseContext(),
                                    "Phone number is INVALID: "+ phoneNumber,
                                    Toast.LENGTH_SHORT).show();

                        }

                        break;

                    }
                }
            };

            // we will set the listeners
            findViewById(R.id.validateButton).setOnClickListener(handler);

        }catch(NullPointerException e){
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }

    }

}

Sample Output: (I felt like my phone is too small so I tested it on my tablet haha!)

An example of a valid land line number.

Example of an invalid land line number.

Example of an invalid cellphone number.
That's it! Happy New Year guys! :)

Working with Text Files in Android

$
0
0
Today we are going to code about a sample app with some operations I usually play with text files in my Android applications. These operations would include creating, reading, updating,and deleting text files. I find these operations really useful when I have to store some data temporarily, creating some log files, or store some actual content just like what evernote does, see screenshot below.

create, read, update, delete text files in android
Click to enlarge. content.enml is basically a text/xml file.

For apps like Evernote, storing some user content data on the device disk or sdcard is okay, some reason include, the device is a personal property, it is always with you. Another reason is, the data is "syncable". If you think you lost some data in the device (like accidental file deletion), you can always simply sync and your data will come back to life in your device. I love cloud computing!

Below is the code download, basic CRUD codes and a Sample Application.


Sample Application


create, read, update, delete text files in android
Click to enlarge.

In this sample application, when a user clicked a button:

  • Create Text File - a folder in your sdcard will be created with an empty text file in it (sdcard/MikeDalisayFolder/coan_log_file.txt)
  • Read Text File - the contents of coan_log_file.txt text file will be shown in the screen, you should click the update text file button first so it will have contents.
  • Update Text File - it will update our text file with two lines of text.
  • Delete Text File - it will delete our text file, of course. :)

We will use a TextFileHelper class I created. I believe you can see more useful techniques here like code re-usability and validation.

src/com.your.package/TextFileHelper.java code - This class contains our text file CRUD codes.

package com.example.textfilesexample;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

import android.content.Context;
import android.widget.Toast;

/*
 * This class is for text file CRUD.
 * You can just make flashMessage() a comment if you do not need it.
 */

public class TextFileHelper {

    // context is used for toasts
    Context mContext;

    /*
     * Constructor
     */

    public TextFileHelper(Context mContext) {
        this.mContext = mContext;
    }

    /*
     * Create a text file.
     */

    public void createTextFile(String actualFile) {
        try {

            File file = new File(actualFile);

            if (file.exists()) {
                flashMessage("Text file already exists.");
            } else {

                // create the text file
                if (file.createNewFile()) {
                    flashMessage("Text file was created.");
                } else {
                    flashMessage("Unable to create text file.");
                }

            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Read a text file.
     */

    public String readTextFile(String actualFile) {

        String contents = "";

        try {

            // Get the text file
            File file = new File(actualFile);

            // check if file is not empty
            if (file.exists() && file.length() != 0) {

                // read the file to get contents
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line;

                while ((line = br.readLine()) != null) {
                    // store the text file line to contents variable
                    contents += line + "\n";
                }

            } else {
                flashMessage("Unable to read. File may be missing or empty.");
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return contents;
    }

    /*
     * Update a text file.
     */

    public void updateTextFile(String actualFile, String contents) {
        try {

            File textFile = new File(actualFile);

            if (textFile.exists()) {

                // set to true if you want to append contents to text file
                // set to false if you want to remove preivous content of text
                // file
                FileWriter textFileWriter = new FileWriter(textFile, false);

                BufferedWriter out = new BufferedWriter(textFileWriter);

                // create the content string
                String contentString = new String(contents);

                // write the updated content
                out.write(contentString);
                out.close();

                flashMessage("File was updated.");

            } else {
                flashMessage("Cannot update. File does not exist.");
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Delete a text file.
     */

    public void deleteTextFile(String actualFile) {
        try {

            File file = new File(actualFile);

            if (file.exists()) {

                if (file.delete()) {
                    flashMessage("Text file was deleted!");
                } else {
                    flashMessage("Unable to delete text file.");
                }

            } else {
                flashMessage("Unable to delete. File does not exist.");
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Method to create path where our text file will be created.
     */

    public void createPath(String filePath) {
        try {

            File file = new File(filePath);

            if (file.isDirectory()) {
                flashMessage("Path exists.");
            }

            // create the directory
            else {
                if (file.mkdirs()) {
                    flashMessage("Path was created.");
                } else {
                    flashMessage("Unable to create path.");
                }

            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Just an extra method for displaying toasts.
     */

    public void flashMessage(String customText) {
        try {

            Toast.makeText(mContext, customText, Toast.LENGTH_SHORT).show();

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}


src/com.your.package/MainActivity.java code

packagecom.example.textfilesexample;

importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.view.View;
importandroid.widget.TextView;
importandroid.app.Activity;

publicclass MainActivity extends Activity {

    // our TextFileHelper
    TextFileHelper TextFileH;

    // where our text file will be created
    String filePath =Environment.getExternalStorageDirectory()+"/MikeDalisayFolder/";
   
    // name of our text file
    String fileName ="coan_log_file.txt";
   
    // filePath and fileName combined
    String actualFile = filePath + fileName;
   
    TextView contentsTextView;
   
    @Override
    publicvoid onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try{

            // initialize our TextFileHelper here
            TextFileH =new TextFileHelper(MainActivity.this);

            // first, make sure the path to your text file is created
            TextFileH.createPath(filePath);
           
            // so we can show file contents to the user
            contentsTextView =(TextView) findViewById(R.id.contentsTextView);
           
            // here is the actual button listener
            View.OnClickListener handler =newView.OnClickListener(){

                publicvoid onClick(View v){

                    // we will use switch statement and just
                    // get the button's id to make things easier
                    switch(v.getId()){

                    // when create button was clicked
                    case R.id.createBtn:
                        TextFileH.createTextFile(actualFile);
                        contentsTextView.setText("");
                        break;

                    // when read button was clicked
                    case R.id.readBtn:
                        String contents = TextFileH.readTextFile(actualFile);
                        contentsTextView.setText(contents);
                        break;

                    // when update button was clicked
                    case R.id.updateBtn:
                        TextFileH.updateTextFile(actualFile, "Mike is so handsome!\nNew line here!");
                        contentsTextView.setText("");
                        break;

                    // when edit button was clicked
                    case R.id.deleteBtn:
                        TextFileH.deleteTextFile(actualFile);
                        contentsTextView.setText("");
                        break;
                    }
                }
            };

            // we will get the button views and set the listener (handler)
            findViewById(R.id.createBtn).setOnClickListener(handler);
            findViewById(R.id.readBtn).setOnClickListener(handler);
            findViewById(R.id.updateBtn).setOnClickListener(handler);
            findViewById(R.id.deleteBtn).setOnClickListener(handler);

        }catch(NullPointerException e){
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

}

AndroidManifest.xml code - the permission will be WRITE_EXTERNAL_STORAGE

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.textfilesexample"
   android:versionCode="1"
   android:versionName="1.0" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
    <uses-sdk
       android:minSdkVersion="8"
       android:targetSdkVersion="15" />

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

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

</manifest>

res/layout/activity_main.xml code

<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" >

    <Button
       android:id="@+id/createBtn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_alignParentTop="true"
       android:text="Create Text File" />

    <Button
       android:id="@+id/readBtn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_below="@+id/createBtn"
       android:text="Read Text File" />

    <Button
       android:id="@+id/updateBtn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_below="@+id/readBtn"
       android:text="Update Text File" />

    <Button
       android:id="@+id/deleteBtn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_below="@+id/updateBtn"
       android:text="Delete Text File" />

    <TextView
       android:id="@+id/contentsTextView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentLeft="true"
       android:layout_below="@+id/deleteBtn"
       android:text="Text file contents should be here." />

</RelativeLayout>

Some other notes:
  • You can create a text file with a different extension name and yet it will still be readable by your program. For example, you can make a file name like "my_file.coan", evernote does "content.enml". That file will not be easily read in the device since there are no app that can open a file with that extension. Your text file will be easily ignored by the users.
  • If you want to update a specific line of your text file, you have to read it first, track the line number, insert the updated line and use the code above.

More of Android AlertDialog

$
0
0
Ages ago, I posted about a very simple example use of Android AlertDialog. Today I want to share about some more example uses of Android AlertDialog. In this post, you can see and learn codes not only about Android AlertDialogs, but also some Android user interface elements like date and time pickers, ListView, ScrollView, form widgets like Checkbox and Radio buttons, EditText and WebView.

Just some Android AlertDialog Examples.
You can download our code here:


In this example, all codes are in one activity only, which is our MainActivity.java

OnCreate Code - This will be our main screen, with buttons that when you click, it will trigger a specific method with AlertDialog.
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// activity_main is in res/layout/activity_main.xml
setContentView(R.layout.activity_main);

try {

// Click listener.
View.OnClickListener handler =newView.OnClickListener() {
publicvoidonClick(Viewv) {

switch (v.getId()) {

caseR.id.alertTwoBtn:
alertTwoButtons();
break;

caseR.id.alertThreeBtn:
alertThreeButtons();
break;

caseR.id.alertTimePickerBtn:
alertTimePicker();
break;

caseR.id.alertDatePickerBtn:
alertDatePicker();
break;

caseR.id.alertSimpleListViewBtn:
alertSimpleListView();
break;

caseR.id.alertScrollViewBtn:
alertScrollView();
break;

caseR.id.alertFormElementsBtn:
alertFormElements();
break;

caseR.id.alertWebViewBtn:
alertWebView();
break;

}
}
};

// Set button listeners.
findViewById(R.id.alertTwoBtn).setOnClickListener(handler);
findViewById(R.id.alertThreeBtn).setOnClickListener(handler);
findViewById(R.id.alertTimePickerBtn).setOnClickListener(handler);
findViewById(R.id.alertDatePickerBtn).setOnClickListener(handler);
findViewById(R.id.alertSimpleListViewBtn).setOnClickListener(
handler);
findViewById(R.id.alertScrollViewBtn).setOnClickListener(handler);
findViewById(R.id.alertFormElementsBtn).setOnClickListener(handler);
findViewById(R.id.alertWebViewBtn).setOnClickListener(handler);

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
res/layout/activity_main.xml code
<RelativeLayoutxmlns: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">

<Button
android:id="@+id/alertTwoBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:text="Alert Dialog With Two Buttons" />

<Button
android:id="@+id/alertThreeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/alertTwoBtn"
android:text="Alert Dialog With Three Buttons" />

<Button
android:id="@+id/alertTimePickerBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/alertThreeBtn"
android:text="Alert Dialog With Time Picker" />

<Button
android:id="@+id/alertDatePickerBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/alertTimePickerBtn"
android:text="Alert Dialog With Date Picker" />

<Button
android:id="@+id/alertSimpleListViewBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/alertDatePickerBtn"
android:text="Alert Dialog With Simple List View" />

<Button
android:id="@+id/alertScrollViewBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/alertSimpleListViewBtn"
android:text="Alert Dialog With Scroll View" />

<Button
android:id="@+id/alertFormElementsBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/alertScrollViewBtn"
android:text="Alert Dialog With Form Elements" />

<Button
android:id="@+id/alertWebViewBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/alertFormElementsBtn"
android:text="Alert Dialog With Web View" />

</RelativeLayout>
Output:
Our main screen.

Alert Dialog With Two Buttons - Usually used with 'OK' or 'CANCEL', and 'YES' and 'NO' buttons.
/*
* AlertDialog with two button choices.
*
* We also set the ninja icon here.
*/

publicvoid alertTwoButtons() {
newAlertDialog.Builder(MainActivity.this)
.setTitle("Two Buttons")
.setMessage("Do you think Mike is awesome?")
.setIcon(R.drawable.ninja)
.setPositiveButton("YES",
newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {
showToast("Thank you! You're awesome too!");
dialog.cancel();
}
})
.setNegativeButton("NO", newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {
showToast("Mike is not awesome for you. :(");
dialog.cancel();
}
}).show();
}
Output:

When the user touched YES.

Alert Dialog With Three Buttons - You can give users three choices of action, other example can be 'YES', 'NO', and 'CANCEL'. In Android ICS, negative button is always in the left, neutral button is in the center and the yes button is in the right side.
/*
* AlertDialog with three button choices.
*
* We also set the ninja icon here.
*/

publicvoid alertThreeButtons() {
newAlertDialog.Builder(MainActivity.this)
.setTitle("Three Buttons")
.setMessage("Where do you want to go?")
.setIcon(R.drawable.ninja)
.setPositiveButton("RIGHT",
newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {
showToast("You want to go to the RIGHT.");

dialog.cancel();
}
})
.setNeutralButton("CENTER",
newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {
showToast("You want to go to the CENTER.");
dialog.cancel();
}
})
.setNegativeButton("LEFT",
newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {
showToast("You want to go to the LEFT.");
dialog.cancel();
}
}).show();
}
Output:

When the user touched CENTER.

Alert Dialog With Time Picker - Another good thing about AlertDialogs is that you can save space on your main UI. You can let users pick the time in the pop up which is simple and beautiful.
/*
* Show AlertDialog with time picker.
*/

publicvoid alertTimePicker() {

/*
* Inflate the XML view. activity_main is in res/layout/time_picker.xml
*/

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.time_picker, null, false);

// the time picker on the alert dialog, this is how to get the value
finalTimePicker myTimePicker = (TimePicker) view
.findViewById(R.id.myTimePicker);

/*
* To remove option for AM/PM, add the following line:
*
* operatingHoursTimePicker.setIs24HourView(true);
*/


// the alert dialog
newAlertDialog.Builder(MainActivity.this).setView(view)
.setTitle("Set Time")
.setPositiveButton("Go", newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {

String currentHourText = myTimePicker.getCurrentHour()
.toString();

String currentMinuteText = myTimePicker
.getCurrentMinute().toString();

// We cannot get AM/PM value since the returning value
// will always be in 24-hour format.

showToast(currentHourText +":"+ currentMinuteText);

dialog.cancel();

}

}).show();
}

res/layout/time_picker.xml code:

<?xml version="1.0" encoding="utf-8"?>
<TimePickerxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myTimePicker"
android:layout_width="match_parent"
android:layout_height="match_parent">

</TimePicker>
Output:


Alert Dialog With Date Picker - Date pickers on an AlertDialog also save you more space and make date picking enjoyable to the user.
/*
* Show AlertDialog with date picker.
*/

publicvoid alertDatePicker() {

/*
* Inflate the XML view. activity_main is in res/layout/date_picker.xml
*/

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.date_picker, null, false);

// the time picker on the alert dialog, this is how to get the value
finalDatePicker myDatePicker = (DatePicker) view
.findViewById(R.id.myDatePicker);

// the alert dialog
newAlertDialog.Builder(MainActivity.this).setView(view)
.setTitle("Set Date")
.setPositiveButton("Go", newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {

/*
* In the docs of the calendar class, January = 0, so we
* have to add 1 for getting correct month.
* http://goo.gl/9ywsj
*/

int month = myDatePicker.getMonth() +1;
int day = myDatePicker.getDayOfMonth();
int year = myDatePicker.getYear();

showToast(month +"/"+ day +"/"+ year);

dialog.cancel();

}

}).show();
}
res/layout/date_picker.xml code

<DatePickerxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myDatePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

Output:


Alert Dialog With Simple ListView - I usually do this when I have to give users more than three choices of action.
/*
* Show AlertDialog with a simple list view.
*
* No XML needed.
*/

publicvoid alertSimpleListView() {

/*
* WebView is created programatically here.
*
* @Here are the list of items to be shown in the list
*/

finalCharSequence[] items = { "John", "Michael", "Vincent", "Dalisay" };

AlertDialog.Builder builder =newAlertDialog.Builder(MainActivity.this);
builder.setTitle("Make your selection");
builder.setItems(items, newDialogInterface.OnClickListener() {
publicvoidonClick(DialogInterfacedialog, intitem) {

// will toast your selection
showToast("Name: "+ items[item]);
dialog.dismiss();

}
}).show();
}
Output:

When the user tapped 'Michael' on the list.

Alert Dialog With ScrollView - If you want to show long text to the user like your terms of use or privacy policy, you can use a ScrollView with a TextView inside.
/*
* Show AlertDialog with ScrollView.
*
* We use a TextView as ScrollView's child/host
*/

publicvoid alertScrollView() {

/*
* Inflate the XML view.
*
* @activity_main is in res/layout/scroll_text.xml
*/

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View myScrollView = inflater.inflate(R.layout.scroll_text, null, false);

// textViewWithScroll is the name of our TextView on scroll_text.xml
TextView tv = (TextView) myScrollView
.findViewById(R.id.textViewWithScroll);

// Initializing a blank textview so that we can just append a text later
tv.setText("");

/*
* Display the text 10 times so that it will exceed the device screen
* height and be able to scroll
*/

for (int x =1; x <50; x++) {
tv.append("You've been HACKED!\n");
tv.append("By NINJAZHAI.\n");
tv.append("Just kidding.\n\n");
}

newAlertDialog.Builder(MainActivity.this).setView(myScrollView)
.setTitle("Scroll View")
.setPositiveButton("OK", newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {
dialog.cancel();
}

}).show();

}
res/layout/scroll_text.xml code
<ScrollViewxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView
android:id="@+id/textViewWithScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="" />

</ScrollView>
Output:

Alert Dialog With Form Elements - Here you can also save a lot of space and make your app more simple to use by reducing the number of navigation to forms.
/*
* Show AlertDialog with some form elements.
*/

publicvoid alertFormElements() {

/*
* Inflate the XML view. activity_main is in
* res/layout/form_elements.xml
*/

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
finalView formElementsView = inflater.inflate(R.layout.form_elements,
null, false);

// You have to list down your form elements
finalCheckBox myCheckBox = (CheckBox) formElementsView
.findViewById(R.id.myCheckBox);

finalRadioGroup genderRadioGroup = (RadioGroup) formElementsView
.findViewById(R.id.genderRadioGroup);

finalEditText nameEditText = (EditText) formElementsView
.findViewById(R.id.nameEditText);

// the alert dialog
newAlertDialog.Builder(MainActivity.this).setView(formElementsView)
.setTitle("Form Elements")
.setPositiveButton("OK", newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {

String toastString ="";

/*
* Detecting whether the checkbox is checked or not.
*/

if (myCheckBox.isChecked()) {
toastString +="Happy is checked!\n";
} else {
toastString +="Happy IS NOT checked.\n";
}

/*
* Getting the value of selected RadioButton.
*/

// get selected radio button from radioGroup
int selectedId = genderRadioGroup
.getCheckedRadioButtonId();

// find the radiobutton by returned id
RadioButton selectedRadioButton = (RadioButton) formElementsView
.findViewById(selectedId);

toastString +="Selected radio button is: "
+ selectedRadioButton.getText() +"!\n";

/*
* Getting the value of an EditText.
*/

toastString +="Name is: "+ nameEditText.getText()
+"!\n";

showToast(toastString);

dialog.cancel();
}

}).show();
}
res/layout/form_elements/xml code:

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">


<CheckBox
android:id="@+id/myCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Happy?" />

<RadioGroup
android:id="@+id/genderRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/myCheckBox">


<RadioButton
android:id="@+id/maleRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="Male" />


<RadioButton
android:id="@+id/femaleRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/maleRadioButton"
android:text="Female" />

</RadioGroup>



<EditText
android:id="@+id/nameEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/genderRadioGroup"
android:ems="10"
android:hint="Type your name here...">

<requestFocus />
</EditText>

</RelativeLayout>
Output:


AlertDialog with WebView - Some app that I see put their privacy policy, terms of use and other information to an online page. You can make that AlertDialog with a WebView too.
/*
* Show AlertDialog with web view.
*
* Don't forget the Internet permission on your AndroidManifest.xml
*/

publicvoid alertWebView() {

// WebView is created programatically here.
WebView myWebView =newWebView(MainActivity.this);
myWebView.loadUrl("http://google.com/");

/*
* This part is needed so it won't ask the user to open another browser.
*/

myWebView.setWebViewClient(newWebViewClient() {
@Override
publicbooleanshouldOverrideUrlLoading(WebViewview, Stringurl) {
view.loadUrl(url);
returntrue;
}
});

newAlertDialog.Builder(MainActivity.this).setView(myWebView)
.setTitle("My Web View")
.setPositiveButton("OK", newDialogInterface.OnClickListener() {
@TargetApi(11)
publicvoidonClick(DialogInterfacedialog, intid) {

dialog.cancel();

}

}).show();
}
Output:
When webpage is not available.


Other tips:
If you want to prevent your AlertDialog from cancelling when you touched its button, you have to override the onClickListener of the button.

You can let me know in the comments if you want to correct or add something in this post, thanks!

Coding A Responsive Website Design

$
0
0
In today's tutorial, I'm going to show you a systematic and very simple way to create a responsive website with CSS3 media queries and HTML5. Responsive web design has been around for few years now and is widely accepted as a new standard when building a modern website.

Responsive Web Design Code
A screenshot of our responsive web page.

I want to give you a brief definition of what a responsive web design is, if you already know what it is, you may skip this part and jump to the "Let's code" section below. Well, for me, responsive web design is a way to show your web site's content in an easy-to-understand manner regardless of what device views it. For example, a visitor of your website must feel comfortable when viewing the same website for any type of devices (with different screen sizes) he has. Example of those devices include:
  • Android phones
  • iPhones
  • 7" tablets
  • 10" tablets
  • iPads
  • Desktop computers
  • and many more devices that can view a web page.
Other points to consider...
  • Your website should not have a horizontal scrollbar.
  • Users must not use the zoom tool to view your site's contents.
You can download our code or see a live demo (Resize your browser or try accessing the URL on your mobile devices in landscape and portrait mode, you'll see its responsiveness.)

  

By the way, if you want to test the live demo on different devices easily, you can use the tools described on this link: Responsive Web Design Testing Tools.

Let's code.

Step 1: It is important to build your website for the smallest device possible first. Build the website for smart phones. You can view a live demo of our step 1 here.

<!DOCTYPE HTML>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8" />
<metaname="viewport"content="width=device-width">

<title>Your Website</title>

<style>

/* misc start */
*{
margin:0px;
padding:0px
}

body{
font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
}

.media1140px{
background-color:#CE9429;
}

.media768px{
background-color:#EDD49A;
}

.media480px{
background-color:#EFEF34;
}

.media300px{
background-color:#82EAFF;
}

.media1140px, .media768px, .media480px, .media300px{
padding:15px;
}

p{
margin:0 0 20px 0;
}

.clearb{
clear:both;
}
/* misc end */






/* header start */
#mainHeader{
background-color:#82EAFF;
padding:0.5em;
overflow:auto;
}

/* to make our logo resize automatically */
#responsiveLogo{
width:100%;
}

#responsiveLogoimg{
max-height: 100%;
max-width: 100%;
}
/* header end */





/* navigation start */
nav{
float:left;
width:100%;
}

navul{
list-style-type:none;
padding:0;
}

navulli{

}

navullia{
background-color:green;
border:thin solid #fff;
color:#fff;
display:block;
height:3em;
line-height:3em;
text-align:center;
text-decoration:none;
width:100%;
}

navullia:hover{
background-color:yellow;
color:#000;
}
/* navigation end */





/* middle section start */
#mainSection{
background-color: #D9F8F2;
float: left;
width: 96%;
}

#sideBox1{
background-color: #C9A449;
width: 96%;
}

#mainSection, #sideBox1{
overflow: auto;
padding:2%;
}
/* middle section end */



/* footer start */
footer{
background-color:orange;
height:50px;
line-height:50px;
text-align:center;
width:100%;
}
/* footer end */

</style>

</head>
<body>

<headerid='mainHeader'>

<divid='responsiveLogo'>
<imgsrc='images/logo4.png' />
</div>
<nav>
<ul>
<li><ahref="#home">Home</a></li>
<li><ahref="#news">News</a></li>
<li><ahref="#contact">Contact</a></li>
<li><ahref="#about">About</a></li>
</ul>
</nav>
</header>

<sectionid='mainSection'>

<article>
<header>
<h2>About The Code Of A Ninja</h2>
<p>Posted on <timedatetime="2003-01-01T16:31:24+02:00">January 1st, 2013</time> by <ahref="#">Mike</a> - <ahref="#comments">173 comments</a></p>
</header>
<p>
<divclass='media1140px'>@media 1140px</div>
<divclass='media768px'>@media 768px</div>
<divclass='media480px'>@media 480px</div>
<divclass='media300px'>@media 300px</div>
</p>
<p>
My name is Mike Dalisay, a 22 year old Software Developer (<ahref="http://en.wikipedia.org/wiki/Web_developer">Web</a> and
<ahref="http://developer.android.com/index.html">Android</a>) from The Philippines.
My posts here are mainly notes to self and for <i>anyone else</i> that may find them useful.
</p>
<p>
This blog contains programming tutorials, codes, demos, scripts, how-to's, tips, tricks, code downloads and other fun stuff
related to web and android apps <ahref="http://en.wikipedia.org/wiki/Software_development">development</a>.
</p>
<p>
Most of my time is spent with PHP, MySQL, AJAX, HTML, CSS, jQuery, JavaScript, XML, Web Design, Android, JAVA and some
other Open source software projects related to Web and Android apps development.
</p>
<p>
You can leave a comment, <ahref="http://twitter.com/ninjazhai">follow</a> or <ahref="https://www.facebook.com/pages/the-code-of-a-ninja/107786425949934">subscribe</a>
to this blog. Take care. :)
</p>
</article>

</section>

<asideid='sideBox1'>
<h2>The Blogger</h2>
<p>This is your side bar. You can add your information or links here.</p>
</aside>

<divclass='clearb'></div>

<footer>
<p>Copyright 2013 - Game Note</p>
</footer>

</body>
</html>

After doing the code above, our webpage is not yet responsive. You won't see the magic even if you resize your browser. By the way, you can also include the CSS code as external file.

Step 2: Now let's create the website layout for a type of device next to a smart phone, maybe we can consider a 7" tablets as one. You can view a live demo of your step 2 here.

We'll just add the following CSS:

/* 
-can be for 7 inch tablets
-This CSS will apply for devices with the minimum width of 480 pixels
*/

@mediaonlyscreenand (min-width:480px) {
#mainHeader {
background-color:#EFEF34;
}

navulli{
float:left;
width:25%;
}
}

Now if you'll resize your browser, you can see that your website is already responsive in two ways.

Step 3: Now we will create the website layout for another type of screen next to 7" tablets, we can consider the iPad or 10" tablets in portrait mode. Our step 3 live demo is here.

Please add the following CSS:

/*
-10 inch tablets
-This CSS will apply for devices with the minimum width of 768 pixels
*/

@mediaonlyscreenand (min-width:768px) {
#mainHeader {
background-color:#EDD49A;
}

#mainSection{
float:left;
width:61%;
}

#sideBox1{
float:right;
width:30%;
}

}

Now our website is responsive in three ways. Try to re-size your browser again.

Step 4: Now we will create the website for desktop computers, laptops or 10" tablets in landscape mode.
/*
-Desktop computers
-This CSS will apply for devices with the minimum width of 1140 pixels
*/

@mediaonlyscreenand (min-width:1140px) {
#mainHeader {
background-color:#CE9429;
}

#responsiveLogo{
float:left;
width:30%;
}

nav{
float:left;
width:70%;
}

navul{
margin:1.5em000;
}
}

Complete web page code:

<!DOCTYPE HTML>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8" />
<metaname="viewport"content="width=device-width">

<title>Your Website</title>

<style>

/* misc start */
*{
margin:0px;
padding:0px
}

body{
font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
}

.media1140px{
background-color:#CE9429;
}

.media768px{
background-color:#EDD49A;
}

.media480px{
background-color:#EFEF34;
}

.media300px{
background-color:#82EAFF;
}

.media1140px, .media768px, .media480px, .media300px{
padding:15px;
}

p{
margin:0 0 20px 0;
}

.clearb{
clear:both;
}
/* misc end */






/* header start */
#mainHeader{
background-color:#82EAFF;
padding:0.5em;
overflow:auto;
}

#responsiveLogo{
width:100%;
}

#responsiveLogoimg{
max-height: 100%;
max-width: 100%;
}
/* header end */





/* navigation start */
nav{
float:left;
width:100%;
}

navul{
list-style-type:none;
padding:0;
}

navulli{

}

navullia{
background-color:green;
border:thin solid #fff;
color:#fff;
display:block;
height:3em;
line-height:3em;
text-align:center;
text-decoration:none;
width:100%;
}

navullia:hover{
background-color:yellow;
color:#000;
}
/* navigation end */





/* middle section start */
#mainSection{
background-color: #D9F8F2;
float: left;
width: 96%;
}

#sideBox1{
background-color: #C9A449;
width: 96%;
}

#mainSection, #sideBox1{
overflow: auto;
padding:2%;
}
/* middle section end */



/* footer start */
footer{
background-color:orange;
height:50px;
line-height:50px;
text-align:center;
width:100%;
}
/* footer end */







/* @media start */

/* we don't need to specify for smartphones, that's our default layout */

/*
-7 inch tablets
-This CSS will apply for devices with the minimum width of 480 pixels
*/

@mediaonlyscreenand (min-width:480px) {
#mainHeader {
background-color:#EFEF34;
}

navulli{
float:left;
width:25%;
}
}

/*
-10 inch tablets
-This CSS will apply for devices with the minimum width of 768 pixels
*/

@mediaonlyscreenand (min-width:768px) {
#mainHeader {
background-color:#EDD49A;
}

#mainSection{
float:left;
width:61%;
}

#sideBox1{
float:right;
width:30%;
}


}

/*
-Desktop computers
-This CSS will apply for devices with the minimum width of 1140 pixels
*/

@mediaonlyscreenand (min-width:1140px) {
#mainHeader {
background-color:#CE9429;
}

#responsiveLogo{
float:left;
width:30%;
}

nav{
float:left;
width:70%;
}

navul{
margin:1.5em000;
}
}

/* @media end */

</style>

</head>
<body>

<headerid='mainHeader'>

<divid='responsiveLogo'>
<imgsrc='images/logo4.png' />
</div>
<nav>
<ul>
<li><ahref="#home">Home</a></li>
<li><ahref="#news">News</a></li>
<li><ahref="#contact">Contact</a></li>
<li><ahref="#about">About</a></li>
</ul>
</nav>
</header>

<sectionid='mainSection'>

<article>
<header>
<h2>About The Code Of A Ninja</h2>
<p>Posted on <timedatetime="2003-01-01T16:31:24+02:00">January 1st, 2013</time> by <ahref="#">Mike</a> - <ahref="#comments">173 comments</a></p>
</header>
<p>
<divclass='media1140px'>@media 1140px</div>
<divclass='media768px'>@media 768px</div>
<divclass='media480px'>@media 480px</div>
<divclass='media300px'>@media 300px</div>
</p>
<p>
My name is Mike Dalisay, a 22 year old Software Developer (<ahref="http://en.wikipedia.org/wiki/Web_developer">Web</a> and
<ahref="http://developer.android.com/index.html">Android</a>) from The Philippines.
My posts here are mainly notes to self and for <i>anyone else</i> that may find them useful.
</p>
<p>
This blog contains programming tutorials, codes, demos, scripts, how-to's, tips, tricks, code downloads and other fun stuff
related to web and android apps <ahref="http://en.wikipedia.org/wiki/Software_development">development</a>.
</p>
<p>
Most of my time is spent with PHP, MySQL, AJAX, HTML, CSS, jQuery, JavaScript, XML, Web Design, Android, JAVA and some
other Open source software projects related to Web and Android apps development.
</p>
<p>
You can leave a comment, <ahref="http://twitter.com/ninjazhai">follow</a> or <ahref="https://www.facebook.com/pages/the-code-of-a-ninja/107786425949934">subscribe</a>
to this blog. Take care. :)
</p>
</article>

</section>

<asideid='sideBox1'>
<h2>The Blogger</h2>
<p>This is your side bar. You can add your information or links here.</p>
</aside>

<divclass='clearb'></div>

<footer>
<p>Copyright 2013 - Game Note</p>
</footer>

</body>
</html>

Some screenshots of our output:

Page header smartphone screenshot - landscape mode

Footer screenshot from my smartphone in landscape mode.

Header screenshot from my smartphone
in portrait mode.

Body section screenshot from
my Smartphone in  portrait mode.

Footer screenshot from
my smartphone in portrait mode.

Screenshot from my 10.1 Android tablet in portrait mode.


Screenshot from my 10.1 Android tablet in landscape mode.

Credits: Image from Game Note.

Android: Copy Asset To SD Card

$
0
0
Assets folder is where you can store some files for you app. Today I'm going to show you how to copy files from your android app's asset's folder to the device SD card. I used this when I have to deploy some default text files for my app and manipulate it at later time. Some existing android applications do this, they create folders with files inside on the first install. You can do the check if the file exists in the directory so you won't have to copy the assets files every time.

By the way, the assets folder is included in your project package. If you're using eclipse, you can see it in the package explorer. It looks like this:

An example assets folder. Image from http://goo.gl/ml9UD

In our example our assets has MyHtmlFiles folder with CodeOfANinja.html and ThankYou.html inside. Okay, so now we are going to code the app that:

  1. Copies 2 HTML files from the assets.
  2. Store to the device root directory.
If the HTML files were copied to your SD card, you can now manipulate its contents, rewrite it or make it a dynamic content and show it to your user anytime using the WebView. You can use this code for that.

Download code here:


MainActivity.java code

packagecom.example.assetstosdcard;

importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;

importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.app.Activity;
importandroid.content.res.AssetManager;

publicclassMainActivityextendsActivity {

// Buffer size used.
privatefinalstaticintBUFFER_SIZE=1024;

@Override
publicvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

try {
AssetManager assetFiles = getAssets();

// MyHtmlFiles is the name of folder from inside our assets folder
String[] files = assetFiles.list("MyHtmlFiles");

// Initialize streams
InputStream in =null;
OutputStream out =null;

for (int i =0; i < files.length; i++) {

if (files[i].toString().equalsIgnoreCase("images")
|| files[i].toString().equalsIgnoreCase("js")) {

/*
* @Do nothing. images and js are folders but they will be
* interpreted as files.
*
* @This is to prevent the app from throwing file not found
* exception.
*/


} else {

/*
* @Folder name is also case sensitive
*
* @MyHtmlFiles is the folder from our assets
*/

in = assetFiles.open("MyHtmlFiles/"+ files[i]);

/*
* Currently we will copy the files to the root directory
* but you should create specific directory for your app
*/

out =newFileOutputStream(
Environment.getExternalStorageDirectory() +"/"
+ files[i]);
copyAssetFiles(in, out);

}
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}

}

privatestaticvoidcopyAssetFiles(InputStreamin, OutputStreamout) {
try {

byte[] buffer =newbyte[BUFFER_SIZE];
int read;

while ((read = in.read(buffer)) !=-1) {
out.write(buffer, 0, read);
}

in.close();
in =null;
out.flush();
out.close();
out =null;

} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

}


ActivityMain.xml code - This will what will be seen when our the code runs.

<RelativeLayoutxmlns: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">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center"
android:text="CodeOfANinja.html and ThankYou.html should be copied to the root directory of your SD card by now."
tools:context=".MainActivity" />

</RelativeLayout>


AndroidManifest.xml code - permission is WRITE_EXTERNAL_STORAGE since we are writing files to SD card.

<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.assetstosdcard"
android:versionCode="1"
android:versionName="1.0">

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

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />

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

</manifest>

When our code runs:

Check your SD card when you see this.

Programming a Simple Application with Android SQLite - Tutorial

$
0
0
February 7, 2013 Update: For those who don't like a tutorial with an example application, I posted another version of Android Sqlite tutorial which is shorter and easier to grasp.
Hi guys! Our tutorial for today is about creating a very simple application that uses Android Sqlite database capability. I am personally amazed by this Android feature, imagine, a database in your hands? Wow. Our app will maintain records of locations. Database operations we'll discuss include:
  • Creating a record.
  • Reading single and all records.
  • Updating records.
  • Deleting single and all records.
  • and counting location records.
Our code here can be downloaded. Also, you can install the APK on your Android device if you want a live demo:

download code for Android SQLite Tutorial  download apk for Android SQLite Tutorial

This post will also show you how I manage my database tables. If you just want to see codes for Android SQLite CRUD operations, jump and see the code of LocationsTableController.java (highlighted in green below)

We're going to have file structure like this (see highlighted):

We'll create these highlighted files.

If you notice, we have 6 packages. Why we are using packages here? Because we want to be well organized. Imagine if our app will have more activities, objects, tables, on click listeners, etc., it will be harder to maintain. We have to group them, make separate files, and make our code a joy to read or re-use.

You can create new package by right clicking your src folder > new > package.

Packages.

We'll write 7 JAVA files. Our JAVA files are grouped into packages based on its functions.

Java files.

We'll create 2 layout files. This is our user interface stuff.

XML layout files.

Let's Code

Codes below are shown based on when the file is created. Please read comments on code.

The first file we've created is of course, our MainActivity.java and activity_main.xml

MainActivity.java
packagecom.example.Activities;

/*
* http://codeofaninja.com/
* code from the code of a ninja
*/


importjava.util.List;

importcom.example.Objects.LocationObject;
importcom.example.OnClickListeners.ButtonCreateLocationOnClickListener;
importcom.example.OnClickListeners.TextViewLocationItemOnClickListener;
importcom.example.TableControllers.LocationTableController;
importcom.example.sqlitedatabase.R;

importandroid.os.Bundle;
importandroid.util.Log;
importandroid.widget.Button;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
importandroid.app.Activity;

publicclassMainActivityextendsActivity {

// for debugging purposes
publicstaticfinalStringLOG_TAG="MainActivity.java";

@Override
publicvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

try {

// create location button
Button buttonCreateLocation = (Button) findViewById(R.id.buttonCreateLocation);

// create location button's on click listener
// it will pop up the locations add form
buttonCreateLocation
.setOnClickListener(newButtonCreateLocationOnClickListener());

// show records to user (from the database)
showRecords();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

publicvoidshowRecords() {
try {

Log.v(LOG_TAG, "Showing records.");

// count records, show it by appending to existing text view
appendRecordCount();

// load the linear layout where our location record text view will
// be added
LinearLayout linearLayoutLocationRecords = (LinearLayout) findViewById(R.id.linearLayoutLocationRecords);

// remove current contents first, so we can load new contents
linearLayoutLocationRecords.removeAllViews();

// initialize controller
LocationTableControllerLocationTableC=newLocationTableController(
MainActivity.this);

// read record
List<LocationObject> locations =LocationTableC.read();

if (locations.size() >0) {

// loop through each record in the database
for (LocationObject obj : locations) {

// the texts that will be seen
int locationId = obj.locationId;
String locationName = obj.locationName;
String locationDescription = obj.locationDescription;

// make the TextView ready
TextView textViewLocationItem =newTextView(this);

// set the tag so that we can know what record to delete
textViewLocationItem.setTag(Integer.toString(locationId));

// set the TextView contents
String textViewContents = locationId +". "+ locationName
+"\n"+ locationDescription;
textViewLocationItem.setText(textViewContents);

// set the on click listener for pop up options of edit or
// delete
textViewLocationItem
.setOnClickListener(newTextViewLocationItemOnClickListener());

// just add some padding
textViewLocationItem.setPadding(3, 8, 3, 8);

// finally, add the TextView on the list
linearLayoutLocationRecords.addView(textViewLocationItem);
}

} else {
// no records yet
// prepare our TextView
TextView locationItem =newTextView(this);
locationItem.setPadding(8, 8, 8, 8);
locationItem.setText("No records yet.");

// show to user that there are no records yet.
linearLayoutLocationRecords.addView(locationItem);
}

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/*
* This method will show the user the number of records.
*/

publicvoidappendRecordCount() {
try {

// initialize controller
LocationTableControllerLocationTableC=newLocationTableController(
MainActivity.this);

// read record
int recordCount =LocationTableC.count();

// the text view where we will put our record count
TextView textViewSomeNotes = (TextView) findViewById(R.id.textViewRecordCount);
textViewSomeNotes.setText(recordCount +" records found.");

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

}

activity_main.xml code
<RelativeLayoutxmlns: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">

<!-- will pop up add form when clicked -->

<Button
android:id="@+id/buttonCreateLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create Location" />

<!-- Just some note to the user. -->

<TextView
android:id="@+id/textViewSomeNotes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/buttonCreateLocation"
android:padding="1dp"
android:text="Below is the list of Locations from the database. Click an item to Edit or Delete. Scroll if you believe the list is long." />

<TextView
android:id="@+id/textViewRecordCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewSomeNotes"
android:text="0 records found"
android:padding="1dp" />

<!-- We use ScrollView so that when there are many names added, it is still possible to see all of them by scrolling -->

<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewRecordCount">

<!-- ScrollView always has only one child layout, in our case, child layout is the LinearLayout -->

<LinearLayout
android:id="@+id/linearLayoutLocationRecords"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<!-- This is where the list of Names text views will be added -->
</LinearLayout>
</ScrollView>

</RelativeLayout>

Our LocationObject.java code, it represents our location details or fields. We don't have to use getters/setters here. :)
packagecom.example.Objects;

/*
* We won't need getters/setters
*/

publicclassLocationObject {

publicint locationId;
publicString locationName;
publicString locationDescription;

// constructor for adding
publicLocationObject(StringlocationName, StringlocationDescription){
this.locationName = locationName;
this.locationDescription = locationDescription;
}

//constructor for updating
publicLocationObject(intlocationId, StringlocationName, StringlocationDescription){
this.locationId = locationId;
this.locationName = locationName;
this.locationDescription = locationDescription;
}

}


Since we are already using a database operation in our MainActivity (showing of records), we'll have to create our DatabaseHandler.java
packagecom.example.Handlers;

importcom.example.TableHelpers.LocationTableHelper;

importandroid.content.Context;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.database.sqlite.SQLiteOpenHelper;

/*
* This class will handle the database name, upgrade, table helpers, dropping and creating tables.
*
* Table helper and controller codes can be put here
* but we chose to put it in different files so it will be easier to read,
* implement code re-use, and make it easier to manage and debug,
* especially if you have lots of database tables.
*/

publicclassDatabaseHandlerextendsSQLiteOpenHelper {

// for our logs
publicstaticfinalStringLOG_TAG="DatabaseHandler.java";

// database version
privatestaticfinalintDATABASE_VERSION=7;

// database name
protectedstaticfinalStringDATABASE_NAME="NinjaDatabase1";

// table helpers
publicLocationTableHelperLocationTableH;

// constructor
publicDatabaseHandler(Contextcontext) {

super(context, DATABASE_NAME, null, DATABASE_VERSION);

// instantiate our table helper.
LocationTableH=newLocationTableHelper();
}

// creating Tables
@Override
publicvoidonCreate(SQLiteDatabasedb) {

LocationTableH.createTable(db);

}

/*
* When upgrading the database, it will drop the current tables and recreate.
*/

@Override
publicvoidonUpgrade(SQLiteDatabasedb, intoldVersion, intnewVersion) {

LocationTableH.dropTable(db);
onCreate(db);
}

}

Related to the code above is our LocationsTableHelper.java. It contains our code for creating and dropping the locations table.
packagecom.example.TableHelpers;

importandroid.database.sqlite.SQLiteDatabase;

publicclassLocationTableHelper {

publicString tableName ="locations";

publicString fieldLocationId ="id";
publicString fieldLocationName ="name";
publicString fieldLocationDescription ="description";

/*
* Create the table.
*/

publicvoidcreateTable(SQLiteDatabasedb) {
try {
String sql ="";

sql +="CREATE TABLE "+ tableName;
sql +=" ( ";
sql += fieldLocationId +" INTEGER PRIMARY KEY AUTOINCREMENT, ";
sql += fieldLocationName +" TEXT, ";
sql += fieldLocationDescription +" TEXT ";
sql +=" ) ";

db.execSQL(sql);
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/*
* Drop the table.
*/

publicvoiddropTable(SQLiteDatabasedb) {
try {
String sql ="DROP TABLE IF EXISTS "+ tableName;
db.execSQL(sql);
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}

And the code where all the database operation of our locations table will be accessed is the LocationsTableController.java
packagecom.example.TableControllers;

importjava.util.ArrayList;
importjava.util.List;

importandroid.content.ContentValues;
importandroid.content.Context;
importandroid.database.Cursor;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.util.Log;

importcom.example.Handlers.DatabaseHandler;
importcom.example.Objects.LocationObject;

/*
* This class will control all the locations table activities such as
* creating, reading (single and all), updating, deleting (single and all), and counting location records.
*/

publicclassLocationTableControllerextendsDatabaseHandler {

publicLocationTableController(Contextcontext) {
super(context);
}

/*
* Create location record.
*
* @param - location contains location details to be added as single row.
*/

publicvoidcreate(LocationObjectlocation) {

try {

ContentValues values =newContentValues();

values.put(LocationTableH.fieldLocationName, location.locationName);

values.put(LocationTableH.fieldLocationDescription,
location.locationDescription);

SQLiteDatabase db =this.getWritableDatabase();

db.insert(LocationTableH.tableName, null, values);
db.close();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/*
* Read all location record.
*/

publicList<LocationObject>read() {

List<LocationObject> recordsList =newArrayList<LocationObject>();

try {

// select query
String sql ="";
sql +="SELECT * FROM "+LocationTableH.tableName;
sql +=" ORDER BY "+LocationTableH.fieldLocationId +" DESC";

SQLiteDatabase db =this.getWritableDatabase();

// execute the query
Cursor cursor = db.rawQuery(sql, null);

// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {

int locationId =Integer.parseInt(cursor.getString(cursor
.getColumnIndex(LocationTableH.fieldLocationId)));

String locationName = cursor.getString(cursor
.getColumnIndex(LocationTableH.fieldLocationName));

String locationDescription = cursor
.getString(cursor
.getColumnIndex(LocationTableH.fieldLocationDescription));

LocationObject location =newLocationObject(locationId,
locationName, locationDescription);

// add to list
recordsList.add(location);

} while (cursor.moveToNext());
}

// close the database
db.close();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}

// return the list of records
return recordsList;
}

/*
* Update location record.
*
* @param id - will identify which record is to be updated.
*
* @param name - the new location name to be saved.
*
* @param description - the new location description to be saved.
*/

publicvoidupdate(intid, Stringname, Stringdescription) {

try {
Log.v("LOGHERE", "desc: "+ description);
ContentValues values =newContentValues();

values.put(LocationTableH.fieldLocationName, name);
values.put(LocationTableH.fieldLocationDescription, description);

// you can use AND if you have multiple conditions
String where =LocationTableH.fieldLocationId +" = ?";

// you should use commas when you have multiple conditions
String[] whereArgs = { Integer.toString(id) };

SQLiteDatabase db =this.getWritableDatabase();

// use the update command
db.update(LocationTableH.tableName, values, where, whereArgs);
db.close();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/*
* Delete location record.
*
* @param id - to identify which location record is to be deleted.
*/

publicbooleandelete(Stringid) {
boolean deleteSuccessful =false;

try {

SQLiteDatabase db =this.getWritableDatabase();
deleteSuccessful = db.delete(LocationTableH.tableName, "id ='"+ id
+"'", null) >0;
db.close();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}

return deleteSuccessful;

}

/*
* Retrieve single record.
*
* @param id - to identify which location record data is to be returned.
*/

publicLocationObjectgetLocation(intid) {

LocationObject location =null;

try {

// select query
String sql ="";
sql +="SELECT * FROM "+LocationTableH.tableName;
sql +=" ORDER BY "+LocationTableH.fieldLocationId +" DESC";

SQLiteDatabase db =this.getWritableDatabase();

// execute the query
Cursor cursor = db.rawQuery(sql, null);

// looping through all rows and adding to list
if (cursor.moveToFirst()) {

int locationId =Integer.parseInt(cursor.getString(cursor
.getColumnIndex(LocationTableH.fieldLocationId)));

String locationName = cursor.getString(cursor
.getColumnIndex(LocationTableH.fieldLocationName));

String locationDescription = cursor
.getString(cursor
.getColumnIndex(LocationTableH.fieldLocationDescription));

location =newLocationObject(locationId, locationName,
locationDescription);

}

// close the database
db.close();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}

return location;

}

/*
* Count all location records.
*/

publicintcount() {

// select query
SQLiteDatabase db =this.getWritableDatabase();

String sql ="SELECT * FROM "+LocationTableH.tableName;
int recordCount = db.rawQuery(sql, null).getCount();
db.close();

return recordCount;

}

/*
* Delete ALL accounts receivable record.
*
* More efficient way is to delete and then recreate it.
* http://stackoverflow.com/a/4280131/903298
*
* You can call it from an on click listener too. :)
*/

publicvoiddeleteAll() {
try {

LocationTableH.dropTable(this.getWritableDatabase());
LocationTableH.createTable(this.getWritableDatabase());

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}


We'll create the location_form layout to be inflated on the "add form" pop up. Here's the code for our location_form.xml
<RelativeLayoutxmlns: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">

<!-- Text field where the location name will be entered. -->

<EditText
android:id="@+id/editTextLocationName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:ems="10"
android:hint="Location Name"
android:singleLine="true">

<requestFocus />
</EditText>

<!-- Text field where the location description will be entered. -->

<EditText
android:id="@+id/editTextLocationDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/editTextLocationName"
android:ems="10"
android:hint="Location Description"
android:singleLine="true" />

</RelativeLayout>

Since we have specified our ButtonCreateLocationOnClickListener on the MainActivity, here's the code of our ButtonCreateLocationOnClickListener.java that will pop up form to add a location.
packagecom.example.OnClickListeners;

importcom.example.Activities.MainActivity;
importcom.example.Objects.LocationObject;
importcom.example.TableControllers.LocationTableController;
importcom.example.sqlitedatabase.R;

importandroid.app.AlertDialog;
importandroid.content.Context;
importandroid.content.DialogInterface;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.EditText;
importandroid.widget.Toast;

publicclassButtonCreateLocationOnClickListenerimplementsOnClickListener {

@Override
publicvoidonClick(Viewv) {
try {

// get the context
finalContext mContext = v.getContext();

// inflate our location_form.xml
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
finalView formElementsView = inflater.inflate(
R.layout.location_form, null, false);

// You have to list down your form elements, we have two EditText
finalEditText editTextLocationName = (EditText) formElementsView
.findViewById(R.id.editTextLocationName);

finalEditText editTextLocationDescription = (EditText) formElementsView
.findViewById(R.id.editTextLocationDescription);

// the alert dialog
newAlertDialog.Builder(mContext)
.setView(formElementsView)
.setTitle("codeofaninja.com")
.setPositiveButton("Add",
newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterfacedialog,
intid) {

// save the values
String locationName = editTextLocationName
.getText().toString();

String locationDescription = editTextLocationDescription
.getText().toString();

// set the values from those EditText
LocationObject location =newLocationObject(
locationName, locationDescription);

// create the new record
newLocationTableController(mContext)
.create(location);

// retrieve the records
((MainActivity) mContext).showRecords();

// tell the user it was added
Toast.makeText(mContext,
"Location item was added.",
Toast.LENGTH_SHORT).show();

dialog.cancel();
}

}).show();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

}

Our records is listed when the ActivityMain was called, here's the on click listener that will pop up an edit or delete option to the user when a location item was clicked, the file is TextViewLocationItemOnClickListener.java
packagecom.example.OnClickListeners;

importcom.example.Activities.MainActivity;
importcom.example.Objects.LocationObject;
importcom.example.TableControllers.LocationTableController;
importcom.example.sqlitedatabase.R;

importandroid.app.AlertDialog;
importandroid.content.Context;
importandroid.content.DialogInterface;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.EditText;
importandroid.widget.Toast;

publicclassTextViewLocationItemOnClickListenerimplementsOnClickListener {

// make a context property
Context mContext;

/*
* This method will run when the user clicked a location item on the list.
*
* It will show a pop up with options to edit or delete the clicked location
* item.
*/

@Override
publicvoidonClick(Viewv) {

// get the context
mContext = v.getContext();

// get the tag we set earlier as the unique location ID
finalString id = v.getTag().toString();

// prepare the options
finalCharSequence[] items = { "Edit", "Delete" };

// show the options in a dialog
newAlertDialog.Builder(mContext).setTitle("Location Item")
.setItems(items, newDialogInterface.OnClickListener() {
publicvoidonClick(DialogInterfacedialog, intitem) {

// instantiate our locations table.
LocationTableControllerLocationTableC=newLocationTableController(
mContext);

// edit
if (item ==0) {
// pops up the edit form
editLocation(Integer.parseInt(id));
}

// delete
elseif (item ==1) {

// delete using the table controller
if (LocationTableC.delete(id)) {

// tell the user the record was deleted.
Toast.makeText(mContext,
"Location item was deleted.",
Toast.LENGTH_SHORT).show();

// show the updated list to the user
((MainActivity) mContext).showRecords();

}

}

dialog.dismiss();

}
}).show();

}

/*
* This method will pop up an AlertDialog with the edit form.
*
* @param - locationId is the unique database ID of the selected location
* record.
*/

publicvoideditLocation(finalintlocationId) {
try {

// new instance of our table
finalLocationTableControllerLocationTableC=newLocationTableController(
mContext);

// read current value based on location id
LocationObject location =LocationTableC.getLocation(locationId);

// inflate our location_form XML which is location in
// res/layout/location_form.xml
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
finalView formElementsView = inflater.inflate(
R.layout.location_form, null, false);

// listing down our form elements
finalEditText editTextLocationName = (EditText) formElementsView
.findViewById(R.id.editTextLocationName);

finalEditText editTextLocationDescription = (EditText) formElementsView
.findViewById(R.id.editTextLocationDescription);

// set value to our form EditTexts
editTextLocationName.setText(location.locationName);
editTextLocationDescription.setText(location.locationDescription);

// the alert dialog with our form
newAlertDialog.Builder(mContext)
.setView(formElementsView)
.setTitle("codeofaninja.com")
.setPositiveButton("Save Changes",
newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterfacedialog,
intid) {

// update the record
LocationTableC.update(locationId,
editTextLocationName.getText()
.toString(),
editTextLocationDescription
.getText().toString());

// tell the user it was updated
Toast.makeText(mContext,
"Location item was updated.",
Toast.LENGTH_SHORT).show();

// show the updated list to the user
((MainActivity) mContext).showRecords();

dialog.cancel();
}

}).show();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

}
Output Screenshots:
Android SQLite Tutorial
Our main screen.
When "Create Location" button was touched.

When the "Add" button
on the pop up was touched.
When the added location record
on the list was touched.
When the user chose to edit.

After touching the "Save Changes" button.
It will show the record was updated.

When the user chose to delete.

Android SQLite Example (Version 2)

$
0
0
Hi guys! Some friends told me that my previous Android Sqlite database tutorial was a bit not for beginners. So I'm posting another version of my Android Sqlite tutorial. This version is very simple, contains only two JAVA files, focuses on Android CRUD and hopefully easier to understand.

Android SQLite Example (Version 2) - Run
When you run this code.

You can download this code:


MainActivity.java - This is where our CRUD commands will be executed. The location object can also be found here.
packagecom.example.sqliteexample2;

importjava.util.List;

importandroid.os.Bundle;
importandroid.util.Log;
importandroid.app.Activity;

publicclassMainActivityextendsActivity {

// for our logs
publicstaticfinalStringLOG_TAG="MainActivity.java";

@Override
publicvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

DatabaseHandler databaseH =newDatabaseHandler(MainActivity.this);

// CREATE
LocationObjectLocationObj=newLocationObject("Quezon City",
"The place where I work.");
if (databaseH.create(LocationObj)) {
Log.v(LOG_TAG, "Record successfully created.");
}

// READ
List<LocationObject> locations = databaseH.read();
for (LocationObject record : locations) {
Log.v(LOG_TAG, "ID: "+ record.locationId);
Log.v(LOG_TAG, "Name: "+ record.locationName);
Log.v(LOG_TAG, "Description: "+ record.locationDescription);
}

// UPDATE
if (databaseH.update(1, "Quezon City, PH",
"The place where I work AND CODE.")) {
Log.v(LOG_TAG, "Record successfully updated.");
}

// DELETE
if (databaseH.delete(1)) {
Log.v(LOG_TAG, "Record successfully deleted.");
}
}

}

/*
* Represents location details or fields.
*/

classLocationObject {

publicint locationId;
publicString locationName;
publicString locationDescription;

// constructor for adding
publicLocationObject(StringlocationName, StringlocationDescription) {
this.locationName = locationName;
this.locationDescription = locationDescription;
}

// constructor for updating
publicLocationObject(intlocationId, StringlocationName,
StringlocationDescription) {
this.locationId = locationId;
this.locationName = locationName;
this.locationDescription = locationDescription;
}

}

DatabaseHandler.java - This handles all database operations or methods like creation, dropping, upgrading database version and ofcource, CRUD.
packagecom.example.sqliteexample2;

importjava.util.ArrayList;
importjava.util.List;

importandroid.content.ContentValues;
importandroid.content.Context;
importandroid.database.Cursor;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.database.sqlite.SQLiteOpenHelper;

publicclassDatabaseHandlerextendsSQLiteOpenHelper {

// for our logs
publicstaticfinalStringLOG_TAG="DatabaseHandler.java";

// database version
privatestaticfinalintDATABASE_VERSION=2;

// database name
protectedstaticfinalStringDATABASE_NAME="NinjaDatabase2";

// table details
publicString tableName ="locations";

publicString fieldLocationId ="id";
publicString fieldLocationName ="name";
publicString fieldLocationDescription ="description";

// constructor
publicDatabaseHandler(Contextcontext) {

super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

// creating Tables
@Override
publicvoidonCreate(SQLiteDatabasedb) {

String sql ="";

sql +="CREATE TABLE "+ tableName;
sql +=" ( ";
sql += fieldLocationId +" INTEGER PRIMARY KEY AUTOINCREMENT, ";
sql += fieldLocationName +" TEXT, ";
sql += fieldLocationDescription +" TEXT ";
sql +=" ) ";

db.execSQL(sql);

}

/*
* When upgrading the database, it will drop the current table and recreate.
*/

@Override
publicvoidonUpgrade(SQLiteDatabasedb, intoldVersion, intnewVersion) {

String sql ="DROP TABLE IF EXISTS "+ tableName;
db.execSQL(sql);

onCreate(db);
}

/*
* Create location record.
*
* @param - location contains location details to be added as single row.
*/

publicbooleancreate(LocationObjectlocation) {

boolean createSuccessful =false;

ContentValues values =newContentValues();

values.put(fieldLocationName, location.locationName);
values.put(fieldLocationDescription, location.locationDescription);

SQLiteDatabase db =this.getWritableDatabase();

createSuccessful = db.insert(tableName, null, values) >0;
db.close();

return createSuccessful;
}

/*
* Read all location record.
*/

publicList<LocationObject>read() {

List<LocationObject> recordsList =newArrayList<LocationObject>();

// select query
String sql ="";
sql +="SELECT * FROM "+ tableName;
sql +=" ORDER BY "+ fieldLocationId +" DESC";

SQLiteDatabase db =this.getWritableDatabase();

// execute the query
Cursor cursor = db.rawQuery(sql, null);

// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {

int locationId =Integer.parseInt(cursor.getString(cursor
.getColumnIndex(fieldLocationId)));

String locationName = cursor.getString(cursor
.getColumnIndex(fieldLocationName));

String locationDescription = cursor.getString(cursor
.getColumnIndex(fieldLocationDescription));

LocationObject location =newLocationObject(locationId,
locationName, locationDescription);

// add to list
recordsList.add(location);

} while (cursor.moveToNext());
}

// close the database
db.close();

// return the list of records
return recordsList;
}

/*
* Update location record.
*
* @param id - will identify which record is to be updated.
*
* @param name - the new location name to be saved.
*
* @param description - the new location description to be saved.
*/

publicbooleanupdate(intid, Stringname, Stringdescription) {

boolean updateSuccessful =false;

ContentValues values =newContentValues();

values.put(fieldLocationName, name);
values.put(fieldLocationDescription, description);

// you can use AND if you have multiple conditions
String where = fieldLocationId +" = ?";

// you should use commas when you have multiple conditions
String[] whereArgs = { Integer.toString(id) };

SQLiteDatabase db =this.getWritableDatabase();

// use the update command
updateSuccessful = db.update(tableName, values, where, whereArgs) >0;
db.close();

return updateSuccessful;
}

/*
* Delete location record.
*
* @param id - to identify which location record is to be deleted.
*/

publicbooleandelete(intid) {
boolean deleteSuccessful =false;

SQLiteDatabase db =this.getWritableDatabase();
deleteSuccessful = db.delete(tableName, "id ='"+ id +"'", null) >0;
db.close();

return deleteSuccessful;

}

/*
* For more methods like reading single record or counting records, see my
* full version of Android Sqlite tutorial, specifically,
* LocationTableController.java
*/

}

You can see the output of this code on your logcat. You can find the logcat in Window > Show View > Other > Search for "LogCat" Output should look like this:

Our logcat output.
The first line is our create command. Line 2 to 4 is our read command. Line 5 is our update and the last line, line 6 is our delete command.

Let me know if you have any questions. Hope you'll also check my previous Android Sqlite tutorial after you learn the basics from here! :)

Share URL, Text or Image with Android Share Intent

$
0
0
In today's tutorial, we are going to do a code that will enable your app to share a URL or text and Image to other apps installed in your Android device like Facebook, Twitter, Messaging, Instagram, Evernote, etc.. Example uses of this code include: 
  • You are building an app that browses a certain website or URL.
  • Your app generates an image that a user can share.
Android Share Intent - share text or url and image
Share your content.

You can download the code:

Android Share Intent download code free

MainActivity.java code

packagecom.example.androidshareurlintent;

importjava.io.File;

importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.view.View;
importandroid.app.Activity;
importandroid.content.Intent;

publicclassMainActivityextendsActivity {

@Override
publicvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// listeners of our two buttons
View.OnClickListener handler =newView.OnClickListener() {
publicvoidonClick(Viewv) {
switch (v.getId()) {

caseR.id.buttonShareTextUrl:
shareTextUrl();
break;

caseR.id.buttonShareImage:
shareImage();
break;
}
}
};

// our buttons
findViewById(R.id.buttonShareTextUrl).setOnClickListener(handler);
findViewById(R.id.buttonShareImage).setOnClickListener(handler);

}

/*
* Method to share either text or URL.
*/

privatevoidshareTextUrl() {
Intent share =newIntent(android.content.Intent.ACTION_SEND);
share.setType("text/plain");
share.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

// Add data to the intent, the receiving app will decide
// what to do with it.
share.putExtra(Intent.EXTRA_SUBJECT, "Title Of The Post");
share.putExtra(Intent.EXTRA_TEXT, "http://www.codeofaninja.com");

startActivity(Intent.createChooser(share, "Share link!"));
}

/*
* Method to share any image.
*/

privatevoidshareImage() {
Intent share =newIntent(Intent.ACTION_SEND);

// If you want to share a png image only, you can do:
// setType("image/png"); OR for jpeg: setType("image/jpeg");
share.setType("image/*");

// Make sure you put example png image named myImage.png in your
// directory
String imagePath =Environment.getExternalStorageDirectory()
+"/myImage.png";

File imageFileToShare =newFile(imagePath);

Uri uri =Uri.fromFile(imageFileToShare);
share.putExtra(Intent.EXTRA_STREAM, uri);

startActivity(Intent.createChooser(share, "Share Image!"));
}

}

Please note that when you use the setType() method, you are enabling Android to filter what apps can share your content. For example, you are sharing a text or URL, the appropriate apps to be shown can be Facebook, Messaging or Email. If you are sharing an image, proper apps can be Instagram, Snapseed or Picasa.

Output screenshots:

Main screen.
Share Text or URL button was touched. Take note of the apps on the list.

User chose to share to Facebook

"Share Image" button was touched. Apps was different on the list.

User chose to share with Gmail. Our image was attached.

User chose to share to Snapseed.

Ways to Create a Splash Screen for Android App

$
0
0
Today we're going to create a splash screen for your Android app. A splash screen is usually an image or a view that appears to the user while the app is loading, it is also a way to make your brand or logo easier to be recognize by the user. Some android apps that uses splash screens include Facebook, Pocket and of course, the game apps. I'm going to show you two ways to create android splash screens.

Example logo to be seen in our splash screen.

Splash Screen With Two Activities


The first way I'm gonna teach you is using two activities, the first activity will be our splash screen and the second activity will be our app's main screen. The splash screen activity will  be shown for four seconds and then it will show the next activity. Download the code here:

download code - Ways to Code a Splash Screen for Android

Here are the files we need:

Highlighted are the files we have to create.

SplashScreenActivity.java - The initial activity executed. This activity will end with an animation that depends on the device.
packagecom.example.splashscreenexample;

importjava.util.Timer;
importjava.util.TimerTask;

importandroid.os.Bundle;
importandroid.view.Window;
importandroid.app.Activity;
importandroid.content.Intent;

/*
* This is our first activity.
*/

publicclassSplashScreenActivityextendsActivity {

@Override
publicvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);

// remove title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);

// our layout xml
setContentView(R.layout.activity_splash_screen);

// we're gonna use a timer task to show the main activity after 4 seconds
TimerTask task =newTimerTask() {

@Override
publicvoidrun() {

// go to the main activity
Intent nextActivity =newIntent(SplashScreenActivity.this,
MainActivity.class);
startActivity(nextActivity);

// make sure splash screen activity is gone
SplashScreenActivity.this.finish();

}

};

// Schedule a task for single execution after a specified delay.
// Show splash screen for 4 seconds
newTimer().schedule(task, 4000);

}

}


MainActivity.java - Our app's main screen, where the main functions of your app should be seen.
packagecom.example.splashscreenexample;

importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.Window;

publicclassMainActivityextendsActivity {

@Override
publicvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);

// remove title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);

// our main activity layout
setContentView(R.layout.activity_main);

}
}


codeofaninja350pxwidth.png - An example image used in the splash screen. This is included in the code download.

Splash Screen with One Activity


The second way to create a splash screen is using just one activity - your MainActivity. It should be covered with an ImageView first and then after few seconds, it will disappear with a simple fade-out animation to make it look smooth. Download code this code:


Files we need are highlighted below:

We'll work on three files in this example.

MainActivitity.java - The file with double purpose, it will show our splash screen and then main screen.
packagecom.example.splashscreenexample2;

importjava.util.Timer;
importjava.util.TimerTask;

importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.view.View;
importandroid.view.Window;
importandroid.view.animation.Animation;
importandroid.view.animation.AnimationUtils;
importandroid.widget.ImageView;

publicclassMainActivityextendsActivity {

@Override
publicvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);

// remove title bar.
requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.activity_main);

// our timer task.
TimerTask task =newTimerTask() {

@Override
publicvoidrun() {

// we have to run it on UI thread so we won't get view error
MainActivity.this.runOnUiThread(newRunnable() {
publicvoidrun() {

// get the splash image
ImageView splashImage = (ImageView) MainActivity.this
.findViewById(R.id.imageViewSplashLogo);

// make the splash image invisible
splashImage.setVisibility(View.GONE);

// specify animation
Animation animFadeOut =AnimationUtils.loadAnimation(MainActivity.this,
R.anim.splash_screen_fadeout);

// apply the animattion
splashImage.startAnimation(animFadeOut);

}
});

}

};

// Schedule a task for single execution after a specified delay.
// Show splash screen for 4 seconds
newTimer().schedule(task, 4000);

}

}


splash_screen_fadeout.xml - It will make our splash screen gone beautifully - a simple fade-out animation.
<?xml version="1.0" encoding="utf-8"?>
<!--
-zAdjustment makes sure the activity is on top
-interpolator defines the rate of change of an animation
-we use decelerate_interpolator to reduce animation speed from visible (Alpha 1.0) to invisible (Alpha 0.0)
-->

<alphaxmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromAlpha="1.0"
android:interpolator="@android:anim/decelerate_interpolator"
android:toAlpha="0.0"
android:zAdjustment="top" />


codeofaninja350pxwidth.png - our example logo.

Output screenshots:

Ways to Code a Splash Screen for Android
Splash screen.

Main Activity.

Parse XML in Android With Three Input Sources

$
0
0
XML parsing could be one of the most basic requirement on your Android application. In today's tutorial, we are going to read XML files using three input sources. There can be three sources of your XML:
  1. XML from device SD Card. Your dynamic XML file could be downloaded first for offline use.
  2. XML from a URL. You could be parsing data from your online database or RSS feed. Works if device is online only.
  3. XML from your app's assets folder. Your XML file is not dynamic so it is better to put it in the asset's folder where it cannot be change.
By the way, we'll be using SAX parser here. I think that for mobile apps, SAX parser is better to use than DOM parser.DOM parser consumes more memory because it loads the whole XML data to the device memory while SAX parser does an event driven approach. SAX parser processes each line of the XML without loading it to the device memory first.

Parse XML in Android tutorial
Our code's logcat final output. Click to enlarge.

You can download our code here:

download code for Parse XML in Android tutorial

Our XML structure looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<Contents>
<Owners>
<Owner>
<Name>Joselito Dimaculangan</Name>
<Age>16</Age>
<EmailAddress>joselito123@gmail.com</EmailAddress>
</Owner>
<Owner>
<Name>Noemi De Galileo</Name>
<Age>14</Age>
<EmailAddress>noemi111@gmail.com</EmailAddress>
</Owner>
</Owners>
<Dogs>
<Dog>
<Name>Barky</Name>
<Birthday>June 29, 2012</Birthday>
</Dog>
<Dog>
<Name>Jumbo</Name>
<Birthday>December 30, 2012</Birthday>
</Dog>
</Dogs>
</Contents>

MainActivity.java code - Here you can change the value of x to 1,2 or 3 to change the input source. Read comments on code.
packagecom.example.androidparsexml;

importjava.io.File;
importjava.io.FileInputStream;
importjava.net.URL;
importjava.util.Iterator;
importjava.util.List;

importjavax.xml.parsers.SAXParser;
importjavax.xml.parsers.SAXParserFactory;

importorg.xml.sax.InputSource;
importorg.xml.sax.XMLReader;

importandroid.os.AsyncTask;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.util.Log;
importandroid.app.Activity;

publicclassMainActivityextendsActivity {

publicstaticfinalStringLOG_TAG="MainActivity.java";

@Override
publicvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

try {

// parse our XML
new parseXmlAsync().execute();

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/*
* @We are using an AsyncTask to avoid
* android.os.NetworkOnMainThreadException when parsing from a URL
*
* @If you don't know a thing about AsyncTasks,there are a lot of excellent
* tutorial out there, see this thread
*/

privateclassparseXmlAsyncextendsAsyncTask<String, String, String> {

@Override
protectedStringdoInBackground(String... strings) {

try {

/*
* You may change the value of x to try different sources of XML
*
* @1 = XML from SD Card
*
* @2 = XML from URL
*
* @3 = XML from assets folder
*/

int x =2;

// initialize our input source variable
InputSource inputSource =null;

// XML from sdcard
if (x ==1) {

// make sure sample.xml is in your root SD card directory
File xmlFile =newFile(
Environment.getExternalStorageDirectory()
+"/sample.xml");
FileInputStream xmlFileInputStream =newFileInputStream(
xmlFile);
inputSource =newInputSource(xmlFileInputStream);
}

// XML from URL
elseif (x ==2) {
// specify a URL
// make sure you are connected to the internet
URL url =newURL(
"http://demo.codeofaninja.com/AndroidXml/sample.xml");
inputSource =newInputSource(url.openStream());
}

// XML from assets folder
elseif (x ==3) {
inputSource =newInputSource(getAssets()
.open("sample.xml"));
}

// instantiate SAX parser
SAXParserFactory saxParserFactory =SAXParserFactory
.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();

// get the XML reader
XMLReader xmlReader = saxParser.getXMLReader();

// prepare and set the XML content or data handler before
// parsing
XmlContentHandler xmlContentHandler =newXmlContentHandler();
xmlReader.setContentHandler(xmlContentHandler);

// parse the XML input source
xmlReader.parse(inputSource);

// put the parsed data to a List
List<ParsedDataSet> parsedDataSet = xmlContentHandler
.getParsedData();

// we'll use an iterator so we can loop through the data
Iterator<ParsedDataSet> i = parsedDataSet.iterator();
ParsedDataSet dataItem;

while (i.hasNext()) {

dataItem = (ParsedDataSet) i.next();

/*
* parentTag can also represent the main type of data, in
* our example, "Owners" and "Dogs"
*/

String parentTag = dataItem.getParentTag();
Log.v(LOG_TAG, "parentTag: "+ parentTag);

if (parentTag.equals("Owners")) {
Log.v(LOG_TAG, "Name: "+ dataItem.getName());
Log.v(LOG_TAG, "Age: "+ dataItem.getAge());
Log.v(LOG_TAG,
"EmailAddress: "+ dataItem.getEmailAddress());
}

elseif (parentTag.equals("Dogs")) {
Log.v(LOG_TAG, "Name: "+ dataItem.getName());
Log.v(LOG_TAG, "Birthday: "+ dataItem.getBirthday());
}

}

} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
returnnull;
}

@Override
protectedvoidonPostExecute(StringlenghtOfFile) {
// your do stuff after parsing the XML
}
}

}


XmlContentHandler.java - We'll extend the default handler.
packagecom.example.androidparsexml;

importjava.util.ArrayList;
importjava.util.List;

importorg.xml.sax.Attributes;
importorg.xml.sax.SAXException;
importorg.xml.sax.helpers.DefaultHandler;

importandroid.util.Log;

publicclassXmlContentHandlerextendsDefaultHandler {

privatestaticfinalStringLOG_TAG="XmlContentHandler";

// used to track of what tags are we
privateboolean inOwner =false;
privateboolean inDog =false;

// accumulate the values
privateStringBuilder mStringBuilder =newStringBuilder();

// new object
privateParsedDataSet mParsedDataSet =newParsedDataSet();

// the list of data
privateList<ParsedDataSet> mParsedDataSetList =newArrayList<ParsedDataSet>();

/*
* Called when parsed data is requested.
*/

publicList<ParsedDataSet>getParsedData() {
Log.v(LOG_TAG, "Returning mParsedDataSetList");
returnthis.mParsedDataSetList;
}

// Methods below are built in, we just have to do the tweaks.

/*
* @Receive notification of the start of an element.
*
* @Called in opening tags such as <Owner>
*/

@Override
publicvoidstartElement(StringnamespaceURI, StringlocalName,
StringqName, Attributesatts) throwsSAXException {

if (localName.equals("Owner")) {
// meaning new data object will be made
this.mParsedDataSet =newParsedDataSet();
this.inOwner =true;
}

elseif (localName.equals("Dog")) {
this.mParsedDataSet =newParsedDataSet();
this.inDog =true;
}

}

/*
* @Receive notification of the end of an element.
*
* @Called in end tags such as </Owner>
*/

@Override
publicvoidendElement(StringnamespaceURI, StringlocalName, StringqName)
throwsSAXException {

// Owners
if (this.inOwner ==true&& localName.equals("Owner")) {
this.mParsedDataSetList.add(mParsedDataSet);
mParsedDataSet.setParentTag("Owners");
this.inOwner =false;
}

elseif (this.inOwner ==true&& localName.equals("Name")) {
mParsedDataSet.setName(mStringBuilder.toString().trim());
}

elseif (this.inOwner ==true&& localName.equals("Age")) {
mParsedDataSet.setAge(mStringBuilder.toString().trim());
}

elseif (this.inOwner ==true&& localName.equals("EmailAddress")) {
mParsedDataSet.setEmailAddress(mStringBuilder.toString().trim());
}

// Dogs
if (this.inDog ==true&& localName.equals("Dog")) {
this.mParsedDataSetList.add(mParsedDataSet);
mParsedDataSet.setParentTag("Dogs");
this.inDog =false;
}

elseif (this.inDog ==true&& localName.equals("Name")) {
mParsedDataSet.setName(mStringBuilder.toString().trim());
}

elseif (this.inDog ==true&& localName.equals("Birthday")) {
mParsedDataSet.setBirthday(mStringBuilder.toString().trim());
}

// empty our string builder
mStringBuilder.setLength(0);
}

/*
* @Receive notification of character data inside an element.
*
* @Gets be called on the following structure: <tag>characters</tag>
*/

@Override
publicvoidcharacters(charch[], intstart, intlength) {
// append the value to our string builder
mStringBuilder.append(ch, start, length);
}
}

ParsedDataSet.java - You can use your own object class if the XML you're parsing is for a more specific data object. For example, you are parsing only for "Owners" and NOT "Owners & Dogs" like what we have.
packagecom.example.androidparsexml;

importjava.util.ArrayList;
importjava.util.List;

importorg.xml.sax.Attributes;
importorg.xml.sax.SAXException;
importorg.xml.sax.helpers.DefaultHandler;

importandroid.util.Log;

publicclassXmlContentHandlerextendsDefaultHandler {

privatestaticfinalStringLOG_TAG="XmlContentHandler";

// used to track of what tags are we
privateboolean inOwner =false;
privateboolean inDog =false;

// accumulate the values
privateStringBuilder mStringBuilder =newStringBuilder();

// new object
privateParsedDataSet mParsedDataSet =newParsedDataSet();

// the list of data
privateList<ParsedDataSet> mParsedDataSetList =newArrayList<ParsedDataSet>();

/*
* Called when parsed data is requested.
*/

publicList<ParsedDataSet>getParsedData() {
Log.v(LOG_TAG, "Returning mParsedDataSetList");
returnthis.mParsedDataSetList;
}

// Methods below are built in, we just have to do the tweaks.

/*
* @Receive notification of the start of an element.
*
* @Called in opening tags such as <Owner>
*/

@Override
publicvoidstartElement(StringnamespaceURI, StringlocalName,
StringqName, Attributesatts) throwsSAXException {

if (localName.equals("Owner")) {
// meaning new data object will be made
this.mParsedDataSet =newParsedDataSet();
this.inOwner =true;
}

elseif (localName.equals("Dog")) {
this.mParsedDataSet =newParsedDataSet();
this.inDog =true;
}

}

/*
* @Receive notification of the end of an element.
*
* @Called in end tags such as </Owner>
*/

@Override
publicvoidendElement(StringnamespaceURI, StringlocalName, StringqName)
throwsSAXException {

// Owners
if (this.inOwner ==true&& localName.equals("Owner")) {
this.mParsedDataSetList.add(mParsedDataSet);
mParsedDataSet.setParentTag("Owners");
this.inOwner =false;
}

elseif (this.inOwner ==true&& localName.equals("Name")) {
mParsedDataSet.setName(mStringBuilder.toString().trim());
}

elseif (this.inOwner ==true&& localName.equals("Age")) {
mParsedDataSet.setAge(mStringBuilder.toString().trim());
}

elseif (this.inOwner ==true&& localName.equals("EmailAddress")) {
mParsedDataSet.setEmailAddress(mStringBuilder.toString().trim());
}

// Dogs
if (this.inDog ==true&& localName.equals("Dog")) {
this.mParsedDataSetList.add(mParsedDataSet);
mParsedDataSet.setParentTag("Dogs");
this.inDog =false;
}

elseif (this.inDog ==true&& localName.equals("Name")) {
mParsedDataSet.setName(mStringBuilder.toString().trim());
}

elseif (this.inDog ==true&& localName.equals("Birthday")) {
mParsedDataSet.setBirthday(mStringBuilder.toString().trim());
}

// empty our string builder
mStringBuilder.setLength(0);
}

/*
* @Receive notification of character data inside an element.
*
* @Gets be called on the following structure: <tag>characters</tag>
*/

@Override
publicvoidcharacters(charch[], intstart, intlength) {
// append the value to our string builder
mStringBuilder.append(ch, start, length);
}
}

Our AndroidManifest.xml will have internet permissions because we use a URL input
<uses-permissionandroid:name="android.permission.INTERNET" />

Our code output on the device look simply like this:

Parse XML in Android tutorial device output
Device output.



Customized List Items in Android ListView

$
0
0
Almost all Android apps uses ListView - showing list of records, settings, songs, articles, and many other types of data a certain app can handle. A ListView is simply a vertically scrollable list of items.This tutorial will show you how to create a customized list item in your ListView. This is probably the simplest android ListView tutorial on the internet. Haha! I remember using a ListView when I have to list records of location with its thumbnail, location name and date the data were taken.

Upper part of our ListView

Anyway, we are going to have Folders as our items on the list. Our code will have the following capability:

  • Include custom folder icon, folder name and description for each list item.
  • Show a toast when a user clicks on an item on the list (means we're going to have an onClickListener)
You can download the code here: (If you're not familiar with Google Drive, you have to click on File > Download to download the code)

android listview tutorial download code

We are going to need only 2 JAVA files, 2 XML files and 3 custom icons.

Highlighted are the files we'll create.

activity_main.xml - Contains our ListView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF"
android:orientation="vertical">

<ListView
android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />

</LinearLayout>

listview_item_row.xml - the layout of each list item in our list view.
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp">

<ImageView
android:id="@+id/imageViewFolderIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:paddingRight="10dp"
android:src="@drawable/folder" />

<TextView
android:id="@+id/textViewFolderName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/imageViewFolderIcon"
android:text="Folder name here."
android:textSize="20dp" />

<TextView
android:id="@+id/textViewFolderDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewFolderName"
android:layout_toRightOf="@+id/imageViewFolderIcon"
android:text="Folder description here."
android:textColor="#c5c5c5"
android:textSize="14dp" />

</RelativeLayout>
It will look like this:


-Folder Icon
     android:id="@+id/imageViewFolderIcon"
     android:layout_alignParentLeft="true"
     android:layout_alignParentTop="true"

-Folder Name
     android:id="@+id/textViewFolderName"
     android:layout_alignParentTop="true"
     android:layout_toRightOf="@+id/imageViewFolderIcon"

-Folder Description
     android:id="@+id/textViewFolderDescription"
     android:layout_below="@+id/textViewFolderName"
     android:layout_toRightOf="@+id/imageViewFolderIcon"

MainActivity.java - We have two classes in this file, first is the MainActivity where we set each of our list item data and second is the small Folder class that will take care of our list item data such as the folderIcon, folderName and folderDescription.
packagecom.example.androidlistview;

importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.view.View;
importandroid.widget.AdapterView;
importandroid.widget.ListView;
importandroid.widget.TextView;
importandroid.widget.Toast;
importandroid.widget.AdapterView.OnItemClickListener;

publicclassMainActivityextendsActivity {

privateListView listViewArticles;

@Override
publicvoidonCreate(BundlesavedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

/*
* Data can be from your database. You have to know the number of list
* items in advanced, in our example, we have 9
*/

Folder[] folderData =newFolder[9];

/*
* @always start with index 0
*
* @9 items in our list view.
*/

folderData[0] =newFolder(R.drawable.icon_music_folder, "Usher",
"My most favorite Usher songs.");

folderData[1] =newFolder(R.drawable.icon_pictures_folder,
"Family Images", "Pictures from different occasions.");

folderData[2] =newFolder(R.drawable.icon_spreadsheet_folder,
"Budget Spreadsheet", "My budget record every week.");

folderData[3] =newFolder(R.drawable.icon_music_folder, "FM Static",
"One of my most favorite bands.");

folderData[4] =newFolder(R.drawable.icon_pictures_folder,
"Outing 2012", "Pictures in Boracay Island.");

folderData[5] =newFolder(R.drawable.icon_spreadsheet_folder,
"Business Spreadsheet", "Business accounts record.");

folderData[6] =newFolder(R.drawable.icon_music_folder, "New Artists",
"Cool songs by new artists.");

folderData[7] =newFolder(R.drawable.icon_pictures_folder,
"Anniversary 2012", "Company party.");

folderData[8] =newFolder(R.drawable.icon_spreadsheet_folder,
"Credit Spreadsheet", "Credit records every month.");

// Pass the folderData to our ListView adapter
FolderAdapter adapter =newFolderAdapter(this,
R.layout.listview_item_row, folderData);

// Set the adapter to our ListView
listViewArticles = (ListView) findViewById(R.id.listView1);
listViewArticles.setAdapter(adapter);

/*
* ListView item click listener. So we'll have the do stuff on click of
* our ListItem
*/

listViewArticles.setOnItemClickListener(newOnItemClickListener() {
publicvoidonItemClick(AdapterView<?>parent, Viewview,
intposition, longid) {

// get the clicked folder name
String listItemText = ((TextView) view
.findViewById(R.id.textViewFolderName)).getText()
.toString();

// just toast it
Toast.makeText(MainActivity.this,
"You clicked: "+ listItemText, Toast.LENGTH_LONG)
.show();

}
});
}

/*
* You can put this in another java file. This will hold the data elements
* of our list item.
*/

classFolder {

publicint folderIcon;
publicString folderName;
publicString folderDescription;

// Constructor.
publicFolder(intfolderIcon, StringfolderName,
StringfolderDescription) {

this.folderIcon = folderIcon;
this.folderName = folderName;
this.folderDescription = folderDescription;
}
}
}


FolderAdapter.java - This file will make the list items come true. We'll override the getView to set our customized data.
packagecom.example.androidlistview;

importcom.example.androidlistview.MainActivity.Folder;

importandroid.app.Activity;
importandroid.content.Context;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.ArrayAdapter;
importandroid.widget.ImageView;
importandroid.widget.TextView;

publicclassFolderAdapterextendsArrayAdapter<Folder> {

Context mContext;
int layoutResourceId;
Folder data[] =null;

/*
* @mContext - app context
*
* @layoutResourceId - the listview_item_row.xml
*
* @data - the ListItem data
*/

publicFolderAdapter(ContextmContext, intlayoutResourceId, Folder[] data) {

super(mContext, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.mContext = mContext;
this.data = data;
}

/*
* @We'll overried the getView method which is called for every ListItem we
* have.
*
* @There are lots of different caching techniques for Android ListView to
* achieve better performace especially if you are going to have a very long
* ListView.
*/

@Override
publicViewgetView(intposition, ViewconvertView, ViewGroupparent) {

View listItem = convertView;

// inflate the listview_item_row.xml parent
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
listItem = inflater.inflate(layoutResourceId, parent, false);

// get the elements in the layout
ImageView imageViewFolderIcon = (ImageView) listItem
.findViewById(R.id.imageViewFolderIcon);

TextView textViewFolderName = (TextView) listItem
.findViewById(R.id.textViewFolderName);

TextView textViewFolderDescription = (TextView) listItem
.findViewById(R.id.textViewFolderDescription);

/*
* Set the data for the list item. You can also set tags here if you
* want.
*/

Folder folder = data[position];

imageViewFolderIcon.setImageResource(folder.folderIcon);
textViewFolderName.setText(folder.folderName);
textViewFolderDescription.setText(folder.folderDescription);

return listItem;
}

}


Output screenshots:

Lower part of our ListView

When user clicks on an item
"Budget Spreadsheet"

How Do You Start A Facebook Page?

$
0
0
Hi guys! Most of the top posts here in my blog is related to web development with Facebook. Many asks beforehand how to create a Facebook page where we will pull our data. So here's a step by step tutorial on how to do such task.

Our final output. Click to enlarge.

Photos are kinda small, you have to click each photos below to enlarge.

Step 1

Go to Facebook "Create A Page" section that can be found in this link: Create a Page. You should see this page:

Create a Facebook page.

Step 2

In this example, we are going to create a "Brand or Product" for our website. Click "Brand or Product" box and fill up the required filled. 

On the "Category" dropdown, select "Website".
On the "Brand or Product Name" field, I'll enter "Mike Dalisay Works" for example.
Check "I agree to Facebook Pages Terms" checkbox.

It should look like this:

Creating a brand or product Facebook page.

Step 3

Click the "Get Started" button. It will make you set up some information for your Facebook page such as profile picture, about, Facebook web address, and enable ads option. Just follow the flow.

Facebook page info set up.

Facebook page profile picture.

Facebook page "About" info

Facebook web address.

Enable ads. You can click the skip button.

Step 4

At this stage, you already have successfully created your Facebook page! Congrats! Now Facebook will give you some guidelines on how to use your Facebook page.

Like your own page.

Invite others to like your page.

Do your first post!


Solving Your Table Row Data's Long List Of Options

$
0
0
When building a web application, there are some situations where you want to have long list options for a table row data. Like in our example for today, I have a list of "Authors", I wanna have the ability to go to their websites, list of articles, or social networking links easily when the list is shown, but of course, the "Options" column space is limited.

jquery slideToggle example
Click to enlarge.

Here is how I solved it.

  • I only put three options on the first load. As you can see we have "Edit", "Delete" and "More" options.
  • The "More" options which is highlighted in "green" will give the user a cue that it can be clicked and more options will be shown, it will beautifully animate to show "more options".
  • "More" text will become "Less" and will be highlighted in "red" which will give the user a cue that you can hide the options.
jquery slideToggle tutorial
Click to enlarge.

download code for jquery slideToggle example  live demo for jquery slideToggle example

CSS code - styling our table.

body{
font-family:arial,sans-serif;
}

tablea{
color:#039;
font-weight:bold;
text-decoration:none;
}

tablea:hover{
color:#000;
font-weight:bold;
}

th {
background-color:#b9c9fe;
color:#039;
padding:10px;
}

td {
background-color:#e8edff;
padding:10px;
}

.verticalOption{
margin:8px0;
}

.moreOptionsLink{
background-color:green;
color:#fff;
padding:02px;
}

.moreOptionsLink:hover{
color:#fff;
}

.moreOptions{
display:none;
}


HTML code - we are using static HTML in this example, in the real world, this HTML should be generated dynamically.

<!-- our example table -->
<tableborder='0'cellpadding='2'>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Username</th>
<th>Options</th>
</tr>
<tr>
<td>JM</td>
<td>Dalisay</td>
<td>jm@gmail.com</td>
<td>dalisay</td>
<td>
<!-- It is important to understand our "Options" HTML structure. -->
<ahref="">Edit</a> /
<ahref="">Delete</a> /
<ahref=""class="moreOptionsLink">More</a>

<!--
Here are the hidden "moreOptions"
which will be shown when "More" was clicked
and hidden when "Less" was clicked
-->

<divclass="moreOptions">
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Articles</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">View Online</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Website</a>
</div>
<divclass="verticalOption">
<ahref="https://www.facebook.com/CodeOfANinja"target="_blank">Facebook</a>
</div>
<divclass="verticalOption">
<ahref="http://twitter.com/ninjazhai"target="_blank">Twitter</a>
</div>
<divclass="verticalOption">
<ahref="https://plus.google.com/103126728967620382717"target="_blank">Google+</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">LinkedIn</a>
</div>
</div>
</td>
</tr>
<!-- more table rows should be here -->
</table>

jQuery code - the animation and magic. :)

<!-- include our jQuery -->
<scriptsrc="js/jquery-1.9.1.min.js"></script>
<script>
$(document).ready(function(){

// when "More" or "Less" (class moreOptionsLink) was clicked.
$(".moreOptionsLink").click(function(){

var txt =$(this).text();

if(txt=='More'){
/*
* change the text to "Less"
* change the background color to "red"
* which means it shows all the options
*/

$(this).text('Less');
$(this).css("background-color","red");
}

else{
/*
* change the text to "More"
* change the background color to "green"
* which means it hides other options
*/

$(this).text('More');
$(this).css("background-color","green");
}

/*
* to animate the container of other options
* we use jQuery "next" to select the "moreOptions" of the current row
*/

$(this).next(".moreOptions").slideToggle("fast");

// so that it won't refresh the page
returnfalse;
});
});
</script>

Codes combined:

<html>
<head>
<title>A Way To Solve Long List Of Options Of Your Table Row Data</title>

<!-- just some styling -->
<style>
body{
font-family:arial,sans-serif;
}

tablea{
color:#039;
font-weight:bold;
text-decoration:none;
}

tablea:hover{
color:#000;
font-weight:bold;
}

th {
background-color:#b9c9fe;
color:#039;
padding: 10px;
}

td {
background-color:#e8edff;
padding: 10px;
}

.verticalOption{
margin:8px 0;
}

.moreOptionsLink{
background-color:green;
color:#fff;
padding: 0 2px;
}

.moreOptionsLink:hover{
color:#fff;
}

.moreOptions{
display:none;
}

</style>
</head>
<body>

<!-- our example table -->
<tableborder='0'cellpadding='2'>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Username</th>
<th>Options</th>
</tr>
<tr>
<td>JM</td>
<td>Dalisay</td>
<td>jm@gmail.com</td>
<td>dalisay</td>
<td>
<!-- It is important to understand our "Options" HTML structure. -->
<ahref="">Edit</a> /
<ahref="">Delete</a> /
<ahref=""class="moreOptionsLink">More</a>

<!--
Here are the hidden "moreOptions"
which will be shown when "More" was clicked
and hidden when "Less" was clicked
-->

<divclass="moreOptions">
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Articles</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">View Online</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Website</a>
</div>
<divclass="verticalOption">
<ahref="https://www.facebook.com/CodeOfANinja"target="_blank">Facebook</a>
</div>
<divclass="verticalOption">
<ahref="http://twitter.com/ninjazhai"target="_blank">Twitter</a>
</div>
<divclass="verticalOption">
<ahref="https://plus.google.com/103126728967620382717"target="_blank">Google+</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">LinkedIn</a>
</div>
</div>
</td>
</tr>
<tr>
<td>Edward</td>
<td>Morden</td>
<td>edward_cullen@yahoo.com</td>
<td>edward</td>
<td>
<ahref="">Edit</a> /
<ahref="">Delete</a> /
<ahref=""class="moreOptionsLink">More</a>
<divclass="moreOptions">
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Articles</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">View Online</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Website</a>
</div>
<divclass="verticalOption">
<ahref="https://www.facebook.com/CodeOfANinja"target="_blank">Facebook</a>
</div>
<divclass="verticalOption">
<ahref="http://twitter.com/ninjazhai"target="_blank">Twitter</a>
</div>
<divclass="verticalOption">
<ahref="https://plus.google.com/103126728967620382717"target="_blank">Google+</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">LinkedIn</a>
</div>
</div>
</td>
</tr>
<tr>
<td>Vanessa</td>
<td>Hudgens</td>
<td>vane@yahoo.com</td>
<td>vanessa</td>
<td>
<ahref="">Edit</a> /
<ahref="">Delete</a> /
<ahref=""class="moreOptionsLink">More</a>
<divclass="moreOptions">
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Articles</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">View Online</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Website</a>
</div>
<divclass="verticalOption">
<ahref="https://www.facebook.com/CodeOfANinja"target="_blank">Facebook</a>
</div>
<divclass="verticalOption">
<ahref="http://twitter.com/ninjazhai"target="_blank">Twitter</a>
</div>
<divclass="verticalOption">
<ahref="https://plus.google.com/103126728967620382717"target="_blank">Google+</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">LinkedIn</a>
</div>
</div>
</td>
</tr>
<tr>
<td>Michael</td>
<td>Jackson</td>
<td>mike@gmail.com</td>
<td>michael</td>
<td>
<ahref="">Edit</a> /
<ahref="">Delete</a> /
<ahref=""class="moreOptionsLink">More</a>
<divclass="moreOptions">
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Articles</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">View Online</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">Website</a>
</div>
<divclass="verticalOption">
<ahref="https://www.facebook.com/CodeOfANinja"target="_blank">Facebook</a>
</div>
<divclass="verticalOption">
<ahref="http://twitter.com/ninjazhai"target="_blank">Twitter</a>
</div>
<divclass="verticalOption">
<ahref="https://plus.google.com/103126728967620382717"target="_blank">Google+</a>
</div>
<divclass="verticalOption">
<ahref="http://codeofaninja.com/"target="_blank">LinkedIn</a>
</div>
</div>
</td>
</tr>
</table>

<!-- include our jQuery -->
<scriptsrc="js/jquery-1.9.1.min.js"></script>
<script>
$(document).ready(function(){

// when "More" or "Less" (class moreOptionsLink) was clicked.
$(".moreOptionsLink").click(function(){

var txt =$(this).text();

if(txt=='More'){
/*
* change the text to "Less"
* change the background color to "red"
* which means it shows all the options
*/

$(this).text('Less');
$(this).css("background-color","red");
}

else{
/*
* change the text to "More"
* change the background color to "green"
* which means it hides other options
*/

$(this).text('More');
$(this).css("background-color","green");
}

/*
* to animate the container of other options
* we use jQuery "next" to select the "moreOptions" of the current row
*/

$(this).next(".moreOptions").slideToggle("fast");

// so that it won't refresh the page
returnfalse;
});
});
</script>

</body>
</html>

How To Get Facebook App ID and Secret Keys?

$
0
0
After creating a Facebook page where we will pull our data, we have to create an app to get an appId and appSecret keys. Those keys are required to use the Facebook PHP SDK and do our queries like pulling Facebook photos, events, videos, and feeds. Here's a step by step tutorial on how to get those keys.

Facebook developer apps dashboard.

Step 1

Here's the link where you would start: create a Facebook app. On the pop up, specify your app name (the name of your website or app) and app namespace (used for your Facebook app URL e.g., http://apps.facebook.com/yournamespace) 

Facebook appId and appSecret
Creating an app. Click to enlarge.

Step 2

You'll be asked to enter a security code to verify that you're a human and not a bot or malware that creates random Facebook apps. After entering the text in the box, click the "Continue" button.

Facebook appId and appSecret - security check
A security check. Click to enlarge.

Step 3

Congrats! now you can copy your Facebook appId and appSecret. See the arrows below.

copy your Facebook appId and appSecret
Your Facebook appId and appSecret keys. Click to enlarge.


Resposive Web Design Testing Tools

$
0
0
Hello geeks! This is a quick guide on how you can test your responsive website without actual gadgets or devices. I personally recommend these tools for testing on devices such as smartphones, laptops, tablets, and TVs. We are going to have two categories: Browser Extensions and Online Tools.

Browser Extensions

1. Internet Explorer - You should have Microsoft Internet Explorer Developer Toolbar which can be downloaded on this link: Internet Explorer Developer Toolbar. After installing, you have to press F12 on your keyboard to use this tool.

EI Developer Toolbar. Click to enlarge.

2. Firefox - For Firefox users, you may use Firesizer which can be downloaded on this link: Firesizer. To use this, you have to enable your addon bar:

Enable Add-on bar for Firesizer. Click to enlarge.

Then on the add-on bar look for the Firesizer function which is located on the lower right corner of Firefox, you have to right click to customize the sizes.

Using Firesizer. Click to enlarge.

You may also try Responsive Design View on Firefox > Web Developer > Responsive Web Design or Ctrl + Shift + M for keyboard shortcut.

Firefox Responsive Web Design View. Click to enlarge.

3. Google Chrome - Chrome has Window Resizer, you can install this awesome Chrome extension from this link: Window Resizer

Google Chrome Window Resizer. Click to enlarge.

Online Tools

1. Screenfly - Allows you to enter your website URL and gives you many view options for testing such as Netbooks, Desktop, Kindle Fire, iPad 1-3/Mini, Nexus 7, Motorola Razr, Blackberry, LG optimus, Galaxy SIII, iPhones, and Television views (480p, 720p, 1080p). It also allows you to specify custom screen size and rotate the screen view. This is my favorite online testing tool.

Screenfly.

2. Responsinator - Also allows you to enter your website URL (located on the upper left corner) and gives you the available views in one load which is kinda fast and convenient, you just have to scroll down. The available views is limited to iPhone (3,4,5), iPad, Kindle, and Samsung Galaxy. All has portrait and landscape mode.

Responsinator.

3. Responsivetest- Also allows you to enter your responsive website URL (located on the upper left corner) and loads the view one at a time, depends on your device selection. Screens are limited to XGA, WXGA, iPad, Kindle Fire, iPhone and Android phones (320 x 240 and 515 x 295), also has landscape and portrait mode.

responsivetest.net

By the way, the example website we used in this post is this responsive web design live demo. The tutorial for coding a responsive website can be found here: Coding A Responsive Website Design.

Let us know in the comments what testing tools do you use? :)
Viewing all 100 articles
Browse latest View live