Android
|
Modified: |
Resources
http://developer.android.com/guide/topics/fundamentals.html - Discussion of Android fundamentals.
http://www.vogella.de/articles/AndroidServices/article.html - Service and broadcast tutorial
Overview - from Android Fundamentals
Activities
An activity represents a single screen with a user interface. An activity is implemented as a subclass of Activity.For example, an email application might have one activity that shows a list of new emails, another activity to compose an email, and another activity for reading emails. Although the activities work together to form a cohesive user experience in the email application, each one is independent of the others. As such, a different application can start any one of these activities (if the email application allows it). For example, a camera application can start the activity in the email application that composes new mail, in order for the user to share a picture.
Broadcast receivers
A broadcast receiver is a component that responds to system-wide broadcast announcements.Many broadcasts originate from the system—for example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More commonly, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work. For instance, it might initiate a service to perform some work based on the event.
A broadcast receiver is implemented as a subclass of BroadcastReceiver and each broadcast is delivered as an Intent object.
A broadcast receiver is a class which extends BroadcastReceiver and which is registered as a receiver in an Android Application via the AndroidManifest.xml (or via code). The class can receive intents via the sendBroadcast() method.
BroadCastReceiver defines the method onReceive(). Only during this method is the broadcast receiver object valid, it does not have a user interface, afterwards the Android system will consider the receiver as no longer active. Therefore no asynchronous operations may be performed.
Services
A service is a component that runs in the background to perform long-running operations or to perform work for remote processes.A service does not provide a user interface. For example, a service might play music in the background while the user is in a different application, or it might fetch data over the network without blocking user interaction with an activity. Another component, such as an activity, can start the service and let it run or bind to it in order to interact with it.
A service is implemented as a subclass of Service.
Broadcast sender and receiver
The broadcast receiver is installed on a device but has no UI.
The broadcasting activity sends a broadcast that is received, extra data is displayed.
Note that to test, the receiver should be executed, then the sender, both on the same device.
Sender
The sender of the broadcast constructs an Intent with an action, "edu.ius.rwisman.custom.intent.action.TEST".
package edu.ius.rwisman.BroadcastSend;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class BroadcastSend extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = new Intent();
intent.setAction("edu.ius.rwisman.custom.intent.action.TEST");
intent.putExtra("url", "www.ius.edu");
sendBroadcast( intent );
}
}
|
| <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.ius.rwisman.BroadcastSend" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="13" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".BroadcastSend" 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> |
Receiver
The receiver of the broadcast registers to receive the action, "edu.ius.rwisman.custom.intent.action.TEST" in the AndroidManifest.xml file.
Note that a BroadcastReceiver is not an Activity so has no UI but is installed and executed whenever the action to which it is registered is broadcast.
Android simply installs the BroadcastReceiver without execution until broadcast the of "edu.ius.rwisman.custom.intent.action.TEST".
| <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.ius.rwisman.BroadcastReceive" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="13" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <receiver android:name=".BroadcastReceive" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="edu.ius.rwisman.custom.intent.action.TEST"/> </intent-filter> </receiver> </application> </manifest> |
Executing BroadcastSend broadcasts the "edu.ius.rwisman.custom.intent.action.TEST" action which is received by BroadcastReceive.
The only evidence is a short duration message displayed, see video above:
BroadcastReceive: www.ius.edu
package edu.ius.rwisman.BroadcastReceive;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class BroadcastReceive extends BroadcastReceiver {
@Override
public void onReceive( Context context, Intent intent ){
String url = intent.getExtras().getString("url");
Toast.makeText(context, "BroadcastReceive:"+url, Toast.LENGTH_SHORT).show();
}
} |

Service provider and consumer
PrimeService computes prime numbers, the current prime number computed is available to the consumer.
ServiceConsumer gets the current prime number from the service.
ServiceConsumer
The consumer is an Activity that defines a ServiceConnection for connecting to the PrimeService:
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
ps = ((PrimeService.MyBinder) binder).getService();
}and binds the service connection to PrimeService:
bindService(new Intent(this, PrimeService.class), mConnection, Context.BIND_AUTO_CREATE);
After binding to the service, the ServiceConsumer consumes the PrimeService by:
ps.getPrime()
each time the Current Prime button is clicked.
package edu.ius.rwisman.ServiceConsumer;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class ServiceConsumer extends Activity {
private PrimeService ps;
TextView primeText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
primeText = (TextView) findViewById(R.id.prime);
Intent intent = new Intent( this, PrimeService.class );
bindService( intent, mConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
ps = ((PrimeService.MyBinder) binder).getService();
Toast.makeText(ServiceConsumer.this, "Connected", Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
ps = null;
}
};
public void showPrimeServiceData(View view) { // Current Prime button click
if (ps != null) {
primeText.setText( ps.getPrime()+"");
}
}
}
|
PrimeService
The service computes primes using a brute-force method which is slow enough to provide visibly interesting results.
getPrime() returns the current prime number.
PrimeService extends Service requiring implementing methods:
public void onCreate()
public void onDestroy()
public IBinder onBind(Intent intent)
and a Binder class defining getService() method :
public class MyBinder extends Binder {
PrimeService getService() {
return PrimeService.this;
}
}
package edu.ius.rwisman.ServiceConsumer;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class PrimeService extends Service {
long n=3;
long currentPrime=n;
boolean running;
private final IBinder mBinder = new MyBinder();
public void onCreate() {
super.onCreate();
computePrime();
}
@Override
public void onDestroy() {
super.onDestroy();
running = false;
}
private boolean prime(long candidate) {
long trialDivisor = 2;
while(trialDivisor * trialDivisor <= candidate) {
if(candidate % trialDivisor == 0)
return false;
trialDivisor++;
}
return true;
}
private void computePrime() {
new Thread(new Runnable() {
public void run() {
running = true;
while(running) {
if(prime(n))
currentPrime=n;
n++;
}
}
}).start();
}
public long getPrime() { return currentPrime; }
@Override
public IBinder onBind(Intent intent) { return mBinder; }
// Called by: ((PrimeService.MyBinder) binder).getService()
public class MyBinder extends Binder {
PrimeService getService() {
return PrimeService.this;
}
}
}
|
AndroidManifest.xml distinction is to define the service PrimeService.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.ius.rwisman.ServiceConsumer" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="13" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ServiceConsumer" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".PrimeService"></service> </application> </manifest> |
<?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:text="Current Prime" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="showPrimeServiceData"></Button> <TextView android:text=" " android:id="@+id/prime" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> </LinearLayout> |
Permissions
Global access to a service can be enforced when it is declared in its manifest's <service> tag.By doing so, other applications will need to declare a corresponding <uses-permission> element in their own manifest to be able to start, stop, or bind to the service.