Thursday 12 December 2013

Android Architecture

Android Architecture Diagram:
Android Architecture


The above figure shows the diagram of Android Architecture. The Android OS can be referred to as a software stack of different layers, where each layer is a group of several  program components. Together it includes operating system, middle ware and important applications. Each layer in the architecture provides different services to the layer just above it. We will examine the features of each layer in detail.

Linux Kernel

The basic layer is the Linux kernel. The whole Android OS is built on top of the Linux 2.6 Kernel with some further architectural changes made by Google.  It is this Linux that interacts with the hardware and contains all the essential hardware drivers. Drivers are programs that control and communicate with the hardware. For example, consider the Bluetooth function. All devices has a Bluetooth hardware in it. Therefore the kernel must include a Bluetooth driver to communicate with the Bluetooth hardware.  The Linux kernel also  acts as an abstraction layer between the hardware and other software layers. Android uses the Linux for all its core functionality such as Memory management, process management, networking, security settings etc. As the Android is built on a most popular and proven foundation, it made the porting of Android to variety of hardware, a relatively painless task.

Libraries

The next layer is the Android’s native libraries. It is this layer that enables the device to handle different types of data. These libraries are written in c or c++ language and are specific for a particular hardware.
Some of the important native libraries include the following:
Surface Manager: It is used for compositing window manager with off-screen buffering. Off-screen buffering means you cant directly draw into the screen, but your drawings go to the off-screen buffer. There it is combined with other drawings and form the final screen the user will see. This off screen buffer is the reason behind the transparency of windows.
Media framework: Media framework provides different media codecs allowing the recording and playback of different media formats
SQLite: SQLite is the database engine used in android for data storage purposes
WebKit: It is the browser engine used to display HTML content
OpenGL: Used to render 2D or 3D graphics content to the screen

Android Runtime

Android Runtime consists of Dalvik Virtual machine and Core Java libraries.
Dalvik Virtual Machine
It is a type of JVM used in android devices to run apps and is optimized for low processing power and low memory environments. Unlike the JVM, the Dalvik Virtual Machine doesn’t run .class files, instead it runs .dex files. .dex files are built from .class file at the time of compilation and provides hifger efficiency in low resource environments. The Dalvik VM allows multiple instance of Virtual machine to be created simultaneously providing security, isolation, memory management and threading support. It is developed by Dan Bornstein of Google.
Core Java Libraries
These are different from Java SE and Java ME libraries. However these libraries provides most of the functionalities defined in the Java SE libraries.

Application Framework

These are the blocks that our applications directly interacts with. These programs manage the basic functions of phone like resource management, voice call management etc. As a developer, you just consider these are some basic tools with which we are building our applications.
Important blocks of Application framework are:
Activity Manager: Manages the activity life cycle of applications
Content Providers: Manage the data sharing between applications
Telephony Manager: Manages all voice calls. We use telephony manager if we want to access voice calls in our application.
Location Manager: Location management, using GPS or cell tower
Resource Manager: Manage the various types of resources we use in our Application

Applications

Applications are the top layer in the Android architecture and this is where our applications are gonna fit. Several standard applications comes pre-installed with every device, such as:
  • SMS client app
  • Dialer
  • Web browser
  • Contact manager
As a developer we are able to write an app which replace any existing system app. That is, you are not limited in accessing any particular feature. You are practically limitless and can whatever you want to do with the android (as long as the users of your app permits it). Thus Android is opening endless opportunities to the developer.



List of Android Permissions in Manifest.Xml

Here we will learn details about list of all Android Permissions.

 Android applications use different android permissions for different modules while developing android applications.

 We need to take care of the below points while add any android permission in the Manifest file:


  • All permissions must be add in the project Manifest.xml file
     
  • All permissions must be add above the entry of any activity, service or receiver or action in the Manifest file.
        
  • All permissions must be included in the use tag, example:  <uses-permission android:name=”android.permission.READ_CONTACTS”></uses-permission>
Android Permissions List:

CALL_PHONE= "android.permission.CALL_PHONE";

MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE";

CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";

READ_PHONE_STATE ="android.permission.READ_PHONE_STATE";

