Sunday, 31 March 2013

The role of Transformation Matrices in Animation


The mechanics of animation of are quite simple. Take any scene and if you repaint it quick while some aspect of that scene is changing you get the impression that something is moving smoothly although the repaint is happening only with a certain frequency which is typically 24 or 12 frames per second.
what changes at every redraw may be color, position, orientation, or size or any combination of these. If you want to take a view or a scene or a picture and want to move that scene to the right by a few pixels, you will typically define a transformation matrix and then apply a matrix multiplication or transformation on every pixel of the scene to get the new location. So each tranformation is identified by a certain matrix.
If you start with an identity matrix and then apply each transformation to it then you will get a final matrix that you can apply just one time to transform the view. By changing these matrices in a gradual manner in a time loop you will accomplish animation. Let's spend a little bit more time and understand the matrix api before going further.
You can get an identity matrix by doing

import android.graphics.Matrix;
Matrix matrix = new Matrix();
To achieve rotation you can do

matrix.setRotate(degrees)
This method will rotate the view around origin by those many degrees in a 2D space. Some other methods are

matrix.setScale(x,y);
matrix.setTranslate(x,y);
matrix.setSkew(x,y); 
As you call these methods to arrive at a desired matrix be aware of the "set" semantics. "set" semantics works like a "setting" a variable which means "replace" the current value with the new value. All of these methods, if you follow the java source code of android eventually resolve to some c++ code from a core google graphics library called "skia". You can explore the source code online at

http://android.git.kernel.org/
"git" is a source code control system used by the android open source project. You can learn more about "git" SCM here at

http://git.or.cz/
Now back to understanding of the "set" semantics on these graphics matrices. Let us take a look at the source code for "setScale":

void SkMatrix::setScale(SkScalar sx, SkScalar sy) {
    fMat[kMScaleX] = sx;
    fMat[kMScaleY] = sy;
    fMat[kMPersp2] = kMatrix22Elem;

    fMat[kMTransX] = fMat[kMTransY] =
    fMat[kMSkewX]  = fMat[kMSkewY] = 
    fMat[kMPersp0] = fMat[kMPersp1] = 0;

    this->setTypeMask(kScale_Mask | kRectStaysRect_Mask);
}
The scale function replaces all previous scaling values and pretty much resets the matrix and sets the scale. So if you have done anything else to the matrix all that is gone. Let us take a look at the "setTranslate" to see if that is any different.

void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) {
    if (SkScalarAs2sCompliment(dx) | SkScalarAs2sCompliment(dy)) {
        fMat[kMTransX] = dx;
        fMat[kMTransY] = dy;

        fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1;
        fMat[kMSkewX]  = fMat[kMSkewY] = 
        fMat[kMPersp0] = fMat[kMPersp1] = 0;
        fMat[kMPersp2] = kMatrix22Elem;

        this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask);
    } else {
        this->reset();
    }
}
Basically sets the scale back to 1 and sets the translations replacing everything before.
So what do you do if you want to apply multiple transformations in a tow. Matrix class provides a set of "pre*" and "post*" functions for each of the "set*" fucnctions. Let us take a look at the source code for "preScale"

bool SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
    SkMatrix    m;
    m.setScale(sx, sy, px, py);
    return this->preConcat(m);
}

bool SkMatrix::preConcat(const SkMatrix& mat) {
    return this->setConcat(*this, mat);
}

bool SkMatrix::postConcat(const SkMatrix& mat) {
    return this->setConcat(mat, *this);
}
Essentially "preScale" creates a brand new matrix with the given scale and then multiplies that matrix with the current matrix and replaces the current matrix with the resultant matrix. When matrices are multiplied the order is important. So if we do

m.setScale(..) = rm1
m.preScale(..) = m2 x rm1 = rm3
m.postScale(..) = rm3 x m4 = rm5
I could have acheived the same with

m1.setScale() = m1
m2.setScale() = m2
m3.setScale() = m3

m1.setConcat(m2,m1); // rm3
m1.setConcat(m1,m3); // rm5
You can concat
If "m1" was an identity matrix then the following two would be equal as well

m1.postTranslate(); // take it to the origin
m1.postScale(); //scale it
m1.postTranslate();// take it back to the center

m2.setScale();
m2.preTranslate();
m2.postTranslate();

Here is some more sample code demonstrating matrix equivalence based on the order of operations on that matrix

