Thursday, 2 January 2014

Android Example: Calling Javascript from Android Java coding


In Android application, WebView is the component for display web pages. As Hybrid application are popular now, there are needs of calling javascript method from Android Java coding. We can do this by implement the addJavascriptInterface method in WebView.
The following example demonstarte this:
Step 1: Create a new Android project "JavascriptDemo" in Eclipse. A html web page is created in the assests directory.


Step 2: Modify activity_javascript_demo.xml layout document. Add a button in the WebView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    >  
  <TextView    
        android:layout_width="fill_parent"   
        android:layout_height="wrap_content"   
        android:text="Hello World!!"  
        />  
    <WebView  
        android:id="@+id/webview"  
        android:layout_width="fill_parent"   
        android:layout_height="wrap_content"   
    />  
    <Button  
        android:id="@+id/button"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="Change the webview content"  
    />  

</LinearLayout>  
Step 3: Create a demo.html file under assest directory.
 <html>  
     <script language="javascript"><!--  
    
  function fillContent(){  
      document.getElementById("content").innerHTML =   
    "This Content is showed by Android invoked Javascript function.";  
  }  
       
 // --></script>    
   <body>  
     <p><a onClick="window.demo.startMap()" href="">Start GoogleMap</a></p>  
     <p id="content"></p>  
     <p>EasyInfoGeek.com</p>  
     <p>Javscript Demo ---- Android and Javascript interaction</p>  
     
   </body>  
 </html>   
Step 4: Modify JavascriptDemo.java
 package com.easyinfogeek.javascriptdemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Button;

public class JavascriptDemo extends Activity {
  private WebView mWebView;  
     private Button mButton;  
     public void onCreate(Bundle savedInstanceState) {  
         super.onCreate(savedInstanceState);  
         setContentView(R.layout.activity_javascript_demo);  
         setupViews();  
     }  
     
     private void setupViews() {  
         mWebView = (WebView) findViewById(R.id.webview);  
         WebSettings mWebSettings = mWebView.getSettings();  
       
         mWebSettings.setJavaScriptEnabled(true);  
       
         mWebView.addJavascriptInterface(new Object() {  
       
             public void startMap() {  
                 Intent mIntent = new Intent();  
                 ComponentName component = new ComponentName(  
                         "com.google.android.apps.maps",  
                         "com.google.android.maps.MapsActivity");  
                 mIntent.setComponent(component);  
                 startActivity(mIntent);  
             }  
         }, "demo");  
       
         mWebView.loadUrl("file:///android_asset/demo.html");  
         mButton = (Button) findViewById(R.id.button);  
         mButton.setOnClickListener(new Button.OnClickListener() {  
             public void onClick(View v) {  
                 mWebView.loadUrl("javascript:fillContent()");  
             }  
         });  
     }  

}

 

Wednesday, 1 January 2014

Android Tutorial : Two methods of passing object by Intent (Serializable,Parcelable)



In this post, I will show you an simple example of how to pass object by intent in Android application. Parcelable and Serialization are used for marshaling and unmarshaling Java objects. In Parcelable, developers write custom code for marshaling and unmarshaling so it creates less garbage objects in comparison to Serialization. The performance of Parcelable over Serialization dramatically improves (around two times faster), because of this custom implementation.

Serialization is a marker interface, which implies the user cannot marshal the data according to their requirements. In Serialization, a marshaling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API. This helps identify the Java objects member and behavior, but also ends up creating a lot of garbage objects. Due to this, the Serialization process is slow in comparison to Parcelable.

Step 1: main.xml for the layout
 <?xml version="1.0" encoding="utf-8"?>  
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
     android:orientation="vertical"  
     android:layout_width="fill_parent"  
     android:layout_height="fill_parent"  
     >  
 <TextView    
     android:layout_width="fill_parent"   
     android:layout_height="wrap_content"   
     android:text="Hello Welcome to EasyInfoGeek."  
     />  
 <Button  
     android:id="@+id/button1"  
     android:layout_width="fill_parent"  
     android:layout_height="wrap_content"  
     android:text="Serializable"  
 />  
 <Button  
     android:id="@+id/button2"  
     android:layout_width="fill_parent"  
     android:layout_height="wrap_content"  
     android:text="Parcelable"  
 />  
 </LinearLayout>