READ_CALL_LOG = "android.permission.READ_CALL_LOG";

READ_CONTACTS= "android.permission.READ_CONTACTS";

WRITE_CONTACTS= "android.permission.WRITE_CONTACTS";

LOCATION = "android.permission-group.LOCATION";

NETWORK= "android.permission-group.NETWORK";

REBOOT = "android.permission.REBOOT";

RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";

INTERNET = "android.permission.INTERNET";

WRITE_SMS = "android.permission.WRITE_SMS";

BROADCAST_SMS = "android.permission.BROADCAST_SMS";

MESSAGES = "android.permission-group.MESSAGES";

PHONE_CALLS = "android.permission-group.PHONE_CALLS";

STORAGE = "android.permission-group.STORAGE";

DEVICE_POWER = "android.permission.DEVICE_POWER";

MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";

MOUNT_UNMOUNT_FILESYSTEMS="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"

ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";

ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";

ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";

ACCESS_LOCATION_EXTRA_COMMANDS="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS";

ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";

ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";

ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";

ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";

ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";

ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";

AUTHENTICATE_ACCOUNTS = "android.permission.AUTHENTICATE_ACCOUNTS";

BATTERY_STATS = "android.permission.BATTERY_STATS";

BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";

BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";

BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";

BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";

BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";

BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";

BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";

BIND_WALLPAPER = "android.permission.BIND_WALLPAPER";

BLUETOOTH = "android.permission.BLUETOOTH";

BLUETOOTH_ADMIN = "android.permission.BLUETOOTH_ADMIN";

BRICK = "android.permission.BRICK";

BROADCAST_PACKAGE_REMOVED = "android.permission.BROADCAST_PACKAGE_REMOVED";

BROADCAST_STICKY = "android.permission.BROADCAST_STICKY";

BROADCAST_WAP_PUSH = "android.permission.BROADCAST_WAP_PUSH";

CAMERA = "android.permission.CAMERA";

CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";

CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";

CHANGE_NETWORK_STATE = "android.permission.CHANGE_NETWORK_STATE";

CHANGE_WIFI_MULTICAST_STATE = "android.permission.CHANGE_WIFI_MULTICAST_STATE";

CHANGE_WIFI_STATE = "android.permission.CHANGE_WIFI_STATE";

CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";

CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";

CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";

DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";

DELETE_PACKAGES = "android.permission.DELETE_PACKAGES";

DIAGNOSTIC = "android.permission.DIAGNOSTIC";

DISABLE_KEYGUARD = "android.permission.DISABLE_KEYGUARD";

DUMP = "android.permission.DUMP";

EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";

FACTORY_TEST = "android.permission.FACTORY_TEST";

FLASHLIGHT = "android.permission.FLASHLIGHT";

FORCE_BACK = "android.permission.FORCE_BACK";

GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";

GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";

GET_TASKS = "android.permission.GET_TASKS";

GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";

HARDWARE_TEST = "android.permission.HARDWARE_TEST";

INJECT_EVENTS = "android.permission.INJECT_EVENTS";

INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";

INSTALL_PACKAGES = "android.permission.INSTALL_PACKAGES";

INTERNAL_SYSTEM_WINDOW = "android.permission.INTERNAL_SYSTEM_WINDOW";

KILL_BACKGROUND_PROCESSES = "android.permission.KILL_BACKGROUND_PROCESSES";

MANAGE_ACCOUNTS = "android.permission.MANAGE_ACCOUNTS";

MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";

MASTER_CLEAR = "android.permission.MASTER_CLEAR";

MODIFY_AUDIO_SETTINGS = "android.permission.MODIFY_AUDIO_SETTINGS";

NFC = "android.permission.NFC";

PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";

PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";

READ_CALENDAR = "android.permission.READ_CALENDAR";

READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";

READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";

READ_HISTORY_BOOKMARKS = "com.android.browser.permission.READ_HISTORY_BOOKMARKS";

READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";

READ_LOGS = "android.permission.READ_LOGS";

READ_PROFILE = "android.permission.READ_PROFILE";

READ_SMS = "android.permission.READ_SMS";

READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM";

READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";

READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";