public class TestMatrix
{
public static void test(SomeActivity a)
{
test1(a);
test2(a);
test3(a);
}
public static void test1(SomeActivity a)
{
Matrix m1 = new Matrix();
m1.setScale(2, 2);
m1.preScale(2, 2);
m1.postScale(2, 2);
Matrix m2 = new Matrix();
m2.postScale(2, 2);
m2.postScale(2, 2);
m2.postScale(2, 2);
assertL("test1",a,m1,m2,"m1 and m2 will be same");
}
public static void test2(SomeActivity a)
{
Matrix m1 = new Matrix();
m1.setScale(2, 2);
m1.preTranslate(-2, -2);
m1.postTranslate(2, 2);
Matrix m2 = new Matrix();
m2.postTranslate(-2, -2);
m2.postScale(2, 2);
m2.postTranslate(2, 2);
assertL("test2",a,m1,m2,"m1 and m2 will be the same");
}
public static void test3(SomeActivity a)
{
Matrix m1 = new Matrix();
m1.setScale(2, 2);
m1.preTranslate(-2, -2);
m1.postTranslate(2, 2);
Matrix m2 = new Matrix();
m2.preTranslate(-2, -2);
m2.postTranslate(2, 2);
m2.setScale(2, 2);
assertL("test4",a,m1,m2,"m1 and m2 will not be the same");
Matrix m3 = new Matrix();
m3.setScale(2, 2);
assertL("test3",a,m2,m3,"m2 and m3 will be the same");
}
private static void assertL(String testName
, SomeActivity a
, Matrix m1
, Matrix m2
, String assertText)
{
if (m1.equals(m2))
{
a.appendText("\n" + testName + ": m1 is same as m2");
}
else
{
a.appendText("\n" + testName + ": m1 is NOT same as m2");
}
}
}
view raw TestMatrix.java hosted with ❤ by GitHub
In summary all the "pre*" and "post*" methods are mere shortcuts to "setConcat" against itself.

preTranslate(m) -> setConcat(m x self) 
preRotate(m) -> setConcat(m x self)
preScale(m) -> setConcat(m x self)
preSkew(m) -> setConcat(m x self)

postTranslate(m) -> setConcat (self x m)
postRotate(m) -> setConcat (self x m)
postScale(m) -> setConcat (self x m)
postSkew(m) -> setConcat (self x m)

Introduction To Animation In Android

Android supports two kinds of animation. 
  • One is called "Tweened Animation". 
  • The second one is called "Frame by Frame" animation. 
"Tween" is a short for "in-between" borrowed from traditional animators. Inbetweens are drawings that simulate motion between key frames. There may be 24 inbetweens between two key frames or there could be 12 between two key frames. The former case is called "on ones" and the later ones are called "on twos".

In Android here is how "tweening" works. You start with a view. This view can be any view including a view group with any set of complex composed graphical objects. When tweening animation is attached to this view, the animation gets a call back at regular intervals to change any aspect of the tranformation matrix that would be used to render the view.

Moving an object or scaling an object, or changing the shade of an object can all be represented as a set of matrix transformations. By changing this matrix in the call back of the animation you will render the object at a different place with a different scale or a diferent color.


So at a general level, tweening animation is acomplished by changing the properties of a view at various time intervals during the alloted time of an animation.


Android supports the following types of "tween" animations

  • AlphaAnimation: Changing Transparency of an object
  • RotateAnimation: Rotating an object
  • ScaleAnimation: Scale an object
  • TranslateAnimation: Move an object


In Android frame by frame animation a series of drawable resources are loaded one after the other. The class AnimationDrawable is responsible for frame by frame animation. Each frame in this animation is a drawable resource.


As you get deeper into Android animation you will see that the distinction is not so clearcut where you can mix both concepts by essentially redrawing the canvas one way or the other.




Saturday, 30 March 2013

ViewPager and PagerTabStrip


Note: Require "android-support-v4.jar" and its size greater than 3mb.


