Home >> Miscellaneous
Android Example discussed in a step by step way:
This Application Title: DownloadAnyFileFormat
(This Application on Android Platform can download file of any extension
other than those webpages with MIME-TYPE as Text, HTML, HTM and similar)
I have created an application on Android Platform that I am going to
walk you through in this write-up. I havn't tried to publish this
application in Android App Market from Google. One can download this
application for free from this web site (This program is provided on
"AS IS" basis, so no warranty and/or guarantee of any kind is extended
from our side, user should use this program/application at user's
own risk).
If any one is not interested in
downloading this application from
this web site for personal use only, for them I would like to show following
ways to quickly assemble source code for this application and build one's own
application for personal use only (License agreement of this web site prohibits
any commercial usage of this application without written consent from the Author,
who can be reachable at ----usingframeworks @ gmail . com----).
While building this app, I have used development environment as suggested and
as per the following Link/URL.
http://developer.android.com/sdk/index.html
http://developer.android.com/sdk/installing.html#Preparing
Software Environment used to build this application :
-> Eclipse Galileo
-> JDK 1.5 or above
-> Google Android Emulator
-> Tomcat 5.5 webserver
-> A real device/mobile phone with Android version 2.1 Platform.
Objective of DownloadAnyFileFormat:
Provide a text box on main screen for user to provide URL with the file to be
downloaded and on clicking of a button, this application creates an Async task
and fetches content of this application on Android Platform and saves it locally
in SDCARD (by default).
Common validations such as whether SDCARD is present and functional or not,
whether network connection is up or not, whether the URL is valid and is not
that of a displayable content such as Text/HTML/ any other similar type.
This application on Android Platform has various areas of concern (so to say),
such as Screen Layout, Background process/Async to handle downloading activity
without screen dependencies, passing download progress updates to the progress
bar User Interface, handling validations such as whether internet connection
is active or not, whether SD Card is present or not etc.
There is a feature of notification from Android API, that I have used in this
application. With notification one can monitor download progress even if this
application is not running and user has started another activity/application
in the device.
For notification related code, I have written a helper "NotificationHelper.java"
as shown below:
NotificationHelper.java
/**
* This source code is provided on "AS IS" basis,
* without waranty or guaranty of any kind.
* Author: usingframeworks@gmail.com
* © 2010, All Right Reserved.
*/
package com.tie.helper;
import android.R;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
public class NotificationHelper {
private Context context;
private NotificationManager notifMgr;
private PendingIntent mContent;
private Notification notification;
public NotificationHelper(Context context) {
this.context = context;
}
public void createNotification() {
notifMgr = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.alert_dark_frame;
CharSequence text = "Downloading...";
long when = System.currentTimeMillis();
notification = new Notification(icon,text,when);
Intent notificationIntent = new Intent();
mContent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, "Downloading", "0% complete", mContent);
notification.flags = Notification.FLAG_ONGOING_EVENT;
notifMgr.notify(1, notification);
}
public void progressUpdate(int progress) {
CharSequence txt = progress+"% complete";
notification.setLatestEventInfo(context, "Downloading", txt, mContent);
notifMgr.notify(1, notification);
}
public void completed() {
notifMgr.cancel(1);
}
}
Notification Manager has to be notified with update and progressUpdate method
does this. While createNotification method initializes the NotificationManager
system service, and creates the notification with appropriate settings.
Calling notify method on NotificationManager instance by passing the
notification object as argument starts the notification functionality for this
application on Android Platform.
How to setup development environment is not scope of this write-up, but instead
I am going to explain the source code for this Application on Android Platform.
While creating a new project within the IDE (in Eclipse workspace), one can choose
appropriate properties, such as minSdkVersion, version number, name etc.
For this application on Android Platform with all permissions required, I have
come-up with the AndroidManifest.xml file as follows:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tie.main"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="@drawable/downloadany" android:label="@string/app_name">
<activity android:name=".DownloadAnyFileFormat"
android:label="@string/app_name"
android:configChanges="orientation"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
<receiver android:name=".DownloadAnyFileFormat"/>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
One would like to know why am I asking for these three permissions at all,
ACCESS_NETWORK_STATE - for checking connectivity to network for providing early
warning to user with "no network access" kinda error message.
INTERNET - for downloading file.
WRITE_EXTERNAL_STORAGE - for creating appropriate local file and storing file content
at runtime.
receiver tag is for making this application to receive appropriate Intents from
Platform based on some user initiated action, and for broadcasts from
Android Platform there is a inner class DownloadLinkReceiver within the main
application class file, would get a callback to the onReceive method whenever
appropriate broadcast is being initiated.
onCreate method will receive Intent if any while DownloadAnyFileFormat will
fire oncreate method as part of the life-cycle initiated for this application
on Android Platform.
Intent intent = getIntent();
if(intent != null) {
tmpLink = intent.getStringExtra(Intent.EXTRA_TEXT);
}
....
....
class DownloadLinkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
//System.out.println("****"+arg1.getData().toString()+"*****");
Uri data = arg1.getData();
//Bundle extra = arg1.getExtras();
if(data != null) {
tmpLink = data.toString();
}
}
}
....
....
This particular feature is useful if the URL is being shared from some other
application as a broadcast and user opted to choose DownloadAnyFileFormat
from the list of application in the context menu.
onClickListener is set on a button on screen to receive the onClick method
callback call to start processing the main functionality of this application,
that is doing some pre-download validations as mentioned earlier in this page.
.....
.....
ConnectivityManager conMgr = (ConnectivityManager) getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
if(conMgr != null && conMgr.getActiveNetworkInfo() != null
&& conMgr.getActiveNetworkInfo().isAvailable()) {
if(Environment.getExternalStorageState() != null
&& !Environment.getExternalStorageState()
.equals(Environment.MEDIA_NOFS)) {
....
....
The above code retrieves the Connectivity service from the application context,
and checks for network is active or not, based on the status next validation
for External storage/SDcard status is checked.
The actual downloading happens from within a inner class that extends
AsyncTask api from Android Platform.
I have writtena inner class to do downloading of actual content, as shown below:
....
....
private class DownloadFile extends AsyncTask<Object, Integer, Long> {
//Initializing variables for downloading content using APIs.
// .....
public DownloadFile(Context mContext) {
//create instance of the notification helper.
notifyHelper = new NotificationHelper(mContext);
this.mContext= mContext;
}
private Long loadImageFromNetwork(Object params) {
//code for intializing connection to the URL supplied using params
//argument.....
bis = new BufferedInputStream(din);
while((count = din.read(bt)) != -1) {
total += count;
progress = computeProgress(total,cLength);
publishProgress(progress);
dout.write(bt, 0, count);
}
dout.flush();
}
................
................
return new Long(total);
}
private Integer computeProgress(int i, int cLength) {
return new Integer((i * 100)/cLength);
}
private int getProgress() {
return progress;
}
private void updateProgress(int progress) {
publishProgress(progress);
}
@Override
protected Long doInBackground(Object... params) {
return loadImageFromNetwork(params[0]);
}
@Override
protected void onPreExecute() {
notifyHelper.createNotification();
}
@Override
protected void onPostExecute(Long result) {
notifyHelper.completed();
urlTxt1.setText("Downloaded " + result + " bytes");
urlTxt1.requestFocus();
pD.dismiss();
if(cLength == result)
(Toast.makeText(mContext, "Downloading completed successfully..."
, Toast.LENGTH_LONG)).show();
else
(Toast.makeText(mContext, "Downloading Unsuccessful..."
, Toast.LENGTH_LONG)).show();
}
@Override
protected void onProgressUpdate(Integer... progress) {
pD.setProgress(progress[0].intValue());
notifyHelper.progressUpdate(progress[0].intValue());
urlTxt1.setText("Downloaded: "+progress[0]+"% completed");
urlTxt1.requestFocus();
}
}
....
....
Implementation to this class is mostly based on my understanding of the task
that this class is supposed to do and the callbacks this class is going to
receive download progress updates and many more type of functionalities Android API
provides such as the Toast for showing appropriate messages to user.
Screen layout for this application on Android Platform is designed with
the tags in main.xml file as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearLayoutMain"
android:orientation="vertical"
android:layout_height="fill_parent"
android:animationCache="false" android:layout_width="fill_parent"
android:soundEffectsEnabled="true">
<TextView android:layout_width="wrap_content" android:text="@string/url"
android:layout_height="wrap_content" android:id="@+id/textView1">
</TextView>
<EditText android:autoText="true" android:id="@+id/editText1"
android:editable="false" android:singleLine="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</EditText>
<LinearLayout android:id="@+id/linearLayout1"
android:scrollbars="horizontal|vertical"
android:soundEffectsEnabled="true"
android:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="@string/go"
android:id="@+id/button1">
</Button>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView2">
</TextView>
</LinearLayout>
</LinearLayout>
Screen Layout for the notification for this application, and the XML file
as shown below:
notification_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="3dp">
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#000" />
</LinearLayout>
The above layout for notification purpose can be re-designed to have
any other look and feel.
#Please provide your suggestions regarding this page and about this example
as well.
If anything missed out , please let me know at
techienjoy at yahoo . com
|
|
|
|
|
|
| Android ListView Example : |
Example on Android ListView and
explained with a very simple scenario
and article with appropriate screens
captured and shown.
|
|
| Android ListView Example : |
Example on Android List View
explained with a very simple scenario
and article with appropriate screens
captured and shown.
|
|
| Android ListView Example : |
Example on Android ListView
explained with a very simple scenario
whereby showing folder and files with
structure and appropriate screens
captured and shown.
|
|
|
| Android Gallery Example : |
Example on Android Gallery View
explained with a very simple scenario
and appropriate screens captured and shown.
|
|
|
|
|
|
|
|
|
|
|
| Google GWT Example : |
Example using GWT and some design patterns and various
ways of implementing this example.
|
|
|
|
| Android Sensors Example : |
Example on Android Sensors Listed and
explained with a very simple scenario
and article with appropriate screens
captured and shown.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Android Examples : |
List of ANDROid examples
with source code and output
screens captured and shown.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Android Tab View Example : |
Example on Android Tab View
explained with a very simple scenario
and appropriate screens captured and shown.
|
|
|
|
|
|
|
|
|
|