READ_USER_DICTIONARY = "android.permission.READ_USER_DICTIONARY";

RECEIVE_MMS = "android.permission.RECEIVE_MMS";

RECEIVE_SMS = "android.permission.RECEIVE_SMS";

RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";

RECORD_AUDIO = "android.permission.RECORD_AUDIO";

REORDER_TASKS = "android.permission.REORDER_TASKS";

RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";

SEND_SMS = "android.permission.SEND_SMS";

SET_ACTIVITY_WATCHER = "android.permission.SET_ACTIVITY_WATCHER";

SET_ALARM = "com.android.alarm.permission.SET_ALARM";

SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH";

SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE";

SET_DEBUG_APP = "android.permission.SET_DEBUG_APP";

SET_ORIENTATION = "android.permission.SET_ORIENTATION";

SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED";

SET_PREFERRED_APPLICATIONS = "android.permission.SET_PREFERRED_APPLICATIONS";

SET_PROCESS_LIMIT = "android.permission.SET_PROCESS_LIMIT";

SET_TIME = "android.permission.SET_TIME";

SET_TIME_ZONE = "android.permission.SET_TIME_ZONE";

SET_WALLPAPER = "android.permission.SET_WALLPAPER";

SET_WALLPAPER_HINTS = "android.permission.SET_WALLPAPER_HINTS";

SIGNAL_PERSISTENT_PROCESSES = "android.permission.SIGNAL_PERSISTENT_PROCESSES";

STATUS_BAR = "android.permission.STATUS_BAR";

SUBSCRIBED_FEEDS_READ = "android.permission.SUBSCRIBED_FEEDS_READ";

SUBSCRIBED_FEEDS_WRITE = "android.permission.SUBSCRIBED_FEEDS_WRITE";

SYSTEM_ALERT_WINDOW = "android.permission.SYSTEM_ALERT_WINDOW";

UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";

USE_CREDENTIALS = "android.permission.USE_CREDENTIALS";

USE_SIP = "android.permission.USE_SIP";

VIBRATE = "android.permission.VIBRATE";

WAKE_LOCK = "android.permission.WAKE_LOCK";

WRITE_APN_SETTINGS = "android.permission.WRITE_APN_SETTINGS";

WRITE_CALENDAR = "android.permission.WRITE_CALENDAR";

WRITE_CALL_LOG = "android.permission.WRITE_CALL_LOG";

WRITE_PROFILE = "android.permission.WRITE_PROFILE";

WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";

WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";

WRITE_HISTORY_BOOKMARKS =
"com.android.browser.permission.WRITE_HISTORY_BOOKMARKS";

WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";

WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";

COST_MONEY = "android.permission-group.COST_MONEY";

WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";

WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";

WRITE_USER_DICTIONARY = "android.permission.WRITE_USER_DICTIONARY";

ACCOUNTS = "android.permission-group.ACCOUNTS";

DEVELOPMENT_TOOLS = "android.permission-group.DEVELOPMENT_TOOLS";

HARDWARE_CONTROLS = "android.permission-group.HARDWARE_CONTROLS";

PERSONAL_INFO = "android.permission-group.PERSONAL_INFO";

SYSTEM_TOOLS = "android.permission-group.SYSTEM_TOOLS";


Detailed Description for All Android Permissions List:                                 

CALL_PHONE:
 Allows an application to initiate a phone call without going through the Dialer user interface for the user to confirm the call being placed.
MODIFY_PHONE_STATE :
 Allows modification of the telephony state – power on, mmi, etc.
READ_PHONE_STATE:
Allows read only access to phone state.
READ_LOGS:
Allows an application to read the low-level system log files.
WRITE_SMS:
Allows an application to write SMS messages.
CHANGE_NETWORK_STATE
Allows applications to change network connectivity state
PROCESS_OUTGOING_CALLS:
 Allows an application to monitor, modify, or abort outgoing calls.
READ_CALL_LOG:
 Allows an application to read the user’s call log.