/* main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/background" >
<android.support.v4.view.PagerTabStrip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
*/
//ViewPager Adapter
public class ViewPagerAdapter extends PagerAdapter {
// ----------------------------------------------------------------
private Gallery gallery_disc, gallery_fest, gallery_combo;
private ImageView selectedImageView;
private ImageView leftArrowImageView;
private ImageView rightArrowImageView;
private int discPos, festPos, comboPos = 0;
private List<String> drawable, d1, d2, d3;
private GalleryImageAdapter disc_adapter, fest_adapter, combo_adapter;
TextView tvOfferName_disc, tvDesc_disc, tvItems_disc, tvDiscount_disc;
TextView tvOfferName_fest, tvDesc_fest, tvItems_fest, tvDiscount_fest;
TextView tvOfferName_combo, tvDesc_combo, tvItems_combo, tvDiscount_combo;
String discOffer[][];
String comboOffer[][];
String festOffer[][];
String temp = "% Discount on Following Items:";
ProgressDialog pd;
// --------------------------------------
private static String[] titles = new String[] { "Sport", "Music",
"Games" };
private final Context context;
private int[] scrollPosition = new int[titles.length];
public ViewPagerAdapter(Context context) {
this.context = context;
for (int i = 0; i < titles.length; i++) {
scrollPosition[i] = 0;
}
}
@Override
public String getPageTitle(int position) {
return titles[position];
}
@Override
public int getCount() {
return titles.length;
}
@Override
public Object instantiateItem(View pager, final int position) {
//Instantiate your all controls here
LinearLayout llmain=new LinearLayout(context);
((ViewPager) pager).addView(llmain, 0);
return llmain;
}
@Override
public void destroyItem(View pager, int position, Object view) {
((ViewPager) pager).removeView((LinearLayout) view);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
@Override
public void finishUpdate(View view) {
}
@Override
public void restoreState(Parcelable p, ClassLoader c) {
if (p instanceof ScrollState) {
scrollPosition = ((ScrollState) p).getScrollPos();
}
}
@Override
public Parcelable saveState() {
return new ScrollState(scrollPosition);
}
@Override
public void startUpdate(View view) {
}
}
//To Maintain Scroll State after each Swipe
public class ScrollState implements Parcelable
{
private int[] scrollPos;
public static Parcelable.Creator<ScrollState> CREATOR = new Parcelable.Creator<ScrollState>()
{
@Override
public ScrollState createFromParcel( Parcel source )
{
int size = source.readInt();
int[] scrollPos = new int[ size ];
source.readIntArray( scrollPos );
return new ScrollState( scrollPos );
}
@Override
public ScrollState[] newArray( int size )
{
return new ScrollState[ size ];
}
};
public ScrollState( int[] scrollPos )
{
this.scrollPos = scrollPos;
}
@Override
public int describeContents()
{
return 0;
}
@Override
public void writeToParcel( Parcel dest, int flags )
{
dest.writeInt( scrollPos.length );
dest.writeIntArray( scrollPos );
}
public int[] getScrollPos()
{
return scrollPos;
}
}

Create Quick Action Menu






//Main Activity
public class QuickMenuActivity extends Activity {
/** Called when the activity is first created. */
private static final int ID_UP = 1;
private static final int ID_DOWN = 2;
private static final int ID_SEARCH = 3;
private static final int ID_INFO = 4;
private static final int ID_ERASE = 5;
private static final int ID_OK = 6;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionItem nextItem = new ActionItem(ID_DOWN, "Next", getResources()
.getDrawable(R.drawable.menu_down_arrow));
ActionItem prevItem = new ActionItem(ID_UP, "Prev", getResources()
.getDrawable(R.drawable.menu_up_arrow));
ActionItem searchItem = new ActionItem(ID_SEARCH, "Find",
getResources().getDrawable(R.drawable.menu_search));
ActionItem infoItem = new ActionItem(ID_INFO, "Info", getResources()
.getDrawable(R.drawable.menu_info));
ActionItem eraseItem = new ActionItem(ID_ERASE, "Clear", getResources()
.getDrawable(R.drawable.menu_eraser));
ActionItem okItem = new ActionItem(ID_OK, "OK", getResources()
.getDrawable(R.drawable.menu_ok));
// use setSticky(true) to disable QuickAction dialog being dismissed
// after an item is clicked
prevItem.setSticky(true);
nextItem.setSticky(true);
// create QuickAction. Use QuickAction.VERTICAL or
// QuickAction.HORIZONTAL param to define layout
// orientation
final QuickAction quickAction = new QuickAction(this,
QuickAction.VERTICAL);
// add action items into QuickAction
quickAction.addActionItem(nextItem);
quickAction.addActionItem(prevItem);
quickAction.addActionItem(searchItem);
quickAction.addActionItem(infoItem);
quickAction.addActionItem(eraseItem);
quickAction.addActionItem(okItem);
// Set listener for action item clicked
quickAction
.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {
@Override
public void onItemClick(QuickAction source, int pos,
int actionId) {
ActionItem actionItem = quickAction.getActionItem(pos);
// here we can filter which action item was clicked with
// pos or actionId parameter
if (actionId == ID_SEARCH) {
Toast.makeText(getApplicationContext(),
"Let's do some search action",
Toast.LENGTH_SHORT).show();
} else if (actionId == ID_INFO) {
Toast.makeText(getApplicationContext(),
"I have no info this time",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),
actionItem.getTitle() + " selected",
Toast.LENGTH_SHORT).show();
}
}
});
// set listnener for on dismiss event, this listener will be called only
// if QuickAction dialog was dismissed
// by clicking the area outside the dialog.
quickAction.setOnDismissListener(new QuickAction.OnDismissListener() {
@Override
public void onDismiss() {
Toast.makeText(getApplicationContext(), "Dismissed",
Toast.LENGTH_SHORT).show();
}
});
// show on btn1
Button btn1 = (Button) this.findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
quickAction.show(v);
}
});
Button btn2 = (Button) this.findViewById(R.id.btn2);
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
quickAction.show(v);
}
});
Button btn3 = (Button) this.findViewById(R.id.btn3);
btn3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
quickAction.show(v);
quickAction.setAnimStyle(QuickAction.ANIM_REFLECT);
}
});
}
}
//Popup Window Open and Dismiss
/**
* QuickAction dialog, shows action list as icon and text like the one in Gallery3D app. Currently supports vertical
* and horizontal layout.
*
*
*/
public class QuickAction extends PopupWindows implements OnDismissListener {
private View mRootView;
private ImageView mArrowUp;
private ImageView mArrowDown;
private LayoutInflater mInflater;
private ViewGroup mTrack;
private ScrollView mScroller;
private OnActionItemClickListener mItemClickListener;
private OnDismissListener mDismissListener;
private List<ActionItem> actionItems = new ArrayList<ActionItem>();
private boolean mDidAction;
private int mChildPos;
private int mInsertPos;
private int mAnimStyle;
private int mOrientation;
private int rootWidth=0;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int ANIM_GROW_FROM_LEFT = 1;
public static final int ANIM_GROW_FROM_RIGHT = 2;
public static final int ANIM_GROW_FROM_CENTER = 3;
public static final int ANIM_REFLECT = 4;
public static final int ANIM_AUTO = 5;
/**
* Constructor for default vertical layout
*
* @param context Context
*/
public QuickAction(Context context) {
this(context, VERTICAL);
}
/**
* Constructor allowing orientation override
*
* @param context Context
* @param orientation Layout orientation, can be vartical or horizontal
*/
public QuickAction(Context context, int orientation) {
super(context);
mOrientation = orientation;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (mOrientation == HORIZONTAL) {
setRootViewId(R.layout.popup_horizontal);
} else {
setRootViewId(R.layout.popup_vertical);
}
mAnimStyle = ANIM_AUTO;
mChildPos = 0;
}
/**
* Get action item at an index
*
* @param index Index of item (position from callback)
*
* @return Action Item at the position
*/
public ActionItem getActionItem(int index) {
return actionItems.get(index);
}
/**
* Set root view.
*
* @param id Layout resource id
*/
public void setRootViewId(int id) {
mRootView = (ViewGroup) mInflater.inflate(id, null);
mTrack = (ViewGroup) mRootView.findViewById(R.id.tracks);
mArrowDown = (ImageView) mRootView.findViewById(R.id.arrow_down);
mArrowUp = (ImageView) mRootView.findViewById(R.id.arrow_up);
mScroller = (ScrollView) mRootView.findViewById(R.id.scroller);
//This was previously defined on show() method, moved here to prevent force close that occured
//when tapping fastly on a view to show quickaction dialog.
//Thanx to zammbi (github.com/zammbi)
mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
setContentView(mRootView);
}
/**
* Set animation style
*
* @param mAnimStyle animation style, default is set to ANIM_AUTO
*/
public void setAnimStyle(int mAnimStyle) {
this.mAnimStyle = mAnimStyle;
}
/**
* Set listener for action item clicked.
*
* @param listener Listener
*/
public void setOnActionItemClickListener(OnActionItemClickListener listener) {
mItemClickListener = listener;
}
/**
* Add action item
*
* @param action {@link ActionItem}
*/
public void addActionItem(ActionItem action) {
actionItems.add(action);
String title = action.getTitle();
Drawable icon = action.getIcon();
View container;
if (mOrientation == HORIZONTAL) {
container = mInflater.inflate(R.layout.action_item_horizontal, null);
} else {
container = mInflater.inflate(R.layout.action_item_vertical, null);
}
ImageView img = (ImageView) container.findViewById(R.id.iv_icon);
TextView text = (TextView) container.findViewById(R.id.tv_title);
if (icon != null) {
img.setImageDrawable(icon);
} else {
img.setVisibility(View.GONE);
}
if (title != null) {
text.setText(title);
} else {
text.setVisibility(View.GONE);
}
final int pos = mChildPos;
final int actionId = action.getActionId();
container.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(QuickAction.this, pos, actionId);
}
if (!getActionItem(pos).isSticky()) {
mDidAction = true;
dismiss();
}
}
});
container.setFocusable(true);
container.setClickable(true);
if (mOrientation == HORIZONTAL && mChildPos != 0) {
View separator = mInflater.inflate(R.layout.horiz_separator, null);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
separator.setLayoutParams(params);
separator.setPadding(5, 0, 5, 0);
mTrack.addView(separator, mInsertPos);
mInsertPos++;
}
mTrack.addView(container, mInsertPos);
mChildPos++;
mInsertPos++;
}
/**
* Show quickaction popup. Popup is automatically positioned, on top or bottom of anchor view.
*
*/
public void show (View anchor) {
preShow();
int xPos, yPos, arrowPos;
mDidAction = false;
int[] location = new int[2];
anchor.getLocationOnScreen(location);
Rect anchorRect = new Rect(location[0], location[1], location[0] + anchor.getWidth(), location[1]
+ anchor.getHeight());
//mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mRootView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int rootHeight = mRootView.getMeasuredHeight();
if (rootWidth == 0) {
rootWidth = mRootView.getMeasuredWidth();
}
int screenWidth = mWindowManager.getDefaultDisplay().getWidth();
int screenHeight = mWindowManager.getDefaultDisplay().getHeight();
//automatically get X coord of popup (top left)
if ((anchorRect.left + rootWidth) > screenWidth) {
xPos = anchorRect.left - (rootWidth-anchor.getWidth());
xPos = (xPos < 0) ? 0 : xPos;
arrowPos = anchorRect.centerX()-xPos;
} else {
if (anchor.getWidth() > rootWidth) {
xPos = anchorRect.centerX() - (rootWidth/2);
} else {
xPos = anchorRect.left;
}
arrowPos = anchorRect.centerX()-xPos;
}
int dyTop = anchorRect.top;
int dyBottom = screenHeight - anchorRect.bottom;
boolean onTop = (dyTop > dyBottom) ? true : false;
if (onTop) {
if (rootHeight > dyTop) {
yPos = 15;
LayoutParams l = mScroller.getLayoutParams();
l.height = dyTop - anchor.getHeight();
} else {
yPos = anchorRect.top - rootHeight;
}
} else {
yPos = anchorRect.bottom;
if (rootHeight > dyBottom) {
LayoutParams l = mScroller.getLayoutParams();
l.height = dyBottom;
}
}
showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), arrowPos);
setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);
}
/**
* Set animation style
*
* @param screenWidth screen width
* @param requestedX distance from left edge
* @param onTop flag to indicate where the popup should be displayed. Set TRUE if displayed on top of anchor view
* and vice versa
*/
private void setAnimationStyle(int screenWidth, int requestedX, boolean onTop) {
int arrowPos = requestedX - mArrowUp.getMeasuredWidth()/2;
switch (mAnimStyle) {
case ANIM_GROW_FROM_LEFT:
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
break;
case ANIM_GROW_FROM_RIGHT:
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
break;
case ANIM_GROW_FROM_CENTER:
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
break;
case ANIM_REFLECT:
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect : R.style.Animations_PopDownMenu_Reflect);
break;
case ANIM_AUTO:
if (arrowPos <= screenWidth/4) {
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
} else if (arrowPos > screenWidth/4 && arrowPos < 3 * (screenWidth/4)) {
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
} else {
mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
}
break;
}
}
/**
* Show arrow
*
* @param whichArrow arrow type resource id
* @param requestedX distance from left screen
*/
private void showArrow(int whichArrow, int requestedX) {
final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;
final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;
final int arrowWidth = mArrowUp.getMeasuredWidth();
showArrow.setVisibility(View.VISIBLE);
ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();
param.leftMargin = requestedX - arrowWidth / 2;
hideArrow.setVisibility(View.INVISIBLE);
}
/**
* Set listener for window dismissed. This listener will only be fired if the quicakction dialog is dismissed
* by clicking outside the dialog or clicking on sticky item.
*/
public void setOnDismissListener(QuickAction.OnDismissListener listener) {
setOnDismissListener(this);
mDismissListener = listener;
}
@Override
public void onDismiss() {
if (!mDidAction && mDismissListener != null) {
mDismissListener.onDismiss();
}
}
/**
* Listener for item click
*
*/
public interface OnActionItemClickListener {
public abstract void onItemClick(QuickAction source, int pos, int actionId);
}
/**
* Listener for window dismiss
*
*/
public interface OnDismissListener {
public abstract void onDismiss();
}
}
//--------------- Create Another Class------------------------------------------------------------------------
public class PopupWindows {
protected Context mContext;
protected PopupWindow mWindow;
protected View mRootView;
protected Drawable mBackground = null;
protected WindowManager mWindowManager;
/**
* Constructor.
*
* @param context Context
*/
public PopupWindows(Context context) {
mContext = context;
mWindow = new PopupWindow(context);
mWindow.setTouchInterceptor(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mWindow.dismiss();
return true;
}
return false;
}
});
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
/**
* On dismiss
*/
protected void onDismiss() {
}
/**
* On show
*/
protected void onShow() {
}
/**
* On pre show
*/
protected void preShow() {
if (mRootView == null)
throw new IllegalStateException("setContentView was not called with a view to display.");
onShow();
if (mBackground == null)
mWindow.setBackgroundDrawable(new BitmapDrawable());
else
mWindow.setBackgroundDrawable(mBackground);
mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
mWindow.setTouchable(true);
mWindow.setFocusable(true);
mWindow.setOutsideTouchable(true);
mWindow.setContentView(mRootView);
}
/**
* Set background drawable.
*
* @param background Background drawable
*/
public void setBackgroundDrawable(Drawable background) {
mBackground = background;
}
/**
* Set content view.
*
* @param root Root view
*/
public void setContentView(View root) {
mRootView = root;
mWindow.setContentView(root);
}
/**
* Set content view.
*
* @param layoutResID Resource id
*/
public void setContentView(int layoutResID) {
LayoutInflater inflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
setContentView(inflator.inflate(layoutResID, null));
}
/**
* Set listener on window dismissed.
*
* @param listener
*/
public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
mWindow.setOnDismissListener(listener);
}
/**
* Dismiss the popup window.
*/
public void dismiss() {
mWindow.dismiss();
}
}
//Defining Action Items with Quick menu
/**
* Action item, displayed as menu with icon and text.
*/
public class ActionItem {
private Drawable icon;
private Bitmap thumb;
private String title;
private int actionId = -1;
private boolean selected;
private boolean sticky;
/**
* Constructor
*
* @param actionId Action id for case statements
* @param title Title
* @param icon Icon to use
*/
public ActionItem(int actionId, String title, Drawable icon) {
this.title = title;
this.icon = icon;
this.actionId = actionId;
}
/**
* Constructor
*/
public ActionItem() {
this(-1, null, null);
}
/**
* Constructor
*
* @param actionId Action id of the item
* @param title Text to show for the item
*/
public ActionItem(int actionId, String title) {
this(actionId, title, null);
}
/**
* Constructor
*
* @param icon {@link Drawable} action icon
*/
public ActionItem(Drawable icon) {
this(-1, null, icon);
}
/**
* Constructor
*
* @param actionId Action ID of item
* @param icon {@link Drawable} action icon
*/
public ActionItem(int actionId, Drawable icon) {
this(actionId, null, icon);
}
/**
* Set action title
*
* @param title action title
*/
public void setTitle(String title) {
this.title = title;
}
/**
* Get action title
*
* @return action title
*/
public String getTitle() {
return this.title;
}
/**
* Set action icon
*
* @param icon {@link Drawable} action icon
*/
public void setIcon(Drawable icon) {
this.icon = icon;
}
/**
* Get action icon
* @return {@link Drawable} action icon
*/
public Drawable getIcon() {
return this.icon;
}
/**
* Set action id
*
* @param actionId Action id for this action
*/
public void setActionId(int actionId) {
this.actionId = actionId;
}
/**
* @return Our action id
*/
public int getActionId() {
return actionId;
}
/**
* Set sticky status of button
*
* @param sticky true for sticky, pop up sends event but does not disappear
*/
public void setSticky(boolean sticky) {
this.sticky = sticky;
}
/**
* @return true if button is sticky, menu stays visible after press
*/
public boolean isSticky() {
return sticky;
}
/**
* Set selected flag;
*
* @param selected Flag to indicate the item is selected
*/
public void setSelected(boolean selected) {
this.selected = selected;
}
/**
* Check if item is selected
*
* @return true or false
*/
public boolean isSelected() {
return this.selected;
}
/**
* Set thumb
*
* @param thumb Thumb image
*/
public void setThumb(Bitmap thumb) {
this.thumb = thumb;
}
/**
* Get thumb image
*
* @return Thumb image
*/
public Bitmap getThumb() {
return this.thumb;
}
}