Step 2: Create Person.java which implement serializable
 package com.easyinfogeek.objectPass;  
 import java.io.Serializable;  
 public class Person implements Serializable {  
     private static final long serialVersionUID = -7060210544600464481L;   
     private String name;  
     private int age;  
     public String getName() {  
  return name;  
     }  
     public void setName(String name) {  
  this.name = name;  
     }  
     public int getAge() {  
  return age;  
     }  
     public void setAge(int age) {  
  this.age = age;  
     }  
       
 }  

Step 3: Create Book.java which implement Parcelable
 package  com.easyinfogeek.objectPass;  
 import android.os.Parcel;  
 import android.os.Parcelable;  
 public class Book implements Parcelable {  
     private String bookName;  
     private String author;  
     private int publishTime;  
       
     public String getBookName() {  
  return bookName;  
     }  
     public void setBookName(String bookName) {  
  this.bookName = bookName;  
     }  
     public String getAuthor() {  
  return author;  
     }  
     public void setAuthor(String author) {  
  this.author = author;  
     }  
     public int getPublishTime() {  
  return publishTime;  
     }  
     public void setPublishTime(int publishTime) {  
  this.publishTime = publishTime;  
     }  
       
     public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {  
  public Book createFromParcel(Parcel source) {  
      Book mBook = new Book();  
      mBook.bookName = source.readString();  
      mBook.author = source.readString();  
      mBook.publishTime = source.readInt();  
      return mBook;  
  }  
  public Book[] newArray(int size) {  
      return new Book[size];  
  }  
     };  
       
     public int describeContents() {  
  return 0;  
     }  
     public void writeToParcel(Parcel parcel, int flags) {  
  parcel.writeString(bookName);  
  parcel.writeString(author);  
  parcel.writeInt(publishTime);  
     }  
 }  
Step 4: Create The ObjectPassDemo.java which is the main Activity class Create 2 more activity classes: ObjectPassDemo1.java use for display person ObjectPassDemo2.java use for display book
package com.easyinfogeek.objectPass;  
import android.app.Activity;  
import android.content.Intent;  
import android.os.Bundle;  
import android.view.View;  
import android.view.View.OnClickListener;  
import android.widget.Button;  
public class ObjectTranDemo extends Activity implements OnClickListener {  
      
    private Button sButton,pButton;  
    public  final static String SER_KEY = "com.easyinfogeek.objectPass.ser";  
    public  final static String PAR_KEY = "com.easyinfogeek.objectPass.par";  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);     
        setupViews();  
          
    }  
      
    public void setupViews(){  
        sButton = (Button)findViewById(R.id.button1);  
        pButton = (Button)findViewById(R.id.button2);  
        sButton.setOnClickListener(this);  
        pButton.setOnClickListener(this);  
    }  

    public void SerializeMethod(){  
        Person mPerson = new Person();  
        mPerson.setName("Leon");  
        mPerson.setAge(25);  
        Intent mIntent = new Intent(this,ObjectTranDemo1.class);  
        Bundle mBundle = new Bundle();  
        mBundle.putSerializable(SER_KEY,mPerson);  
        mIntent.putExtras(mBundle);  
          
        startActivity(mIntent);  
    }  

    public void PacelableMethod(){  
        Book mBook = new Book();  
        mBook.setBookName("Android Developer Guide");  
        mBook.setAuthor("Leon");  
        mBook.setPublishTime(2014);  
        Intent mIntent = new Intent(this,ObjectTranDemo2.class);  
        Bundle mBundle = new Bundle();  
        mBundle.putParcelable(PAR_KEY, mBook);  
        mIntent.putExtras(mBundle);  
          
        startActivity(mIntent);  
    }  


    public void onClick(View v) {  
        if(v == sButton){  
            SerializeMethod();  
        }else{  
            PacelableMethod();  
        }  
    }  
}  
 package com.easyinfogeek.objectPass;  
 import android.app.Activity;  
 import android.os.Bundle;  
 import android.widget.TextView;  
 public class ObjectPassDemo1 extends Activity {  
     @Override  
     public void onCreate(Bundle savedInstanceState) {  
  super.onCreate(savedInstanceState);  
    
  TextView mTextView = new TextView(this);  
  Person mPerson = (Person)getIntent().getSerializableExtra(ObjectPassDemo.SER_KEY);  
  mTextView.setText("You name is: " + mPerson.getName() + "/n"+  
   "You age is: " + mPerson.getAge());  
    
  setContentView(mTextView);  
     }  
 }  


 package com.easyinfogeek.objectPass;  
 import android.app.Activity;  
 import android.os.Bundle;  
 import android.widget.TextView;  
 public class ObjectPassDemo2 extends Activity {  
    
     public void onCreate(Bundle savedInstanceState) {  
  super.onCreate(savedInstanceState);  
  TextView mTextView = new TextView(this);  
  Book mBook = (Book)getIntent().getParcelableExtra(ObjectPassDemo.PAR_KEY);  
  mTextView.setText("Book name is: " + mBook.getBookName()+"/n"+  
      "Author is: " + mBook.getAuthor() + "/n" +  
      "PublishTime is: " + mBook.getPublishTime());  
  setContentView(mTextView);  
     }  
 }  


