Archive

Archive for the ‘Android’ Category

Redundant div tag added just before the close body tag on Galaxy S3

September 7, 2012 Leave a comment

I found a problem that sometimes there is a “FALSE” character displayed at the end of our web page on Galaxy S3 Phone.

With further research , a div tag <div id = “recog_div”>False</div> be founded just before the close body tag.

It seems to be added by Galaxy itself ?

So , I have to remove it by redundant source code. ūüė¶

Advertisements
Categories: Android

Android:Run native app via Browser

August 22, 2012 Leave a comment

Here is a memo in my recent project for how to run our native app from web app .

  • html

Create an action like bellow.


location.href = "myschemename://myhost/app.do?p1='1'&p2='2'";

(‚ÄĽ app.do makes no sense)

  • manifest

Use an <intent-filter> with a <data> element.
then specify the scheme and host in it for our web app to invoke.

 <intent-filter >
 <action android:name="android.intent.action.VIEW" />
 <category android:name="android.intent.category.DEFAULT"/>
 <category android:name="android.intent.category.BROWSABLE"/>
 <data android:scheme="myscheme" android:host="myhost" />
 </intent-filter>
  • java

You can use getIntent().getData()which returns a Uri object , then get the parameter from it.


if (Intent.ACTION_VIEW.equals(action)) {
Uri uri = getIntent().getData();
String p1 =  uri.getQueryParameter("p1");
String p2 =  uri.getQueryParameter("p2");

...
}

Categories: Android

Android:Update UI through handler

August 22, 2012 1 comment

Here is a short memo for Handler class I have used in my recent project.

Class Overview

A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it — from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler’s handleMessage(Message) method (requiring that you implement a subclass of Handler).

When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.

When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler’s message queue and processed when appropriate.

A Handler can send both Message and Runable objects.

Layout


<?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="wrap_content"
android:orientation="horizontal" >

<TextView
android:id="@+id/txtView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_weight="1"
android:background="#969696"
android:textColor="#fff"
android:textSize="29sp" />

<Button
android:id="@+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Handle in Android" />

</LinearLayout>

  • Message

public class MainActivity extends Activity {

private int index = 0;

private Button btnTest;
private TextView txtView;

private final Handler handler = new Handler() {
public void handleMessage(Message msg) {

txtView.setText(index++ + "");
}
};

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

txtView = (TextView) findViewById(R.id.txtView);
txtView.setText(index++ + "");

btnTest = (Button) findViewById(R.id.btnTest);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
public void run() {
try {
Thread.sleep(1000);

Message msg = handler.obtainMessage();
handler.sendMessage(msg);

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
});
}
}

  • Runable

public class MainActivity extends Activity {

private int index = 0;

private Button btnTest;
private TextView txtView;

private final Handler handler = new Handler();

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

txtView = (TextView) findViewById(R.id.txtView);
txtView.setText(index++ + "");

btnTest = (Button) findViewById(R.id.btnTest);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.post(new Runnable() {

@Override
public void run() {

txtView.setText(index++ + "");
}
});
}
});
}
}

Having the Handler final and declaring it in the class definition is a good practice.

A sample for progress bar , using both runnable and message.

Layout


<?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="wrap_content"
android:orientation="horizontal" >

<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:progress="0"
android:visibility="gone" />

<Button
android:id="@+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Handle in Android" />

</LinearLayout>

Java


public class MainActivity extends Activity {

private Button btnTest;
ProgressBar progressBar;

private final Handler handler = new Handler() {

@Override
public void handleMessage(Message msg) {
progressBar.setProgress(msg.arg1);
handler.postDelayed(run, 1000);
}
};

private final Runnable run = new Runnable() {

int index = 0;

@Override
public void run() {

index += 10;
Message msg = handler.obtainMessage();
msg.arg1 = index;

handler.sendMessage(msg);
if (index >= 100)
handler.removeCallbacks(this);
}
};

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

progressBar = (ProgressBar) findViewById(R.id.progressBar);

btnTest = (Button) findViewById(R.id.btnTest);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressBar.setProgress(0);
progressBar.setVisibility(View.VISIBLE);
handler.post(run);
}
});
}
}

Categories: Android

Android:Make all buttons with the same width inside linearlayout.

August 16, 2012 Leave a comment

I need to create a Tab like UI at the bottom of  main Layout today.

But for some reason , I can’t use TabHost control .¬† So I have to put all buttons inside a LinearLayout with android:layout_alignParentBottom=”true” ¬† . Source code is like below .


<LinearLayout
android:id="@+id/linearLayoutBottom"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:background="@color/black"
android:gravity="center"
android:layout_alignParentBottom="true">