Awesome Gallery With Android....

Gallery With Reflection



//Main Activity
public class TryGallaryActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Integer[] images = { R.drawable.img0001, R.drawable.img0030,
R.drawable.img0100, R.drawable.img0130, R.drawable.img0200,
R.drawable.img0230, R.drawable.img0300, R.drawable.img0330,
R.drawable.img0354 };
ImageAdapter adapter = new ImageAdapter(this, images);
adapter.createReflectedImages();
GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.Gallery01);
galleryFlow.setAdapter(adapter);
}
}
//For Rotation make one class GalleryFlow
public class GalleryFlow extends Gallery {
private Camera mCamera = new Camera();
private int mMaxRotationAngle = 60;
private int mMaxZoom = -120;
private int mCoveflowCenter;
public GalleryFlow(Context context) {
super(context);
this.setStaticTransformationsEnabled(true);
}
public GalleryFlow(Context context, AttributeSet attrs) {
super(context, attrs);
this.setStaticTransformationsEnabled(true);
}
public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setStaticTransformationsEnabled(true);
}
public int getMaxRotationAngle() {
return mMaxRotationAngle;
}
public void setMaxRotationAngle(int maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}
public int getMaxZoom() {
return mMaxZoom;
}
public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}
private int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
+ getPaddingLeft();
}
private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
protected boolean getChildStaticTransformation(View child, Transformation t) {
final int childCenter = getCenterOfView(child);
final int childWidth = child.getWidth();
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if (childCenter == mCoveflowCenter) {
transformImageBitmap((ImageView) child, t, 0);
} else {
rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
: mMaxRotationAngle;
}
transformImageBitmap((ImageView) child, t, rotationAngle);
}
return true;
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
}
private void transformImageBitmap(ImageView child, Transformation t,
int rotationAngle) {
mCamera.save();
final Matrix imageMatrix = t.getMatrix();
final int imageHeight = child.getLayoutParams().height;
final int imageWidth = child.getLayoutParams().width;
final int rotation = Math.abs(rotationAngle);
mCamera.translate(0.0f, 0.0f, 100.0f);
// As the angle of the view gets less, zoom in
if (rotation < mMaxRotationAngle) {
float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
mCamera.translate(0.0f, 0.0f, zoomAmount);
}
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
mCamera.restore();
}
}
//And at last Image Adapter for Reflection and Shadow Effect...
public class ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;
private Integer[] mImageIds;
private ImageView[] mImages;
public ImageAdapter(Context c, Integer[] ImageIds) {
mContext = c;
mImageIds = ImageIds;
mImages = new ImageView[mImageIds.length];
}
public boolean createReflectedImages() {
final int reflectionGap = 4;
int index = 0;
for (int imageId : mImageIds) {
Bitmap originalImage = BitmapFactory.decodeResource(mContext
.getResources(), imageId);
int width = originalImage.getWidth();
int height = originalImage.getHeight();
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmapWithReflection);
canvas.drawBitmap(originalImage, 0, 0, null);
Paint deafaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap,
deafaultPaint);
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0, originalImage
.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(bitmapWithReflection);
imageView.setLayoutParams(new GalleryFlow.LayoutParams(450,300));
// imageView.setScaleType(ScaleType.MATRIX);
mImages[index++] = imageView;
}
return true;
}
private Resources getResources() {
// TODO Auto-generated method stub
return null;
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
return mImages[position];
}
public float getScale(boolean focused, int offset) {
return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
///return 1;
}
}
//Your main.xml should be like this ...
/*
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
>
<com.test.gly.GalleryFlow
android:id="@+id/Gallery01"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_centerInParent="true"/>
</RelativeLayout>
*/

