Thursday, December 8, 2011

Animation Drawbles in Android

To show an animation in app like sailing ship or flying aeroplane with the help of static image frames you need to make a drawble like this:

/drawbles/loading_animation.xml


<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
id="selected"
android:oneshot="true"
android:animationOrder="reverse"
>
<item
android:drawable="@drawable/loading_1"
android:duration="80" />
<item
android:drawable="@drawable/loading_2"
android:duration="80" />
<item
android:drawable="@drawable/loading_3"
android:duration="80" />
<item
android:drawable="@drawable/loading_4"
android:duration="80" />
<item
android:drawable="@drawable/loading_5"
android:duration="80" />
<item
android:drawable="@drawable/loading_6"
android:duration="80" />
<item
android:drawable="@drawable/loading_7"
android:duration="80" />
<item
android:drawable="@drawable/loading_8"
android:duration="80" />
<item
android:drawable="@drawable/loading_9"
android:duration="80" />
<item
android:drawable="@drawable/loading_10"
android:duration="80" />
<item
android:drawable="@drawable/loading_11"
android:duration="80" />
<item
android:drawable="@drawable/loading_12"
android:duration="80" />
<item
android:drawable="@drawable/loading_13"
android:duration="80" />
<item
android:drawable="@drawable/loading_14"
android:duration="80" />
<item
android:drawable="@drawable/loading_15"
android:duration="80" />
</animation-list>


Then in the layout.xml, define your image view like this:


<ImageView android:layout_below="@id/image1"
android:layout_centerHorizontal="true" android:layout_marginTop="20dp"
android:id="@+id/ivLoading" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:background="@drawable/loading_animation" />

Then in the Activity file:

AnimationDrawable loadingAnimation;
loadingAnimation = (AnimationDrawable) ivLoading.getBackground(); // ivLoading is the imageView created in layout.xml
Now start the animation by:
loadingAnimation.start();


Thursday, November 3, 2011

Simple cursor adapter made easy

Here is how to use the CursorAdapter in Android.

Outline:
In this example, we are gonna draw a list, using the CursorAdapter, for the cursor pointing to a table mapped with the list of my pojo "Promotion" basically containing the imageUrl, title and similar kind of info.
"ThumbnailFetchListener" and "downloadThumbnail" are interface and method respectively to download the images from server in the separate thread.
"promotion_banner" is the layout I use as the listViewItem.


 private class MyCursorAdapter extends CursorAdapter {


        LayoutInflater inflater;
        int titleColumnIndex;
        int imageUrlColumnIndex;

        public PromotionsGalleryAdapter(Context context, Cursor c,
                boolean autoRequery) {
            super(context, c, autoRequery);
            init(context, c);
        }
        private void init(Context context, Cursor c) {
            inflater = LayoutInflater.from(context);
            titleColumnIndex = c.getColumnIndexOrThrow(Promotions.TITLE);
            imageUrlColumnIndex = c.getColumnIndexOrThrow(Promotions.IMAGE_URL);
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            Logger.log(TAG, "newView called");
            View v = inflater.inflate(R.layout.promotion_banner, null);
            v.setLayoutParams(new Gallery.LayoutParams(
                    FrameLayout.LayoutParams.FILL_PARENT,
                    FrameLayout.LayoutParams.FILL_PARENT));
            return v;
        }


        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            String title = cursor.getString(titleColumnIndex);
            String imageUrl = cursor.getString(imageUrlColumnIndex);
            Bitmap bitmap = null;
            if (TextUtils.isEmpty(imageUrl)) {
                view.findViewById(R.id.progress).setVisibility(View.GONE);
            } else {
                bitmap = BitmapCache.loadBitmap(imageUrl);
                if (bitmap == null) {
                    serviceHelper.downloadThumbnail(imageUrl,
                            new ThumbnailFetchListener());
                } else {
                    view.findViewById(R.id.progress).setVisibility(View.GONE);
                    view.findViewById(R.id.promotion_image_iv).setVisibility(
                            View.VISIBLE);
                }
            }
            ((ImageView) view.findViewById(R.id.promotion_image_iv))
                    .setImageBitmap(bitmap);
        }


        private class ThumbnailFetchListener implements
                ThumbnailDownloadListener {


            @Override
            public void onComplete(Bitmap bitmap, String url, String filename) {
                BitmapCache.save(url, bitmap);
                notifyDataSetChanged();
            }


            @Override
            public void onError(String url) {
                // ignore
            }        }    }

Friday, May 6, 2011

Turn off, Turn on wifi in android via code

Here is how to turn on and turn off wifi in android.

First you need to declare the following in your manifest file:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>


Now in your activity, do this to control WiFi:

private WifiManager wifiManager;
@Override 
public void onCreate(Bundle icicle) {
  -- your usual stuff -- 

  // Get the Wifi service from our system
  wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);

  // Check the our wifi is currently turned on or turned off
  if(wifiManager.isWifiEnabled()){
    wifiManager.setWifiEnabled(false);
  }else{
    wifiManager.setWifiEnabled(true);
  }
}

Source: 
Complete reference to the WiFi code in android

Saturday, April 16, 2011

Twitter integration in an Android App

Prerequisites:

  1. Consumer Key
  2. Consumer key secret
  3. Signpost-core and signpost-commonshttp libs
Approach:
launch the twitter authentication in a webview and present the login page to user in it.
When user enters the credentials, validate them and proceed.

Activity TwitterConnectWebActivity:
** You can copy the following whole activity in your code, as its a standalone code

public class TwitterConnectWebActivity extends Activity {
    private static final String TAG = "TwitterConnectWebActivity";
    private static String TWITTER_IMAGE_URL = "http://api.twitter.com/1/users/profile_image/@user.json";