Step 5: Modify AndroidManifest.xml add the two acivityies
 <?xml version="1.0" encoding="utf-8"?>  
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
       package="com.tutor.objecttran"  
       android:versionCode="1"  
       android:versionName="1.0">  
     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  <activity android:name=".ObjectPassDemo"  
     android:label="@string/app_name">  
      <intent-filter>  
   <action android:name="android.intent.action.MAIN" />  
   <category android:name="android.intent.category.LAUNCHER" />  
      </intent-filter>  
  </activity>  
  <activity android:name=".ObjectPassDemo1"></activity>  
  <activity android:name=".ObjectPassDemo2"></activity>  
     </application>  
     <uses-sdk android:minSdkVersion="7" />  
 </manifest>   

Thursday, 11 July 2013

Use jquery to prevent double submit


Recently, I was engaged in a web development project. We have encounted the very famous old problem of double submit in web application. Actually, we have many ways to solve it. We can prevent the double submit on server side. However, we do it in client side this time.

Here, I summarized two method of of preventing double submit in client side javascript.

(1) For html button, we can use jquery to disabled the button. Example code is shown here:

<input type="button" value="Click"id="subBtn"/>  
<script type="text/javascript">  

$("#subBtn").click(function(){  
   // Disabled the button
   $(this).attr("disabled","disabled");  
   
   //execute your function e.g. submit a form
   myFunc();  
});

function myFunc(){  
    // ...
    // code
    // ...
    // execute your logic here
    // remove the diabled  attribute and re-enabled the button again
    $("#subBtn").removeAttr("disabled");  
}  
  
</script> 


(2) For html anchor, we can use redirect the event handler of the anchor to another function after the first click.

<a href="javascript:;" onclick="return funcOne();">Click</a>  
<scripttypescripttype="text/javascript">  
function funcOne(){  
    alert("Clickthe button!");  

   //After the first click, funcTwo will be assined to funcOne.
    funcOne=funcTwo;  
    return false;  
}  
function funcTwo(){  
 //function two will not do anything
    return false;  
}  
</script>


Wednesday, 10 July 2013

Microsoft’s Reorganization Plan

>
Microsoft is expected to announce a major reorganization of its management structure on Thursday. The changes will shift the duties and responsibilities of many top Microsoft executives and are intended to eliminate overlap within the 98,000-employee company, AllThingsD reported on Monday, citing anonymous sources.

A new cloud computing and business-focused products unit would be headed by Satya Nadella, who currently oversees Microsoft's server business, according to a Bloomberg report last week. Julie Larson-Green, the current co-head of Microsoft's Windows operating system business, will lead the company's hardware efforts, including the Xbox video game console and the Surface tablets, Bloomberg said.

Chief Executive Steve Ballmer remains under pressure to ramp up Microsoft's presence on mobile devices as the computer industry steadily declines.

Ballmer announced in his annual letter to shareholders last October that Microsoft now sees itself as a "devices and services" company, rather than a software maker.

The company's last significant reorganization came in July 2008 when Ballmer split Microsoft's Platforms & Services Division into three units - Windows, Online Services and Server and Tools.

Microsoft's shares have gained almost 30 percent this year, helped by a rally that began in late April when the company released strong revenue and earnings in what was one of the worst quarters for PC sales on record.

But consumers are increasingly turning to mobile devices such as smartphones and tablets instead of traditional PCs and the shrink-wrapped software products that are the foundation of Microsoft's $74 billion annual revenue business.