Convert Numeric To Varchar in SQL


RIGHT('000000' + CONVERT(VARCHAR(6), BranchMaster.Pincode), 6)

Monday, 11 March 2013

Android Distance Direction With Google Map (JSON)

Output: 



NOTE: Check  your Android Manifest..

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
</uses-permission>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".JsonMapActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:name="com.google.android.maps" >
</uses-library>
</application>
</manifest>
view raw Manifest.xml hosted with ❤ by GitHub

My Layout.xml

<linearlayout android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<button android:id="@+id/btnPutAddress"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="Put New Address" >
</button>
<com .google.android.maps.mapview=""
android:apikey="your key"
android:id="@+id/mpBranch"
android:layout_height="fill_parent"
android:layout_width="fill_parent" />
<linearlayout android:id="@+id/zoom"
android:layout_alignparentbottom="true"
android:layout_centerhorizontal="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</linearlayout>
</linearlayout>
view raw My Layout.xml hosted with ❤ by GitHub

1) Create class MyOverLay which extends Overlay
public class MyOverLay extends Overlay
{
private GeoPoint gp1;
private GeoPoint gp2;
//private int mRadius=6;
private int mode=0;
private int defaultColor;
private String text="";
private Bitmap img = null;
Context mContext;
public MyOverLay(Context context,GeoPoint gp1,GeoPoint gp2,int mode) // GeoPoint is a int. (6E)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.mContext = context;
defaultColor = 999; // no defaultColor
}
public MyOverLay(GeoPoint gp1,GeoPoint gp2,int mode, int defaultColor)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.defaultColor = defaultColor;
}
public void setText(String t)
{
this.text = t;
}
public void setBitmap(Bitmap bitmap)
{
this.img = bitmap;
}
public int getMode()
{
return mode;
}
@Override
public boolean draw
(Canvas canvas, MapView mapView, boolean shadow, long when)
{
Projection projection = mapView.getProjection();
if (shadow == false)
{
Paint paint = new Paint();
paint.setAntiAlias(true);
Point point = new Point();
projection.toPixels(gp1, point);
// mode=1&#65306;start
if(mode==1)
{
if(defaultColor==999)
paint.setColor(Color.BLUE);
else
paint.setColor(defaultColor);
// start point
}
// mode=2&#65306;path
else if(mode==2)
{
if(defaultColor==999)
paint.setColor(Color.RED);
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
}
/* mode=3&#65306;end */
else if(mode==3)
{
/* the last path */
if(defaultColor==999)
paint.setColor(Color.GREEN);
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
/* end point */
}
}
return super.draw(canvas, mapView, shadow, when);
}
}
view raw MyOverLay.java hosted with ❤ by GitHub

