Android Application Development in step by step info
Part 04
Android Notifications
Android Toast class provides a handy way to show users alerts but problem is that these alerts are not persistent which means alert flashes on the screen for a few seconds and then disappears.
For important messages to be given to the user, it is required to have more persistent method. Anotification is a message you can display as an icon at the top of the device which we call notification bar or status bar.
To see the details of the notification, you will have to select the icon which will display notification drwerhaving detail about the notification. While working with emulator with virtual device, you will have to click and drag down the status bar to expand it which will give you detail as follows. This will be just 64 dptall and called normal view.
Above expanded form can have a Big View which will have additional detail about the notification? You can add upto six additional lines in the notification. The following screenshot shows such notification.
Create and Send Notifications
You have simple way to create a notification. Follow the following steps in your application to create a notification:
Step 1 - Create Notification Builder
As a first step is to create a notification builder usingNotificationCompat.Builder.build(). You will use Notification Builder to set various Notification properties like its small and large icons, title, priority etc.
NotificationCompat.Builder mBuilder = newNotificationCompat.Builder(this)
Step 2 - Setting Notification Properties
Once you have Builder object, you can set its Notification properties using Builder object as per your requirement. But this is mandatory to set at least following:
A small icon, set by setSmallIcon()
A title, set by setContentTitle()
Detail text, set by setContentText()
mBuilder.setSmallIcon(R.drawable.notification_icon);
mBuilder.setContentTitle("Notification Alert, Click Me!");
mBuilder.setContentText("Hi, This is Android Notification Detail!");
You have plenty of optional properties which you can set for your notification. To learn more about them, see the reference documentation forNotificationCompat.Builder.
Step 3 - Attach Actions
This is an optional part and required if you want to attach an action with the notification. An action allows users to go directly from the notification to an Activityin your application, where they can look at one or more events or do further work.
The action is defined by a PendingIntent containing an Intent that starts an Activity in your application. To associate the PendingIntent with a gesture, call the appropriate method of NotificationCompat.Builder. For example, if you want to start Activity when the user clicks the notification text in the notification drawer, you add the PendingIntent by callingsetContentIntent().
A PendingIntent object helps you to perform an action on your application’s behalf, often at a later time, without caring of whether or not your application is running.
We take help of stack builder object which will contain an artificial back stack for the started Activity. This ensures that navigating backward from the Activity leads out of your application to the Home screen.
Intent resultIntent = new Intent(this,ResultActivity.class);
TaskStackBuilder stackBuilder =TaskStackBuilder.create(this);
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
Step 4 - Issue the notification
Finally, you pass the Notification object to the system by calling NotificationManager.notify() to send your notification. Make sure you callNotificationCompat.Builder.build() method on builder object before notifying it. This method combines all of the options that have been set and return a new Notification object.
NotificationManager mNotificationManager =
(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
// notificationID allows you to update the notification later on.
mNotificationManager.notify(notificationID,mBuilder.build());
The NotificationCompat.Builder Class
The NotificationCompat.Builder class allows easier control over all the flags, as well as help constructing the typical notification layouts. Following are few important and most frequently used methods available as a part of NotificationCompat.Builder class.
S.N.
Constants & Description
1
Notification build()
Combine all of the options that have been set and return a new Notification object.
Combine all of the options that have been set and return a new Notification object.
2
NotificationCompat.Builder setAutoCancel(boolean autoCancel)
Setting this flag will make it so the notification is automatically canceled when the user clicks it in the panel.
Setting this flag will make it so the notification is automatically canceled when the user clicks it in the panel.
3
NotificationCompat.Builder setContent(RemoteViews views)
Supply a custom RemoteViews to use instead of the standard one.
Supply a custom RemoteViews to use instead of the standard one.
4
NotificationCompat.Builder setContentInfo(CharSequence info)
Set the large text at the right-hand side of the notification.
Set the large text at the right-hand side of the notification.
5
NotificationCompat.Builder setContentIntent(PendingIntent intent)
Supply a PendingIntent to send when the notification is clicked.
Supply a PendingIntent to send when the notification is clicked.
6
NotificationCompat.Builder setContentText(CharSequence text)
Set the text (second row) of the notification, in a standard notification.
Set the text (second row) of the notification, in a standard notification.
7
NotificationCompat.Builder setContentTitle(CharSequence title)
Set the text (first row) of the notification, in a standard notification.
Set the text (first row) of the notification, in a standard notification.
8
NotificationCompat.Builder setDefaults (intdefaults)
Set the default notification options that will be used.
Set the default notification options that will be used.
9
NotificationCompat.Builder setLargeIcon(Bitmap icon)
Set the large icon that is shown in the ticker and notification.
Set the large icon that is shown in the ticker and notification.
10
NotificationCompat.Builder setNumber (intnumber)
Set the large number at the right-hand side of the notification.
Set the large number at the right-hand side of the notification.
11
NotificationCompat.Builder setOngoing(boolean ongoing)
Set whether this is an ongoing notification.
Set whether this is an ongoing notification.
12
NotificationCompat.Builder setSmallIcon (inticon)
Set the small icon to use in the notification layouts.
Set the small icon to use in the notification layouts.
13
NotificationCompat.Builder setStyle(NotificationCompat.Style style)
Add a rich notification style to be applied at build time.
Add a rich notification style to be applied at build time.
14
NotificationCompat.Builder setTicker(CharSequence tickerText)
Set the text that is displayed in the status bar when the notification first arrives.
Set the text that is displayed in the status bar when the notification first arrives.
15
NotificationCompat.Builder setVibrate (long[] pattern)
Set the vibration pattern to use.
Set the vibration pattern to use.
16
NotificationCompat.Builder setWhen (long when)
Set the time that the event occurred. Notifications in the panel are sorted by this time.
Set the time that the event occurred. Notifications in the panel are sorted by this time.
Example
Following example shows the functionality of aAndroid notification using aNotificationCompat.Builder Class which has been introduced in Android 4.1.
Step
Description
1
You will use Eclipse IDE to create an Android application and name it as NotificationDemounder a package com.example.notificationdemo. While creating this project, make sure youTarget SDK and Compile With at the latest version of Android SDK to use higher levels of APIs.
2
Modify src/MainActivity.java file and add the code to define three methods startNotification(),cancelNotification() and updateNotification() to cover maximum functionality related to Android notifications.
3
Create a new Java file src/NotificationView.java, which will be used to display new layout as a part of new activity which will be started when user will click any of the notifications
4
Copy image woman.png in res/drawable-*folders and this image will be used as Notification icons. You can use images with different resolution in case you want to provide them for different devices.
5
Modify layout XML file res/layout/activity_main.xml to add three buttons in linear layout.
6
Create a new layout XML file res/layout/notification.xml. This will be used as layout file for new activity which will start when user will click any of the notifications.
7
Modify res/values/strings.xml to define required constant values
8
Run the application to launch Android emulator and verify the result of the changes done in theaplication.
Following is the content of the modified main activity file src/com.example.notificationdemo/MainActivity.java. This file can include each of the fundamental lifecycle methods.
package com.example.notificationdemo;
import android.os.Bundle;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
importandroid.support.v4.app.NotificationCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private NotificationManagermNotificationManager;
private int notificationID = 100;
private int numMessages = 0;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startBtn = (Button)findViewById(R.id.start);
startBtn.setOnClickListener(newView.OnClickListener() {
public void onClick(View view) {
displayNotification();
}
});
Button cancelBtn = (Button)findViewById(R.id.cancel);
cancelBtn.setOnClickListener(newView.OnClickListener() {
public void onClick(View view) {
cancelNotification();
}
});
Button updateBtn = (Button)findViewById(R.id.update);
updateBtn.setOnClickListener(newView.OnClickListener() {
public void onClick(View view) {
updateNotification();
}
});
}
protected void displayNotification() {
Log.i("Start", "notification");
/* Invoking the default notification service */
NotificationCompat.Builder mBuilder=
newNotificationCompat.Builder(this);
mBuilder.setContentTitle("New Message");
mBuilder.setContentText("You've received new message.");
mBuilder.setTicker("New Message Alert!");
mBuilder.setSmallIcon(R.drawable.woman);
/* Increase notification number every time a new notification arrives */
mBuilder.setNumber(++numMessages);
/* Creates an explicit intent for an Activity in your app */
Intent resultIntent = newIntent(this, NotificationView.class);
TaskStackBuilder stackBuilder =TaskStackBuilder.create(this);
stackBuilder.addParentStack(NotificationView.class);
/* Adds the Intent that starts the Activity to the top of the stack */
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
mNotificationManager =
(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
/* notificationID allows you to update the notification later on. */
mNotificationManager.notify(notificationID,mBuilder.build());
}
protected void cancelNotification() {
Log.i("Cancel", "notification");
mNotificationManager.cancel(notificationID);
}
protected void updateNotification() {
Log.i("Update", "notification");
/* Invoking the default notification service */
NotificationCompat.Builder mBuilder=
newNotificationCompat.Builder(this);
mBuilder.setContentTitle("Updated Message");
mBuilder.setContentText("You've got updated message.");
mBuilder.setTicker("Updated Message Alert!");
mBuilder.setSmallIcon(R.drawable.woman);
/* Increase notification number every time a new notification arrives */
mBuilder.setNumber(++numMessages);
/* Creates an explicit intent for an Activity in your app */
Intent resultIntent = newIntent(this, NotificationView.class);
TaskStackBuilder stackBuilder =TaskStackBuilder.create(this);
stackBuilder.addParentStack(NotificationView.class);
/* Adds the Intent that starts the Activity to the top of the stack */
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
mNotificationManager =
(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
/* Update the existing notification using same notification ID */
mNotificationManager.notify(notificationID,mBuilder.build());
}
}
Following is the content of the modified main activity file src/com.example.notificationdemo/NotificationView.java.
package com.example.notificationdemo;
import android.os.Bundle;
import android.app.Activity;
public class NotificationView extends Activity{
@Override
public void onCreate(BundlesavedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.notification);
}
}
Following will be the content of res/layout/activity_main.xml file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button android:id="@+id/start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/start_note"/>
<Button android:id="@+id/cancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/cancel_note" />
<Button android:id="@+id/update"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/update_note" />
</LinearLayout>
Following will be the content of res/layout/notification.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="fill_parent"
android:layout_height="400dp"
android:text="Hi, Your Detailed notification view goes here...." />
</LinearLayout>
Following will be the content of res/values/strings.xml to define two new constants:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">NotificationDemo</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="start_note">Start Notification</string>
<string name="cancel_note">Cancel Notification</string>
<string name="update_note">Update Notification</string>
</resources>
Following is the default content ofAndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.notificationdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.notificationdemo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activityandroid:name=".NotificationView"
android:label="Details of notification"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
</application>
</manifest>
Let's try to run your NotificationDemo application. I assume you had created your AVD while doing environment setup. To run the app from Eclipse, open one of your project's activity files and click Run icon from the toolbar. Eclipse installs the app on your AVD and starts it and if everything is fine with your setup and application, it will display following Emulator window:
Now click Start Notification button, you will see at the top a message "New Message Alert!" will display momentarily and after that you will have following screen having a small icon at the top left corner.
Now lets expand the view, long click on the small icon, after a second it will display date information and this is the time when you should drag status bar down without releasing mouse. You will see status bar will expand and you will get following screen:
Now let's try to click on the image icon, this will launch your new activity which you have set using intent and you will have following screen:
Next, you can click on "Detail of notification" and it will take you back to the main screen where you can try using Update Notification button which will update existing notification and number will increase by 1 but if you will send notification with new notification ID then it will keep adding in the stack and you see them separately listed on the screen.
Big View Notification
The following code snippet demonstrates how to alter the notification created in the previous snippet to use the Inbox big view style. I'm going to updatedisplayNotification() modification method to show this functionality:
protected void displayNotification() {
Log.i("Start", "notification");
/* Invoking the default notification service */
NotificationCompat.Builder mBuilder=
newNotificationCompat.Builder(this);
mBuilder.setContentTitle("New Message");
mBuilder.setContentText("You've received new message.");
mBuilder.setTicker("New Message Alert!");
mBuilder.setSmallIcon(R.drawable.woman);
/* Increase notification number every time a new notification arrives */
mBuilder.setNumber(++numMessages);
/* Add Big View Specific Configuration */
NotificationCompat.InboxStyleinboxStyle =
newNotificationCompat.InboxStyle();
String[] events = new String[6];
events[0] = new String("This is first line....");
events[1] = new String("This is second line...");
events[2] = new String("This is third line...");
events[3] = new String("This is 4th line...");
events[4] = new String("This is 5th line...");
events[5] = new String("This is 6th line...");
// Sets a title for the Inbox style big view
inboxStyle.setBigContentTitle("Big Title Details:");
// Moves events into the big view
for (int i=0; i < events.length; i++) {
inboxStyle.addLine(events[i]);
}
mBuilder.setStyle(inboxStyle);
/* Creates an explicit intent for an Activity in your app */
Intent resultIntent = newIntent(this, NotificationView.class);
TaskStackBuilder stackBuilder =TaskStackBuilder.create(this);
stackBuilder.addParentStack(NotificationView.class);
/* Adds the Intent that starts the Activity to the top of the stack */
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
mNotificationManager =
(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
/* notificationID allows you to update the notification later on. */
mNotificationManager.notify(notificationID,mBuilder.build());
}
Now if you will try to run your application then you will find following result in expanded form of the
Android Location Based Services
Android location APIs make it easy for you to build location-aware applications, without needing to focus on the details of the underlying location technology. This becomes possible with the help of Google Play services, which facilitates adding location awareness to your app with automated location tracking,geofencing, and activity recognition.
This tutorial shows you how to use Location Services in your app to get the current location, get periodic location updates, look up addresses etc.
The Location Object
The Location object represents a geographic location which can consist of a latitude, longitude, timestamp, and other information such as bearing, altitude and velocity. There are following important methods which you can use with Location object to get location specific information:
S.N.
Method & Description
1
float distanceTo(Location dest)
Returns the approximate distance in meters between this location and the given location.
Returns the approximate distance in meters between this location and the given location.
2
float getAccuracy()
Get the estimated accuracy of this location, in meters.
Get the estimated accuracy of this location, in meters.
3
double getAltitude()
Get the altitude if available, in meters above sea level.
Get the altitude if available, in meters above sea level.
4
float getBearing()
Get the bearing, in degrees.
Get the bearing, in degrees.
5
double getLatitude()
Get the latitude, in degrees.
Get the latitude, in degrees.
6
double getLongitude()
Get the longitude, in degrees.
Get the longitude, in degrees.
7
float getSpeed()
Get the speed if it is available, in meters/second over ground.
Get the speed if it is available, in meters/second over ground.
8
boolean hasAccuracy()
True if this location has an accuracy.
True if this location has an accuracy.
9
boolean hasAltitude()
True if this location has an altitude.
True if this location has an altitude.
10
boolean hasBearing()
True if this location has a bearing.
True if this location has a bearing.
11
boolean hasSpeed()
True if this location has a speed.
True if this location has a speed.
12
void reset()
Clears the contents of the location.
Clears the contents of the location.
13
void setAccuracy(float accuracy)
Set the estimated accuracy of this location, meters.
Set the estimated accuracy of this location, meters.
14
void setAltitude(double altitude)
Set the altitude, in meters above sea level.
Set the altitude, in meters above sea level.
15
void setBearing(float bearing)
Set the bearing, in degrees.
Set the bearing, in degrees.
16
void setLatitude(double latitude)
Set the latitude, in degrees.
Set the latitude, in degrees.
17
void setLongitude(double longitude)
Set the longitude, in degrees.
Set the longitude, in degrees.
18
void setSpeed(float speed)
Set the speed, in meters/second over ground.
Set the speed, in meters/second over ground.
19
String toString()
Returns a string containing a concise, human-readable description of this object.
Returns a string containing a concise, human-readable description of this object.
Get the Current Location
To get the current location, create a location client which is LocationClient object, connect it to Location Services using connect() method, and then call itsgetLastLocation() method. This method returns the most recent location in the form of Location object that contains latitude and longitude coordinates and other information as explained above. To have location based functionality in your activity, you will have to implement two interfaces:
GooglePlayServicesClient.ConnectionCallbacks
GooglePlayServicesClient.OnConnectionFailedListener
These interfaces provide following important callback methods, which you need to implement in your activity class:
S.N.
Callback Methods & Description
1
abstract void onConnected(BundleconnectionHint)
This callback method is called when location service is connected to the location client successfully. You will use connect() method to connect to the location client.
This callback method is called when location service is connected to the location client successfully. You will use connect() method to connect to the location client.
2
abstract void onDisconnected()
This callback method is called when the client is disconnected. You will use disconnect() method to disconnect from the location client.
This callback method is called when the client is disconnected. You will use disconnect() method to disconnect from the location client.
3
abstract voidonConnectionFailed(ConnectionResult result)
This callback method is called when there was an error connecting the client to the service.
This callback method is called when there was an error connecting the client to the service.
You should create the location client in onCreate()method of your activity class, then connect it inonStart(), so that Location Services maintains the current location while your activity is fully visible. You should disconnect the client in onStop() method, so that when your app is not visible, Location Services is not maintaining the current location. This helps in saving battery power up-to a large extent.
Get the Updated Location
If you are willing to have location updates, then apart from above mentioned interfaces, you will need to implement LocationListener interface as well. This interface provide following callback method, which you need to implement in your activity class:
S.N.
Callback Method & Description
1
abstract void onLocationChanged(Location location)
This callback method is used for receiving notifications from the LocationClient when the location has changed.
This callback method is used for receiving notifications from the LocationClient when the location has changed.
Location Quality of Service
The LocationRequest object is used to request a quality of service (QoS) for location updates from theLocationClient. There are following useful setter methods which you can use to handle QoS. There are equivalent getter methods available which you can check in Android official documentation.
S.N.
Method & Description
1
setExpirationDuration(long millis)
Set the duration of this request, in milliseconds.
Set the duration of this request, in milliseconds.
2
setExpirationTime(long millis)
Set the request expiration time, in millisecond since boot.
Set the request expiration time, in millisecond since boot.
3
setFastestInterval(long millis)
Explicitly set the fastest interval for location updates, in milliseconds.
Explicitly set the fastest interval for location updates, in milliseconds.
4
setInterval(long millis)
Set the desired interval for active location updates, in milliseconds.
Set the desired interval for active location updates, in milliseconds.
5
setNumUpdates(int numUpdates)
Set the number of location updates.
Set the number of location updates.
6
setPriority(int priority)
Set the priority of the request.
Set the priority of the request.
Now for example, if your application wants high accuracy location it should create a location request with setPriority(int) set to PRIORITY_HIGH_ACCURACY and setInterval(long) to 5 seconds. You can also use bigger interval and/or other priorities like PRIORITY_LOW_POWER for to request "city" level accuracy or PRIORITY_BALANCED_POWER_ACCURACY for "block" level accuracy.
Activities should strongly consider removing all location request when entering the background (for example at onPause()), or at least swap the request to a larger interval and lower quality to save power consumption.
Displaying a Location Address
Once you have Location object, you can useGeocoder.getFromLocation() method to get an address for a given latitude and longitude. This method is synchronous, and may take a long time to do its work, so you should call the method from thedoInBackground() method of an AsyncTask class.
The AsyncTask must be subclassed to be used and the subclass will override doInBackground(Params...)method to perform a task in the background andonPostExecute(Result) method is invoked on the UI thread after the background computation finishes and at the time to display the result. There is one more important method available in AyncTask which isexecute(Params... params), this method executes the task with the specified parameters.
Check following example to have better understanding on how we use AynchTask in any Android application to get work done in the background without interfering main task.
Example
Following example shows you in practical how to touse Location Services in your app to get the current location and its equivalent addresses etc.
To experiment with this example, you will need actual Mobile device equipped with latest Android OS, otherwise you will have to struggle with emulator which may not work.
Install the Google Play Services SDK
Before you proceed to have location support in your Android Applications, you neet to setup Google Play Services SDK using following simple steps:
Steps
Description
1
Launch the SDK Manager.
From Eclipse (with ADT), select Window > Android SDK Manager.
On Windows, double-click the SDK Manager.exe file at the root of the Android SDK directory.
On Mac or Linux, open a terminal and navigate to the tools/ directory in the Android SDK directory, then execute android sdk.
2
Search for Google Play services option from the given package list under Extra and if its not installed, then install it. The Google Play services SDK is saved in your Android SDK environment at <android-sdk>/extras/google/google_play_services/.
3
Copy the library project at <android-sdk>/extras/google/google_play_services/libproject/google-play-services_lib/ to the location where you maintain your Android app projects. If you are using Eclipse, import the library project into your workspace. Click File > Import, selectAndroid > Existing Android Code into Workspace, and browse to <android-sdk>/extras/google/google_play_services/libproject/, library project to import it.
Create Android Application
Step
Description
1
You will use Eclipse IDE to create an Android application and name it as LBSDemo/i> under a package com.example.lbsdemo. While creating this project, make sure you Target SDK and Compile With at the latest version of Android SDK to use higher levels of APIs.
2
Add Google Play Service library in your project by following simple steps given below.
3
Modify src/MainActivity.java file and add required code as shown below to take care of getting current location and its equivalent address.
4
Modify layout XML file res/layout/activity_main.xml to add all GUI components which include three buttons and two text views to show location/address.
5
Modify res/values/strings.xml to define required constant values
6
Modify AndroidManifest.xml as shown below
7
Run the application to launch Android emulator and verify the result of the changes done in theaplication.
Let's add Google Play Service reference in the project. Right click on the project and select Build Path > Configure Build Path > Android > and then click Add button which will show google-play-service_lib option to be added, just double click on it, which will add required library reference and you will have window as follows:
Following is the content of the modified main activity file src/com.example.lbsdemo/MainActivity.java.
package com.example.lbsdemo;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
importcom.google.android.gms.common.ConnectionResult;
importcom.google.android.gms.common.GooglePlayServicesClient;
importcom.google.android.gms.location.LocationClient;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
importandroid.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extendsFragmentActivity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener
{
LocationClient mLocationClient;
private TextView addressLabel;
private TextView locationLabel;
private Button getLocationBtn;
private Button disconnectBtn;
private Button connectBtn;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationLabel = (TextView)findViewById(R.id.locationLabel);
addressLabel = (TextView)findViewById(R.id.addressLabel);
getLocationBtn = (Button)findViewById(R.id.getLocation);
getLocationBtn.setOnClickListener(newView.OnClickListener() {
public void onClick(View view) {
displayCurrentLocation();
}
});
disconnectBtn = (Button)findViewById(R.id.disconnect);
disconnectBtn.setOnClickListener(newView.OnClickListener() {
public void onClick(View view) {
mLocationClient.disconnect();
locationLabel.setText("Got disconnected....");
}
});
connectBtn = (Button)findViewById(R.id.connect);
connectBtn.setOnClickListener(newView.OnClickListener() {
public void onClick(View view) {
mLocationClient.connect();
locationLabel.setText("Got connected....");
}
});
// Create the LocationRequest object
mLocationClient = newLocationClient(this, this, this);
}
@Override
protected void onStart() {
super.onStart();
// Connect the client.
mLocationClient.connect();
locationLabel.setText("Got connected....");
}
@Override
protected void onStop() {
// Disconnect the client.
mLocationClient.disconnect();
super.onStop();
locationLabel.setText("Got disconnected....");
}
@Override
public void onConnected(BundledataBundle) {
// Display the connection status
Toast.makeText(this, "Connected",Toast.LENGTH_SHORT).show();
}
@Override
public void onDisconnected() {
// Display the connection status
Toast.makeText(this, "Disconnected. Please re-connect.",
Toast.LENGTH_SHORT).show();
}
@Override
public voidonConnectionFailed(ConnectionResultconnectionResult) {
// Display the error code on failure
Toast.makeText(this, "Connection Failure : " +
connectionResult.getErrorCode(),
Toast.LENGTH_SHORT).show();
}
public void displayCurrentLocation() {
// Get the current location's latitude & longitude
Location currentLocation =mLocationClient.getLastLocation();
String msg = "Current Location: " +
Double.toString(currentLocation.getLatitude()) + "," +
Double.toString(currentLocation.getLongitude());
// Display the current location in the UI
locationLabel.setText(msg);
// To display the current address in the UI
(newGetAddressTask(this)).execute(currentLocation);
}
/*
* Following is a subclass of AsyncTaskwhich has been used to get
* address corresponding to the given latitude & longitude.
*/
private class GetAddressTask extendsAsyncTask<Location, Void, String>{
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
/*
* When the task finishes,onPostExecute() displays the address.
*/
@Override
protected void onPostExecute(String address) {
// Display the current address in the UI
addressLabel.setText(address);
}
@Override
protected StringdoInBackground(Location... params) {
Geocoder geocoder =
new Geocoder(mContext,Locale.getDefault());
// Get the current location from the input parameter list
Location loc = params[0];
// Create a list to contain the result address
List<Address> addresses = null;
try {
addresses =geocoder.getFromLocation(loc.getLatitude(),
loc.getLongitude(), 1);
} catch (IOException e1) {
Log.e("LocationSampleActivity",
"IO Exception ingetFromLocation()");
e1.printStackTrace();
return ("IO Exception trying to get address");
} catch (IllegalArgumentExceptione2) {
// Error message to post in the log
String errorString = "Illegalarguments " +
Double.toString(loc.getLatitude()) +
" , " +
Double.toString(loc.getLongitude()) +
" passed to address service";
Log.e("LocationSampleActivity",errorString);
e2.printStackTrace();
return errorString;
}
// If the reverse geocode returned an address
if (addresses != null &&addresses.size() > 0) {
// Get the first address
Address address =addresses.get(0);
/*
* Format the first line of address (if available),
* city, and country name.
*/
String addressText =String.format(
"%s, %s, %s",
// If there's a street address, add it
address.getMaxAddressLineIndex() > 0 ?
address.getAddressLine(0) : "",
// Locality is usually a city
address.getLocality(),
// The country of the address
address.getCountryName());
// Return the text
return addressText;
} else {
return "No address found";
}
}
}// AsyncTask class
}
Following will be the content of res/layout/activity_main.xml file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button android:id="@+id/getLocation"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/get_location"/>
<Button android:id="@+id/disconnect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/disconnect"/>
<Button android:id="@+id/connect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/connect"/>
<TextView
android:id="@+id/locationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/addressLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Following will be the content of res/values/strings.xml to define two new constants:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">LBSDemo</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="get_location">Get Location</string>
<string name="disconnect">Disconnect Service</string>
<string name="connect">Connect Service</string>
</resources>
Following is the default content ofAndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lbsdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.lbsdemo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Let's try to run your LBSDemo application. I assume you have connected your actual Android Mobile device with your computer. To run the app from Eclipse, open one of your project's activity files and click Run icon from the toolbar. Before starting your application, Eclipse will display following window to select an option where you want to run your Android application.
Select mobile device as an option and then check your mobile device which will display following screen:
Now to see location select Get Location Button which will display location information as follows:
You can try by disconnecting location client usingDisconnect Service and then connecting it by singConnect Service button. You can also modify to get location update as explained above and in Android Official documentation.
Android Sending Email
You have learnt Android Intent, which is an object carrying an intent ie. Message from one component to another component with-in the application or outside the application.
As such you do not need to develop your email client from scratch because they are already available like Gmail and K9mail. But you will need to send email from your Android application, where you will have to write an Activity that needs to launch an email client and sends an email using your Android device. For this purpose, your Activity will send an ACTION_SEND along with appropriate data load, to the Android Intent Resolver. The specified chooser gives the proper interface for the user to pick how to send your email data.
Following section explains different parts of our Intent object required to send an email.
Intent Object - Action to send Email
You will use ACTION_SEND action to launch an email client installed on your Android device. Following is simple syntax to create an intent with ACTION_SEND action
Intent emailIntent = newIntent(Intent.ACTION_SEND);
Intent Object - Data/Type to send Email
To send an email you need to specify mailto: as URI using setData() method and data type will be to text/plain using setType() method as follows:
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.setType("text/plain");
Intent Object - Extra to send Email
Android has built-in support to add TO, SUBJECT, CC, TEXT etc. fields which can be attached to the intent before sending the intent to a target email client. You can use following extra fields in your email:
S.N.
Extra Data & Description
1
EXTRA_BCC
A String[] holding e-mail addresses that should be blind carbon copied.
A String[] holding e-mail addresses that should be blind carbon copied.
2
EXTRA_CC
A String[] holding e-mail addresses that should be carbon copied.
A String[] holding e-mail addresses that should be carbon copied.
3
EXTRA_EMAIL
A String[] holding e-mail addresses that should be delivered to.
A String[] holding e-mail addresses that should be delivered to.
4
EXTRA_HTML_TEXT
A constant String that is associated with the Intent, used with ACTION_SEND to supply an alternative to EXTRA_TEXT as HTML formatted text.
A constant String that is associated with the Intent, used with ACTION_SEND to supply an alternative to EXTRA_TEXT as HTML formatted text.
5
EXTRA_SUBJECT
A constant string holding the desired subject line of a message.
A constant string holding the desired subject line of a message.
6
EXTRA_TEXT
A constant CharSequence that is associated with the Intent, used with ACTION_SEND to supply the literal data to be sent.
A constant CharSequence that is associated with the Intent, used with ACTION_SEND to supply the literal data to be sent.
7
EXTRA_TITLE
A CharSequence dialog title to provide to the user when used with a ACTION_CHOOSER.
A CharSequence dialog title to provide to the user when used with a ACTION_CHOOSER.
Here is an example showing you how to assign extra data to your intent:
emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{"recipient@example.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "subject of email");
emailIntent.putExtra(Intent.EXTRA_TEXT , "body of email");
Example
Following example shows you in practical how to use Intent object to launch Email client to send an Email to the given recipients.
To experiment with this example, you will need actual Mobile device equipped with latest Android OS, otherwise you will have to struggle with emulator which may not work. Second you will need to have an Email client like GMail or K9mail installed on your device.
Step
Description
1
You will use Eclipse IDE to create an Android application and name it as SendEmailDemounder a package com.example.sendemaildemo. While creating this project, make sure youTarget SDK and Compile With at the latest version of Android SDK to use higher levels of APIs.
2
Modify src/MainActivity.java file and add required code to take care of sending email.
3
Modify layout XML file res/layout/activity_main.xml add any GUI component if required. I'm adding a simple button to launch Email Client.
4
Modify res/values/strings.xml to define required constant values
5
Modify AndroidManifest.xml as shown below
6
Run the application to launch Android emulator and verify the result of the changes done in theaplication.
Following is the content of the modified main activity file src/com.example.sendemaildemo/MainActivity.java.
package com.example.sendemaildemo;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startBtn = (Button)findViewById(R.id.sendEmail);
startBtn.setOnClickListener(newView.OnClickListener() {
public void onClick(View view) {
sendEmail();
}
});
}
protected void sendEmail() {
Log.i("Send email", "");
String[] TO = {"amrood.admin@gmail.com"};
String[] CC = {"mcmohd@gmail.com"};
Intent emailIntent = newIntent(Intent.ACTION_SEND);
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL, TO);
emailIntent.putExtra(Intent.EXTRA_CC, CC);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Your subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message goes here");
try {
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
finish();
Log.i("Finished sending email...", "");
} catch (android.content.ActivityNotFoundExceptionex) {
Toast.makeText(MainActivity.this,
"There is no email client installed.", Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Following will be the content of res/layout/activity_main.xml file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button android:id="@+id/sendEmail"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/compose_email"/>
</LinearLayout>
Following will be the content of res/values/strings.xml to define two new constants:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SendEmailDemo</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="compose_email">Compose Email</string>
</resources>
Following is the default content ofAndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sendemaildemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.sendemaildemo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Let's try to run your SendEmailDemo application. I assume you have connected your actual Android Mobile device with your computer. To run the app from Eclipse, open one of your project's activity files and click Run icon from the toolbar. Before starting your application, Eclipse will display following window to select an option where you want to run your Android application.
Select your mobile device as an option and then check your mobile device which will display following screen:
Now use Compose Email button to list down all the installed email clients. From the list, you can choose one f email clients to send your email. I'm going to use Gmail client to send my email which will have all the provided defaults fields available as shown below. Here From: will be default email ID you have registered for your Android device.
You can modify either of the given default fields and finally use send email button (marked with red rectangle) to send your email to the mentioned recipients.
Comments
Post a Comment