Under the new structure, Qi Lu, the head of Microsoft's money-losing online group, would also oversee Microsoft Office as well as other apps, Bloomberg said. Tony Bates would oversee Microsoft's business development efforts, including mergers and acquisitions and corporate strategy.

"What they have has worked for the past and led to some pretty profitable businesses, but when people are aligned with certain goals they may not be thinking the right way for the future," David Smith, an analyst with industry research firm Gartner said on Monday about the widely expected reorganization.

Tuesday, 9 July 2013

Andoird Development Example: AutoCompleteTextView and MultiAutoCompleteTextView



Dynamic auto complete for input text can be archived by AutoCompleteTextView. Here's an example to illustrate the usage of AutoCompleteTextView.

(1) layout.xml
< AutoCompleteTextView  
        Android: ID = "@ + ID / Auto"  
        Android: layout_width = "wrap_content"  
        Android: layout_height = "wrap_content"  
        Android: layout_alignParentLeft = "true"  
        Android: layout_alignParentRight = "true"  
        Android: layout_below = "@ + id/textView1"  
        Android: layout_marginTop = "20DP"  
        Android: EMS = "10"  >  
  
        < requestFocus  />  
    </ AutoCompleteTextView > 

< MultiAutoCompleteTextView  
        Android: ID = "@ + ID / multiAuto"  
        Android: layout_width = "wrap_content"  
        Android: layout_height = "wrap_content"  
        Android: layout_alignParentLeft = "true"  
        Android: layout_alignRight = "@ + ID / Auto"  
        Android: layout_below = "@ + id/textView2"  
        Android: layout_marginTop = "19dp"  
        Android: EMS = "10"  />  


(2) Main activity
package com.example.autocomplete;  
  
import android.app.Activity;  
import android.os.Bundle;  
import android.view.Menu;  
import android.widget.ArrayAdapter;  
import android.widget.AutoCompleteTextView;  
import android.widget.MultiAutoCompleteTextView;  
  
public class MainActivity extends Activity {  
    private AutoCompleteTextView auto;  
    private MultiAutoCompleteTextView mulAuto;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        auto=(AutoCompleteTextView) findViewById(R.id.auto);  
        mulAuto= (MultiAutoCompleteTextView) findViewById(R.id.multiAuto);  
        String[] autoStrings = new String[] { "Google Map", "Google", "Google Drive","Google Doc",  
                "java", "javaweb","javascript" };  
        
        ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,  
                android.R.layout.simple_dropdown_item_1line, autoStrings);  
        auto.setAdapter(adapter);  
        mulAuto.setAdapter(adapter);  
       
        mulAuto.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());  
    }  
  
    @Override  
    public boolean onCreateOptionsMenu(Menu menu) {  
        // Inflate the menu; this adds items to the action bar if it is present.  
        getMenuInflater().inflate(R.menu.main, menu);  
        return true;  
    }  
  
}  

IOS7 Beta 3 version: Interface fine tuning



Apple just released iOS 7 third developer beta version. There are many small adjuestments on the system interface design.

Font redesign:

IOS beta 3 choose a new font type. It uses the "normal" Helvetica Neue font. Therefore, you will discovered the font in your SMS interface seems to be being bolded. This change is appied to in weather, nortification and settings interfaces.

Status bar:

On the lock screen, the icon size in the status bar including signal strength, WiFi, Bluetooth, batteries has been increased.

Lock screen :

When playing music, lock screen can also display the time.

Calendar :

In calendar mode, there will be gray dots when there are events on that date .

Siri :

Siri's voice sounds more natural now.

Download Animation :

When download and install the application, the progress indicator change to a clock style.

Control Center :

AirPlay can display the currently connected device.

Monday, 8 July 2013

Android Example: Creating 4 different Tween Animation effects

Android platform facilitates three different types of animation you can define in your application resources: property, tween and frame. In this example, we show you how to do 4 different tween animation effect.

(1) create activity
package com.easyinfogeek;  
import android.app.Activity;  
import android.os.Bundle;  
import android.util.Log;  
import android.view.View;  
import android.view.View.OnClickListener;  
import android.view.animation.AlphaAnimation;  
import android.view.animation.Animation;  
import android.view.animation.AnimationSet;  
import android.view.animation.AnimationUtils;  
import android.view.animation.ScaleAnimation;  
import android.view.animation.TranslateAnimation;  
import android.view.animation.Animation.AnimationListener;  
import android.view.animation.RotateAnimation;  
import android.widget.Button;  
import android.widget.ImageView;  
public class AnimationDemoActivity extends Activity {  
    private ImageView imageView;  