2) Create another class CustomItemizedOverlay which extends ItemizedOverlay<OverlayItem>

 

class CustomItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private final ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
private Context context;
public CustomItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
public CustomItemizedOverlay(Drawable defaultMarker, Context context) {
this(defaultMarker);
this.context = context;
}
@Override
protected OverlayItem createItem(int i) {
return mapOverlays.get(i);
}
@Override
public int size() {
return mapOverlays.size();
}
public void addOverlay(OverlayItem overlay) {
mapOverlays.add(overlay);
this.populate();
}
@Override
protected boolean onTap(int index) {
OverlayItem item = mapOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(item.getTitle());dialog.setMessage(item.getSnippet());
dialog.setNeutralButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
return true;
}
}

3) Now Create Main Activity which extends MapActivity




public class JsonMapActivity extends MapActivity {
/** Called when the activity is first created. */
static double srclongitute, destlongitute;
static double srclatitude, destlatitude;
static String distance_km = "";
MapView mapView;
private JsonMapActivity _activity;
GeoPoint srcGeoPoint, destGeoPoint;
private static List<Overlay> mOverlays;
static String distance = "";
JSONObject jsonObj;
static String _path, start_address, end_address;
Drawable srcdrawable;
static String GPsLoc;
Context context = this;
Button btnDialog;
LocationManager locationManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
jsonObj = getLocationInfo("GandhiNagar", "Surat");
Toast.makeText(getApplicationContext(), "" + jsonObj.length(), 5)
.show();
if (getLatLong(jsonObj)) {
Log.i("srcLati", "" + srclatitude);
Log.i("srcLungi", "" + srclongitute);
Log.i("destLati", "" + destlatitude);
Log.i("destLungi", "" + destlongitute);
}
_activity = this;
mapView = (MapView) findViewById(R.id.mpBranch);
mapView.setBuiltInZoomControls(true);
mapView.displayZoomControls(true);
mapView.setClickable(true);
srcGeoPoint = new GeoPoint((int) (srclatitude * 1E6),
(int) (srclongitute * 1E6));
destGeoPoint = new GeoPoint((int) (destlatitude * 1E6),
(int) (destlongitute * 1E6));
List<Overlay> mapOverlays = mapView.getOverlays();
srcdrawable = getApplicationContext().getResources().getDrawable(
R.drawable.map_user);// // user
CustomItemizedOverlay srcitemizedOverlay = new CustomItemizedOverlay(
srcdrawable, this);
OverlayItem srcoverlayitem = new OverlayItem(srcGeoPoint,
"My Location", start_address);
Drawable destdrawable = this.getResources().getDrawable(
R.drawable.map_restaurant); // rest
CustomItemizedOverlay destitemizedOverlay = new CustomItemizedOverlay(
destdrawable, this);
OverlayItem destoverlayitem = new OverlayItem(destGeoPoint,
"FoodCorner Branch", end_address);
srcitemizedOverlay.addOverlay(srcoverlayitem);
destitemizedOverlay.addOverlay(destoverlayitem);
mapOverlays.add(srcitemizedOverlay);
mapOverlays.add(destitemizedOverlay);
connectAsyncTask _connectAsyncTask = new connectAsyncTask();
_connectAsyncTask.execute();
mOverlays = mapView.getOverlays();
mapView.getController().animateTo(srcGeoPoint);
mapView.getController().setZoom(8);
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
public static JSONObject getLocationInfo(String origin, String dest) {
StringBuilder stringBuilder = new StringBuilder();
try {
origin = origin.replaceAll(" ", "%20");
dest = dest.replaceAll(" ", "%20");
HttpPost httppost = new HttpPost(
"http://maps.googleapis.com/maps/api/directions/json?origin="
+ origin + "&destination=" + dest + "&sensor=false");
// http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los+Angeles,CA&sensor=false
HttpClient client = new DefaultHttpClient();
HttpResponse response;
stringBuilder = new StringBuilder();
response = client.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
JSONObject jsonObject = new JSONObject();
try {
jsonObject = new JSONObject(stringBuilder.toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject;
}
// --------------------------------------------------------------------------
// class Asych task
private class connectAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// SHOW YOU PROGRESS BAR HERE
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (_path != null) {
Overlay ol = new MyOverLay(_activity, srcGeoPoint, srcGeoPoint,
1);
mOverlays.add(ol);
List<GeoPoint> _geopoints = decodePoly(_path);
GeoPoint gp1;
GeoPoint gp2;
gp2 = _geopoints.get(0);
for (int i = 1; i < _geopoints.size(); i++) // the last one
// would be
// crash
{
gp1 = gp2;
gp2 = _geopoints.get(i);
Overlay ol1 = new MyOverLay(gp1, gp2, 2, Color.BLUE);
mOverlays.add(ol1);
}
Overlay ol2 = new MyOverLay(_activity, destGeoPoint,
destGeoPoint, 3);
mOverlays.add(ol2);
// DISMISS PROGRESS BAR HERE
} else {
// showAlert AS "Unable to find the route"
}
Overlay ol2 = new MyOverLay(_activity, destGeoPoint, destGeoPoint,
3);
mOverlays.add(ol2);
// DISMISS PROGRESS BAR HERE
}
}// end of class
// --------------------------------------------------------------------------
private List<GeoPoint> decodePoly(String encoded) {
List<GeoPoint> poly = new ArrayList<GeoPoint>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6),
(int) (((double) lng / 1E5) * 1E6));
poly.add(p);
}
return poly;
}
// --------------------------------------------------
public static boolean getLatLong(JSONObject jsonObject) {
try {
JSONObject jsonOb = ((JSONArray) jsonObject.get("routes"))
.getJSONObject(0);
JSONArray jsonArray = jsonOb.getJSONArray("legs");
JSONObject j1 = jsonArray.getJSONObject(0);
srclatitude = j1.getJSONObject("start_location").getDouble("lat");
srclongitute = j1.getJSONObject("start_location").getDouble("lng");
destlatitude = j1.getJSONObject("end_location").getDouble("lat");
destlongitute = j1.getJSONObject("end_location").getDouble("lng");
start_address = j1.getString("start_address");
end_address = j1.getString("end_address");
JSONObject ja = j1.getJSONObject("distance");
// Log.i("jsonOb size", "" + ja.getString("text"));
JSONObject ja_line = jsonOb.getJSONObject("overview_polyline");
// Log.i("ja_line size", "" + ja_line.getString("points"));
_path = ja_line.getString("points");
} catch (JSONException e) {
return false;
}
return true;
}
public class MyLocationListener implements LocationListener
{
@Override
public void onLocationChanged(Location loc)
{
GPsLoc=new Double(loc.getLatitude()).toString()+",";
GPsLoc+=loc.getLongitude();
String Text = "My current location is: " + "Latitud = "
+ loc.getLatitude() + "Longitud = " + loc.getLongitude();
Toast.makeText(getApplicationContext(), Text, Toast.LENGTH_SHORT)
.show();
}
@Override
public void onProviderDisabled(String provider)
{
Toast.makeText(getApplicationContext(), "Gps Disabled",
Toast.LENGTH_SHORT).show();
}
@Override
public void onProviderEnabled(String provider)
{
Toast.makeText(getApplicationContext(), "Gps Enabled",
Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}/* End of Class MyLocationListener */
}