<Button
android:id="@+id/btn1"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:gravity="center"
android:text="@string/button1"
style="@style/TabStyle"
android:background="@drawable/style_button_black"
android:textColor="@color/snowblack"/>

<Button

android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:gravity="center"
android:text="@string/button2"
style="@style/TabStyle"
android:background="@drawable/style_button_snowblack"
android:textColor="@color/white"/>

<Button
                        android:layout_weight="1"
android:layout_width="0dp"
                        android:layout_height="fill_parent"
android:gravity="center"
android:text="@string/button3"
style="@style/TabStyle"
android:background="@drawable/style_button_black"
android:textColor="@color/snowblack"/>

</LinearLayout>

 

The final effect :

Memo:

I just need use android:layout_width=”0dp” and android:layout_weight=”1″ on these buttons¬†

Setting the ‘width’ to be “0” means you don’t want to explicitly enforce a width and that the OS should work out the relative widths as fractions of total weight.¬†

Setting the ‘weight‘ to be “1” means , 1+1+1 = 3 (total weight). So each of them will take 1/3 total width of the screen width.

Categories: Android

Android practice ‚Äď Custom ExpandableListView Sample

March 25, 2012 8 comments

References: ExpandableListView

A view that shows items in a vertically scrolling two-level list. This differs from the ListView by allowing two levels: groups which can individually be expanded to show its children. The items come from the ExpandableListAdapter associated with this view.

The following shows an example of  how to create a custom ExpandableListView in an activity
1, Create a main.xml  to provide a ListView control .
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 style="@style/background"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical" >

<include layout="@layout/top" />

<ExpandableListView
 android:id="@+id/expandableListView"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:groupIndicator="@drawable/play_expand_background"
 android:listSelector="@drawable/play_expand_seletor"
 android:scrollbars="none" >
 </ExpandableListView>

</LinearLayout>

2, Custom adapter

public class ExpandableListAdapter extends BaseExpandableListAdapter {

private Context mContext;
 private ExpandableListView mExpandableListView;
 private List<GroupEntity> mGroupCollection;
 private int[] groupStatus;

public ExpandableListAdapter(Context pContext,
 ExpandableListView pExpandableListView,
 List<GroupEntity> pGroupCollection) {
 mContext = pContext;
 mGroupCollection = pGroupCollection;
 mExpandableListView = pExpandableListView;
 groupStatus = new int[mGroupCollection.size()];

setListEvent();
 }

private void setListEvent() {

mExpandableListView
 .setOnGroupExpandListener(new OnGroupExpandListener() {

@Override
 public void onGroupExpand(int arg0) {
 // TODO Auto-generated method stub
 groupStatus[arg0] = 1;
 }
 });

mExpandableListView
 .setOnGroupCollapseListener(new OnGroupCollapseListener() {

@Override
 public void onGroupCollapse(int arg0) {
 // TODO Auto-generated method stub
 groupStatus[arg0] = 0;
 }
 });
 }

@Override
 public String getChild(int arg0, int arg1) {
 // TODO Auto-generated method stub
 return mGroupCollection.get(arg0).GroupItemCollection.get(arg1).Name;
 }

@Override
 public long getChildId(int arg0, int arg1) {
 // TODO Auto-generated method stub
 return 0;
 }

@Override
 public View getChildView(int arg0, int arg1, boolean arg2, View arg3,
 ViewGroup arg4) {
 // TODO Auto-generated method stub

ChildHolder childHolder;
 if (arg3 == null) {
 arg3 = LayoutInflater.from(mContext).inflate(
 R.layout.list_group_item, null);

childHolder = new ChildHolder();

childHolder.title = (TextView) arg3.findViewById(R.id.item_title);
 arg3.setTag(childHolder);
 }else {
 childHolder = (ChildHolder) arg3.getTag();
 }

childHolder.title.setText(mGroupCollection.get(arg0).GroupItemCollection.get(arg1).Name);
 return arg3;
 }

@Override
 public int getChildrenCount(int arg0) {
 // TODO Auto-generated method stub
 return mGroupCollection.get(arg0).GroupItemCollection.size();
 }

@Override
 public Object getGroup(int arg0) {
 // TODO Auto-generated method stub
 return mGroupCollection.get(arg0);
 }

@Override
 public int getGroupCount() {
 // TODO Auto-generated method stub
 return mGroupCollection.size();
 }

@Override
 public long getGroupId(int arg0) {
 // TODO Auto-generated method stub
 return arg0;
 }

@Override
 public View getGroupView(int arg0, boolean arg1, View arg2, ViewGroup arg3) {
 // TODO Auto-generated method stub
 GroupHolder groupHolder;
 if (arg2 == null) {
 arg2 = LayoutInflater.from(mContext).inflate(R.layout.list_group,
 null);
 groupHolder = new GroupHolder();
 groupHolder.img = (ImageView) arg2.findViewById(R.id.tag_img);
 groupHolder.title = (TextView) arg2.findViewById(R.id.group_title);
 arg2.setTag(groupHolder);
 } else {
 groupHolder = (GroupHolder) arg2.getTag();
 }
 if (groupStatus[arg0] == 0) {
 groupHolder.img.setImageResource(R.drawable.group_down);
 } else {
 groupHolder.img.setImageResource(R.drawable.group_up);
 }
 groupHolder.title.setText(mGroupCollection.get(arg0).Name);

return arg2;
 }

class GroupHolder {
 ImageView img;
 TextView title;
 }

class ChildHolder {
 TextView title;
 }

@Override
 public boolean hasStableIds() {
 // TODO Auto-generated method stub
 return true;
 }

@Override
 public boolean isChildSelectable(int arg0, int arg1) {
 // TODO Auto-generated method stub
 return true;
 }

}
3,  The final effect
4, Source Code
You can download here
Categories: Android, Article