READ_CONTACTS: 
Allows an application to read the user’s contacts data.
READ_CALENDAR:
Allows an application to read the user’s calendar data.
RECEIVE_BOOT_COMPLETED:
Allows an application to receive the ACTION_BOOT_COMPLETED that is broadcast after the system finishes booting.
ACCESS_CHECKIN_PROPERTIES:
Allows read/write access to the “properties” table in the checkin database, to change values that get uploaded.
ACCESS_FINE_LOCATION:
Allows an app to access precise location from location sources such as GPS, cell towers, and Wi-Fi.
ACCESS_COARSE_LOCATION:
Allows an app to access approximate location derived from network location sources such as cell towers and Wi-Fi.
ACCESS_MOCK_LOCATION:
Allows an application to create mock location providers for testing
ACCESS_NETWORK_STATE:
Allows applications to access information about networks
ACCESS_SURFACE_FLINGER:
Allows an application to use SurfaceFlinger’s low level features
ACCESS_WIFI_STATE:
Allows applications to access information about Wi-Fi networks
ACCOUNT_MANAGER:
Allows applications to call into AccountAuthenticators.
ADD_VOICEMAIL:
Allows an application to add voicemails into the system.
AUTHENTICATE_ACCOUNTS:
Allows an application to act as an AccountAuthenticator for the AccountManager
BATTERY_STATS:
Allows an application to collect battery statistics
BIND_ACCESSIBILITY_SERVICE:
Must be required by an AccessibilityService, to ensure that only the system can bind to it.
BIND_APPWIDGET:
Allows an application to tell the AppWidget service which application can access AppWidget’s data.
BIND_DEVICE_ADMIN:
Must be required by device administration receiver, to ensure that only the system can interact with it.
BIND_INPUT_METHOD:
Must be required by an InputMethodService, to ensure that only the system can bind to it.
BIND_REMOTEVIEWS:
Must be required by a RemoteViewsService, to ensure that only the system can bind to it.
BIND_TEXT_SERVICE:
Must be required by a TextService (e.g.
BIND_VPN_SERVICE:
Must be required by an VpnService, to ensure that only the system can bind to it.
BIND_WALLPAPER:
Must be required by a WallpaperService, to ensure that only the system can bind to it.
BLUETOOTH:
Allows applications to connect to paired bluetooth devices
BLUETOOTH_ADMIN:
Allows applications to discover and pair bluetooth devices
BRICK:
Required to be able to disable the device (very dangerous!).
BROADCAST_PACKAGE_REMOVED:
Allows an application to broadcast a notification that an application package has been removed.
BROADCAST_SMS:
Allows an application to broadcast an SMS receipt notification
BROADCAST_STICKY:
Allows an application to broadcast sticky intents.
BROADCAST_WAP_PUSH:
Allows an application to broadcast a WAP PUSH receipt notification
CALL_PRIVILEGED:
Allows an application to call any phone number, including emergency numbers, without going through the Dialer user interface for the user to confirm the call being placed.
CAMERA:
Required to be able to access the camera device.
CHANGE_COMPONENT_ENABLED_STATE:
Allows an application to change whether an application component (other than its own) is enabled or not.
CHANGE_CONFIGURATION:
Allows an application to modify the current configuration, such as locale.
CHANGE_WIFI_MULTICAST_STATE:
Allows applications to enter Wi-Fi Multicast mode
CHANGE_WIFI_STATE:
Allows applications to change Wi-Fi connectivity state
CLEAR_APP_CACHE:
Allows an application to clear the caches of all installed applications on the device.
CLEAR_APP_USER_DATA:
Allows an application to clear user data
CONTROL_LOCATION_UPDATES:
Allows enabling/disabling location update notifications from the radio.
DELETE_CACHE_FILES:
Allows an application to delete cache files.
DELETE_PACKAGES:
Allows an application to delete packages.
DEVICE_POWER:
Allows low-level access to power management
DIAGNOSTIC:
Allows applications to RW to diagnostic resources.
DISABLE_KEYGUARD:
Allows applications to disable the keyguard

Monday 2 December 2013

Simple Notification in android

Notification:

                          Notifications are a way of alerting a user about an event that he needs to be informed about or even take some action on getting that information. 


Notification on Android can be done in any of the following ways:
  • Status Bar Notification
  • Vibrate
  • Flash lights
  • Play a sound
Through the Notification, we can allow the user to launch a new activity as well.

To create a status bar notification, we'll need to use two classes: Notification and NotificationManager.
  • Notification
    Defines the properties of the status bar notification like the icon to display, the test to display when the notification first appears on the status bar and the time to display.
  • NotificationManager
    NotificationManager is an android system service that executes and manages all notifications. Hence we cannot create an instance of the NotificationManager but we can retrieve a reference to it by calling the getSystemService() method.
Once we got this handle, we invoke the notify() method on it by passing the notification object created.

So far, we have all the information to display on the status bar. However, when the user clicks the notification icon on the status bar, what detailed information should we show the user?
This is yet to be created. This is done by calling the method setLatestEventInfo() on the notification object.

 Get a handle to the NotificationManager:
        
private NotificationManager mNotificationManager;
 mNotificationManager = 
  (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
 
Create  notification object along with properties to display on the status bar: 
 
 final Notification notifyDetails = new Notification(R.drawable.android,
  "You have got a new notification!",System.currentTimeMillis()); 

Add the details that need to get displayed when the user clicks on the notification. In this case, I have created an intent to invoke the browser to show the website http://saravananandroid.blogspot.in

Context context = getApplicationContext();
 CharSequence contentTitle = "Notification Details...";
 CharSequence contentText = "Browse Android blog by clicking me";
 Intent notifyIntent = 
new Intent(android.content.Intent.ACTION_VIEW,Uri.parse
("http://saravananandroid.blogspot.in"));
 PendingIntent intent = 
         PendingIntent.getActivity(NotificationsA.this, 0, 
         notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
          
notifyDetails.setLatestEventInfo(context, contentTitle, contentText, intent);
mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails);
  

Now the stage is set. Notify.  

mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails);
 
      Note that all of the above actions(except getting a handle to the 
NotificationManager) are done on the click of a button Start Notification
So all the details go into the setOnClickListener() method of the button.
Similarly, the notification, for the example sake is stopped by clicking 
a cancel notification button. And the code there is :
 

mNotificationManager.cancel(SIMPLE_NOTFICATION_ID);
 
Now, we may realize that the constant SIMPLE_NOTIFICATION_ID becomes 
the way of controlling, updating, stopping a current notification 
that is started with
 the same ID.  
 
 

Sample code:

 Notification.java:

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Notifications extends Activity {
   
    private NotificationManager mNotificationManager;
    private int SIMPLE_NOTFICATION_ID;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        mNotificationManager =
                (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        final Notification notifyDetails =
                new Notification(R.drawable.android,
                 "You have got a new notification!",System.currentTimeMillis());
      
        Button start = (Button)findViewById(R.id.notifyButton);
        Button cancel = (Button)findViewById(R.id.cancelButton);
       
        start.setOnClickListener(new OnClickListener() {
          
        public void onClick(View v) {
                
                Context context = getApplicationContext();
                CharSequence contentTitle =
                        "Notification Details...";
                CharSequence contentText =
                        "Browse Android blog by clicking me";
                Intent notifyIntent =
                        new Intent(android.content.Intent.ACTION_VIEW,
                             Uri.parse("http://saravananandroid.blogspot.in/"));
                PendingIntent intent =
                    PendingIntent.getActivity(Notifications.this, 0,
                    notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
              
                notifyDetails.setLatestEventInfo(context,
                                               contentTitle, contentText, intent);
                mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails);
            }
        });
       
        cancel.setOnClickListener(new OnClickListener() {      
            public void onClick(View v) {           
                mNotificationManager.cancel(SIMPLE_NOTFICATION_ID);
            }
        });
    }
}
Main.xml

<?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">
    <Button
        android:id="@+id/notifyButton"
        android:text="@string/notify"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal">
    </Button>
    <Button
        android:id="@+id/cancelButton"
        android:text="@string/cancel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal">
    </Button>
</LinearLayout>

Android Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.bogotobogo.notificationsa"
    android:versionCode="1"
    android:versionName="1.0">
    <uses-sdk android:minSdkVersion="14" />  
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Notifications"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>