    // define animationType enum
    enum AnimationType{  
        Alpha,  
        Rotate,  
        Scale,  
        Translate,  
        Complex  
    } 

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

        //define 4 button for each tween animation 
        imageView = (ImageView)findViewById(R.id.imageView);  
        Button alpha = (Button)findViewById(R.id.Alpha);  
        alpha.setOnClickListener(new AnimationClickListener(AnimationType.Alpha));  
        Button rotate = (Button)findViewById(R.id.Rotate);  
        rotate.setOnClickListener(new AnimationClickListener(AnimationType.Rotate));  
        Button scale = (Button)findViewById(R.id.Scale);  
        scale.setOnClickListener(new AnimationClickListener(AnimationType.Scale));  
        Button translate = (Button)findViewById(R.id.Translate);  
        translate.setOnClickListener(new AnimationClickListener(AnimationType.Translate));  
        Button complex = (Button)findViewById(R.id.Complex);  
        complex.setOnClickListener(new AnimationClickListener(AnimationType.Complex));  
    }  
  
     

    // create a listener inner class
    class AnimationClickListener implements OnClickListener{  
        private AnimationType animationType;  
        public AnimationClickListener(AnimationType animType){  
            animationType = animType;  
        }  
        public void onClick(View v) {  
            // TODO Auto-generated method stub  
            switch (animationType) {  
            case Alpha:  

                //Alpha animation. repeat 5 times, last for 1 mins                 
                AlphaAnimation alphaAnimation = (AlphaAnimation)AnimationUtils.loadAnimation(AnimationDemoActivity.this, R.anim.alpha);  
                imageView.startAnimation(alphaAnimation);  
                break;  
            case Rotate:  
                //rotate animation
                RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);  
                rotateAnimation.setDuration(3000);  
                rotateAnimation.setRepeatCount(3);  
                //start animation 
                imageView.startAnimation(rotateAnimation);  
                break;  
            case Scale:  
                //scale animation
                ScaleAnimation scaleAnimation = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);  
                scaleAnimation.setDuration(3000);  
                scaleAnimation.setRepeatCount(3);  
                //start animation 
                imageView.startAnimation(scaleAnimation);  
                break;  
            case Translate:  
                //translate animation
                TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 2, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 2);  
                translateAnimation.setDuration(3000);  
                translateAnimation.setRepeatCount(3);  
                //start animation 
                imageView.startAnimation(translateAnimation);  
                break;  
  
            case Complex:  
                //four animation overlap
                AnimationSet sets = new AnimationSet(false);  
                
                AlphaAnimation _animation1 = new AlphaAnimation(1f, 0.1f);  
                _animation1.setDuration(3000);  
                
                RotateAnimation rotateAnimation1 = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);  
                rotateAnimation1.setDuration(3000);  
                
                ScaleAnimation scaleAnimation1 = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);  
                scaleAnimation1.setDuration(3000);  
                
                TranslateAnimation translateAnimation1 = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 2, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 2);  
                translateAnimation1.setDuration(3000);  
                
                sets.addAnimation(_animation1);  
                sets.addAnimation(rotateAnimation1);  
                sets.addAnimation(scaleAnimation1);  
                sets.addAnimation(translateAnimation1);  
                imageView.startAnimation(sets);  
                break;  
            default:  
                break;  
            }  
        }  
    }  
}  

(2) create layout.xml
<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical" >  
    <TextView  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="@string/hello" />  
    <ImageView  
        android:id="@+id/imageView"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:src="@drawable/qa" />  
    <Button  
        android:id="@+id/Alpha"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Alpha" />  
    <Button  
        android:id="@+id/Rotate"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Rotate" />  
    <Button  
        android:id="@+id/Scale"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Scale" />  
    <Button  
        android:id="@+id/Translate"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Translate" />  
    <Button  
        android:id="@+id/Complex"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Complex" />  
</LinearLayout>  

(3) create alpha.xml resource file
<?xml version="1.0" encoding="utf-8"?>  
<alpha   
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:fromAlpha="1" android:toAlpha="0.3" android:duration="2000" android:repeatCount="3">  
</alpha>