Android practice – ViewFlipper Sample

March 20, 2012 4 comments

References: ViewFlipper

Simple ViewAnimator that will animate between two or more views that have been added to it. Only one child is shown at a time. If requested, can automatically flip between each child at a regular interval.

The following shows an example of  switching between views by fling on ViewFlipper.
1,place a ViewFlipper control into your layout file.

<ViewFlipper
 android:id="@+id/vfShow"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent" >
 </ViewFlipper>
2, create fling animation
  • left in

<translate
 android:duration="500"
 android:fromXDelta="100%p"
 android:toXDelta="0" />

<alpha
 android:duration="500"
 android:fromAlpha="0.1"
 android:toAlpha="1.0" />
  • left out

<translate
 android:duration="500"
 android:fromXDelta="0"
 android:toXDelta="-100%p" />

<alpha
 android:duration="500"
 android:fromAlpha="1.0"
 android:toAlpha="0.1" /Ôľě
  • right in

<translate
 android:duration="500"
 android:fromXDelta="-100%p"
 android:toXDelta="0" />

<alpha
 android:duration="500"
 android:fromAlpha="0.1"
 android:toAlpha="1.0" />
  • right out

<translate
android:duration="500"
android:fromXDelta="0"
android:toXDelta="100%p" />

<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
3, Implement onFling by extends the SimpleOnGestureListener for switching views .

class MyGestureDetector extends SimpleOnGestureListener {
 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
 float velocityY) {
 try {

// right to left swipe
 if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
 && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
 vf.setInAnimation(AnimationUtils.loadAnimation(mContext,
 R.anim.left_in));
 vf.setOutAnimation(AnimationUtils.loadAnimation(mContext,
 R.anim.left_out));
 vf.showNext();
 return true;
 } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
 && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
 vf.setInAnimation(AnimationUtils.loadAnimation(mContext,
 R.anim.right_in));
 vf.setOutAnimation(AnimationUtils.loadAnimation(mContext,
 R.anim.right_out));
 vf.showPrevious();
 return true;
 }

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

return false;
 }
 }
4, Create a OnTouchListener on ViewFlipper and attach GestureDetector object to it.

Detects various gestures and events using the supplied¬†MotionEvents. The¬†GestureDetector.OnGestureListener¬†callback will notify users when a particular motion event has occurred. This class should only be used with¬†MotionEvents reported via touch (don’t use for trackball events). To use this class:

GestureDetector is meant to detect common, simple and non visual Gestures like scrolls, flings, swipes, etc.

detector = new GestureDetector(
 new MyGestureDetector());
 vf = (ViewFlipper) this.findViewById(R.id.vfShow);
 vf.setOnTouchListener(new OnTouchListener() {
 @Override
 public boolean onTouch(final View view, final MotionEvent event) {
 detector.onTouchEvent(event);
 return true;
 }
 });

5, Source Code
You can download here.
Categories: Android

Android practice – ListView With Round Corner

March 19, 2012 2 comments

1, Use the shape tag to create a drawable[listview_roundcorner_item.xml] with rounded corners. Like ,

</pre>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="rectangle" >

<gradient
 android:angle="270"
 android:endColor="#E77A26"
 android:startColor="#E77A26" />

<corners
 android:bottomLeftRadius="8dp"
 android:bottomRightRadius="8dp"
 android:topLeftRadius="8dp"
 android:topRightRadius="8dp" />

</shape>
<pre>

2, There are two ways to implement it .

  • Add attribute to ListView

android:background="@drawable/listview_roundcorner_item"

  • Set background by sourcecode

listView.setBackgroundResource(R.drawable.listview_roundcorner_item);

3, Finally , if you run this example you would get the following effect.

Categories: Android