    private static final int LOADING_DIALOG_ID = 0;
    protected final String CALLBACKURL = "OauthTwitter://taylorswiftapp";
    protected static CommonsHttpOAuthConsumer twitterHttpOauthConsumer;
    protected static OAuthProvider twitterHttpOauthprovider;
    protected int TWITTER_LOGIN_REQUEST_CODE = 1;
    protected int TWITTER_LOGOUT_REQUEST_CODE = 2;

    AccessToken twitterAuthToken;

    Context context;
    WebView webview;
    ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tw_connect_web_activity);
        context = this;
        webview = (WebView) findViewById(R.id.webview);
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);
        new RequestTokenSecretUrlTask().execute();
    }

    private class RequestTokenSecretUrlTask extends
            AsyncTask<Void, Void, String> {

        @Override
        protected void onPreExecute() {
            showDialog(LOADING_DIALOG_ID);
        }

        @Override
        protected String doInBackground(Void... params) {
            try {
                twitterHttpOauthConsumer = new CommonsHttpOAuthConsumer( "YOUR_CONSUMER_KEY",
"YOUR_CONSUMER_SECRET");

                twitterHttpOauthprovider = new DefaultOAuthProvider(
                        "https://api.twitter.com/oauth/request_token",
                        "https://api.twitter.com/oauth/access_token",
                        "https://api.twitter.com/oauth/authorize");
                String authUrl = twitterHttpOauthprovider.retrieveRequestToken(
                        twitterHttpOauthConsumer, CALLBACKURL);
                Log.e(TAG, "Load URL : " + authUrl);
                return authUrl;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String authUrl) {
            dismissDialog(LOADING_DIALOG_ID);

            webview.setWebViewClient(new TwitterWebViewClient());
            webview.getSettings().setPluginsEnabled(true);
            webview.getSettings().setJavaScriptEnabled(true);
            webview.getSettings().setLayoutAlgorithm(
                    WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
            webview.loadUrl(authUrl);
        }
    }

    private class TwitterWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Log.e(TAG, "shouldOverrideUrlLoading() -> url:" + url);

            progressBar.setVisibility(View.VISIBLE);

            Uri uri = Uri.parse(url);
            if (uri != null && uri.toString().startsWith(CALLBACKURL)) {
                String verifier = uri
                        .getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
                try {
                    twitterHttpOauthprovider.retrieveAccessToken(
                            twitterHttpOauthConsumer, verifier);

                    twitterAuthToken = new AccessToken(twitterHttpOauthConsumer
                            .getToken(), twitterHttpOauthConsumer
                            .getTokenSecret());

                    ConfigurationBuilder cb = new ConfigurationBuilder();
                    cb.setDebugEnabled(true).setOAuthConsumerKey(
                            twitterHttpOauthConsumer.getConsumerKey())
                            .setOAuthConsumerSecret(
                                    twitterHttpOauthConsumer
                                            .getConsumerSecret())
                            .setOAuthAccessToken(twitterAuthToken.getToken())
                            .setOAuthAccessTokenSecret(
                                    twitterAuthToken.getTokenSecret());
                    TwitterFactory tf = new TwitterFactory(cb.build());
                    Twitter twitter = tf.getInstance();

                    // if authentication is done,set result to ok finish this
                    // activity
                    Intent intent = new Intent();
                    intent
                            .putExtra("access_token", twitterAuthToken
                                    .getToken());
                    intent.putExtra("access_secret", twitterAuthToken
                            .getTokenSecret());

                    String name = twitter.getScreenName();

                    intent.putExtra("twitter_screen_name", name);
                    intent.putExtra("twitter_uid", "" + twitter.getId());
                    intent
                            .putExtra("twitter_image_url", ""
                                    + twitter.getProfileImage(name,
                                            ProfileImage.BIGGER));

                    setResult(RESULT_OK, intent);
                    finish();

                } catch (Exception e) {
                    e.printStackTrace();
                }
                return true;
            } else {
                Log.e(TAG, " ::2222:: Twitter URl --- " + url);
                view.loadUrl(url);
                return true;
            }
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            progressBar.setVisibility(View.INVISIBLE);
        }

    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case LOADING_DIALOG_ID:
            ProgressDialog dialog = new ProgressDialog(this);
            dialog.setMessage("Loading...");
            dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                public void onCancel(DialogInterface arg0) {
                    finish();
                }
            });
            return dialog;
        default:
            return super.onCreateDialog(id);
        }
    }
}


NOW, from the point where you wanna start this twitter stuff, just call:
startActivity(new Intent(this, TwitterConnectWebActivity.class));

In manifest add this permission:

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

You are done.


Thursday, April 7, 2011

Android: Broadcast Receivers made simple

Lets say you have a requirement:
App starts with Activities A,B and C and then Activity D is started.
A,B and C are the activities for just one time like Terms and Conditions etc, that user should not be able to see them once he has successfully navigated from A->B->C and then to D.

Lets solve this basic problem using BroadcastReceivers:

In your Activity A:

Activity A{

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

...
IntentFilter myFilter = new IntentFilter("finish"); // "finish" can be any string you wanna provide
registerReceiver(myReceiver, myFilter);


}


BroadcastReceiver myReceiver = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
Log.d("ActivityA", "finishing A");
finish();
}
};

@Override
protected void onDestroy() {
unregisterReceiver(myReceiver);
super.onDestroy();
}


}

Similarly register for this broadcast receiver in all other activities you wanna finish at a single action.

Now in Activity D,

you just need to call
sendBroadcast(new Intent("finish"));


at the point where you want that all the activities who have registered for your receiver must get finished.

P.S. Its mandatory to unregister the receiver at some point else there can be a possible exception.