Monthly Archives: April 2013

Synchronized Methods

The Java programming language provides two basic synchronization idioms: synchronized methods and synchronized statements. The more complex of the two, synchronized statements, are described in the next section. This section is about synchronized methods.

To make a method synchronized, simply add the synchronized keyword to its declaration:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }    public synchronized int value() {
        return c;
    }
}

If count is an instance of SynchronizedCounter, then making these methods synchronized has two effects:

  • First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
  • Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.

Note that constructors cannot be synchronized — using the synchronized keyword with a constructor is a syntax error. Synchronizing constructors doesn’t make sense, because only the thread that creates an object should have access to it while it is being constructed.

Advertisements

Android Services

http://developer.android.com/guide/components/services.html#CreatingStartedService

Services

QUICKVIEW

      • A service can run in the background to perform work even while the user is in a different application
      • A service can allow other components to bind to it, in order to interact with it and perform interprocess communication
      • A service runs in the main thread of the application that hosts it, by default

IN THIS DOCUMENT

      1. The Basics
        1. Declaring a service in the manifest
      2. Creating a Started Service
        1. Extending the IntentService class
        2. Extending the Service class
        3. Starting a service
        4. Stopping a service
      3. Creating a Bound Service
      4. Sending Notifications to the User
      5. Running a Service in the Foreground
      6. Managing the Lifecycle of a Service
        1. Implementing the lifecycle callbacks

KEY CLASSES

      1. Service
      2. IntentService

SAMPLES

      1. ServiceStartArguments
      2. LocalService

SEE ALSO

    1. Bound Services

Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.

A service can essentially take two forms:

Started
A service is “started” when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely, even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.
Bound
A service is “bound” when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.

Although this documentation generally discusses these two types of services separately, your service can work both ways—it can be started (to run indefinitely) and also allow binding. It’s simply a matter of whether you implement a couple callback methods:onStartCommand() to allow components to start it and onBind() to allow binding.

Regardless of whether your application is started, bound, or both, any application component can use the service (even from a separate application), in the same way that any component can use an activity—by starting it with an Intent. However, you can declare the service as private, in the manifest file, and block access from other applications. This is discussed more in the section aboutDeclaring the service in the manifest.

Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application’s main thread can remain dedicated to user interaction with your activities.

The Basics


Should you use a service or a thread?

A service is simply a component that can run in the background even when the user is not interacting with your application. Thus, you should create a service only if that is what you need.

If you need to perform work outside your main thread, but only while the user is interacting with your application, then you should probably instead create a new thread and not a service. For example, if you want to play some music, but only while your activity is running, you might create a thread in onCreate(), start running it in onStart(), then stop it inonStop(). Also consider usingAsyncTask or HandlerThread, instead of the traditional Thread class. See theProcesses and Threading document for more information about threads.

Remember that if you do use a service, it still runs in your application’s main thread by default, so you should still create a new thread within the service if it performs intensive or blocking operations.

To create a service, you must create a subclass of Service (or one of its existing subclasses). In your implementation, you need to override some callback methods that handle key aspects of the service lifecycle and provide a mechanism for components to bind to the service, if appropriate. The most important callback methods you should override are:

onStartCommand()
The system calls this method when another component, such as an activity, requests that the service be started, by callingstartService(). Once this method executes, the service is started and can run in the background indefinitely. If you implement this, it is your responsibility to stop the service when its work is done, by calling stopSelf() orstopService(). (If you only want to provide binding, you don’t need to implement this method.)
onBind()
The system calls this method when another component wants to bind with the service (such as to perform RPC), by callingbindService(). In your implementation of this method, you must provide an interface that clients use to communicate with the service, by returning an IBinder. You must always implement this method, but if you don’t want to allow binding, then you should return null.
onCreate()
The system calls this method when the service is first created, to perform one-time setup procedures (before it calls eitheronStartCommand() or onBind()). If the service is already running, this method is not called.
onDestroy()
The system calls this method when the service is no longer used and is being destroyed. Your service should implement this to clean up any resources such as threads, registered listeners, receivers, etc. This is the last call the service receives.

If a component starts the service by calling startService() (which results in a call to onStartCommand()), then the service remains running until it stops itself with stopSelf() or another component stops it by callingstopService().

If a component calls bindService() to create the service (and onStartCommand() is not called), then the service runs only as long as the component is bound to it. Once the service is unbound from all clients, the system destroys it.

The Android system will force-stop a service only when memory is low and it must recover system resources for the activity that has user focus. If the service is bound to an activity that has user focus, then it’s less likely to be killed, and if the service is declared to run in the foreground (discussed later), then it will almost never be killed. Otherwise, if the service was started and is long-running, then the system will lower its position in the list of background tasks over time and the service will become highly susceptible to killing—if your service is started, then you must design it to gracefully handle restarts by the system. If the system kills your service, it restarts it as soon as resources become available again (though this also depends on the value you return fromonStartCommand(), as discussed later). For more information about when the system might destroy a service, see the Processes and Threading document.

In the following sections, you’ll see how you can create each type of service and how to use it from other application components.

Declaring a service in the manifest

Like activities (and other components), you must declare all services in your application’s manifest file.

To declare your service, add a <service> element as a child of the <application> element. For example:

<manifest ... >
  ...
  <application ... >
      <service android:name=".ExampleService" />
      ...
  </application>
</manifest>

There are other attributes you can include in the <service> element to define properties such as permissions required to start the service and the process in which the service should run. The android:name attribute is the only required attribute—it specifies the class name of the service. Once you publish your application, you should not change this name, because if you do, you might break some functionality where explicit intents are used to reference your service (read the blog post, Things That Cannot Change).

See the <service> element reference for more information about declaring your service in the manifest.

Just like an activity, a service can define intent filters that allow other components to invoke the service using implicit intents. By declaring intent filters, components from any application installed on the user’s device can potentially start your service if your service declares an intent filter that matches the intent another application passes to startService().

If you plan on using your service only locally (other applications do not use it), then you don’t need to (and should not) supply any intent filters. Without any intent filters, you must start the service using an intent that explicitly names the service class. More information about starting a service is discussed below.

Additionally, you can ensure that your service is private to your application only if you include theandroid:exported attribute and set it to "false". This is effective even if your service supplies intent filters.

For more information about creating intent filters for your service, see the Intents and Intent Filters document.

Creating a Started Service


Targeting Android 1.6 or lower

If you’re building an application for Android 1.6 or lower, you need to implement onStart(), instead ofonStartCommand() (in Android 2.0,onStart() was deprecated in favor ofonStartCommand()).

For more information about providing compatibility with versions of Android older than 2.0, see theonStartCommand() documentation.

A started service is one that another component starts by callingstartService(), resulting in a call to the service’sonStartCommand() method.

When a service is started, it has a lifecycle that’s independent of the component that started it and the service can run in the background indefinitely, even if the component that started it is destroyed. As such, the service should stop itself when its job is done by calling stopSelf(), or another component can stop it by calling stopService().

An application component such as an activity can start the service by calling startService() and passing an Intent that specifies the service and includes any data for the service to use. The service receives this Intent in the onStartCommand() method.

For instance, suppose an activity needs to save some data to an online database. The activity can start a companion service and deliver it the data to save by passing an intent to startService(). The service receives the intent in onStartCommand(), connects to the Internet and performs the database transaction. When the transaction is done, the service stops itself and it is destroyed.

Caution: A services runs in the same process as the application in which it is declared and in the main thread of that application, by default. So, if your service performs intensive or blocking operations while the user interacts with an activity from the same application, the service will slow down activity performance. To avoid impacting application performance, you should start a new thread inside the service.

Traditionally, there are two classes you can extend to create a started service:

Service
This is the base class for all services. When you extend this class, it’s important that you create a new thread in which to do all the service’s work, because the service uses your application’s main thread, by default, which could slow the performance of any activity your application is running.
IntentService
This is a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is the best option if you don’t require that your service handle multiple requests simultaneously. All you need to do is implement onHandleIntent(), which receives the intent for each start request so you can do the background work.

The following sections describe how you can implement your service using either one for these classes.

Extending the IntentService class

Because most started services don’t need to handle multiple requests simultaneously (which can actually be a dangerous multi-threading scenario), it’s probably best if you implement your service using the IntentServiceclass.

The IntentService does the following:

  • Creates a default worker thread that executes all intents delivered to onStartCommand() separate from your application’s main thread.
  • Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading.
  • Stops the service after all start requests have been handled, so you never have to call stopSelf().
  • Provides default implementation of onBind() that returns null.
  • Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation.

All this adds up to the fact that all you need to do is implement onHandleIntent() to do the work provided by the client. (Though, you also need to provide a small constructor for the service.)

Here’s an example implementation of IntentService:

public class HelloIntentService extends IntentService {

  /**
   * A constructor is required, and must call the super IntentService(String)
   * constructor with a name for the worker thread.
   */
  public HelloIntentService() {
      super("HelloIntentService");
  }

  /**
   * The IntentService calls this method from the default worker thread with
   * the intent that started the service. When this method returns, IntentService
   * stops the service, as appropriate.
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}

That’s all you need: a constructor and an implementation of onHandleIntent().

If you decide to also override other callback methods, such as onCreate()onStartCommand(), or onDestroy(), be sure to call the super implementation, so that the IntentService can properly handle the life of the worker thread.

For example, onStartCommand() must return the default implementation (which is how the intent gets delivered to onHandleIntent()):

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
    return super.onStartCommand(intent,flags,startId);
}

Besides onHandleIntent(), the only method from which you don’t need to call the super class is onBind() (but you only need to implement that if your service allows binding).

In the next section, you’ll see how the same kind of service is implemented when extending the base Serviceclass, which is a lot more code, but which might be appropriate if you need to handle simultaneous start requests.

Extending the Service class

As you saw in the previous section, using IntentService makes your implementation of a started service very simple. If, however, you require your service to perform multi-threading (instead of processing start requests through a work queue), then you can extend the Service class to handle each intent.

For comparison, the following example code is an implementation of the Service class that performs the exact same work as the example above using IntentService. That is, for each start request, it uses a worker thread to perform the job and processes only one request at a time.

public class HelloService extends Service {
  private Looper mServiceLooper;
  private ServiceHandler mServiceHandler;

  // Handler that receives messages from the thread
  private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
          super(looper);
      }
      @Override
      public void handleMessage(Message msg) {
          // Normally we would do some work here, like download a file.
          // For our sample, we just sleep for 5 seconds.
          long endTime = System.currentTimeMillis() + 5*1000;
          while (System.currentTimeMillis() < endTime) {
              synchronized (this) {
                  try {
                      wait(endTime - System.currentTimeMillis());
                  } catch (Exception e) {
                  }
              }
          }
          // Stop the service using the startId, so that we don't stop
          // the service in the middle of handling another job
          stopSelf(msg.arg1);
      }
  }

  @Override
  public void onCreate() {
    // Start up the thread running the service.  Note that we create a
    // separate thread because the service normally runs in the process's
    // main thread, which we don't want to block.  We also make it
    // background priority so CPU-intensive work will not disrupt our UI.
    HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();
   
    // Get the HandlerThread's Looper and use it for our Handler
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

      // For each start request, send a message to start a job and deliver the
      // start ID so we know which request we're stopping when we finish the job
      Message msg = mServiceHandler.obtainMessage();
      msg.arg1 = startId;
      mServiceHandler.sendMessage(msg);
     
      // If we get killed, after returning from here, restart
      return START_STICKY;
  }

  @Override
  public IBinder onBind(Intent intent) {
      // We don't provide binding, so return null
      return null;
  }
 
  @Override
  public void onDestroy() {
    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
  }
}

As you can see, it’s a lot more work than using IntentService.

However, because you handle each call to onStartCommand() yourself, you can perform multiple requests simultaneously. That’s not what this example does, but if that’s what you want, then you can create a new thread for each request and run them right away (instead of waiting for the previous request to finish).

Notice that the onStartCommand() method must return an integer. The integer is a value that describes how the system should continue the service in the event that the system kills it (as discussed above, the default implementation for IntentService handles this for you, though you are able to modify it). The return value fromonStartCommand() must be one of the following constants:

START_NOT_STICKY
If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.
START_STICKY
If the system kills the service after onStartCommand() returns, recreate the service and callonStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.
START_REDELIVER_INTENT
If the system kills the service after onStartCommand() returns, recreate the service and callonStartCommand() with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as downloading a file.

For more details about these return values, see the linked reference documentation for each constant.

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying the service to start) to startService(). The Android system calls the service’s onStartCommand() method and passes it the Intent. (You should never call onStartCommand() directly.)

For example, an activity can start the example service in the previous section (HelloSevice) using an explicit intent with startService():

Intent intent = new Intent(this, HelloService.class);
startService(intent);

The startService() method returns immediately and the Android system calls the service’s onStartCommand()method. If the service is not already running, the system first calls onCreate(), then calls onStartCommand().

If the service does not also provide binding, the intent delivered with startService() is the only mode of communication between the application component and the service. However, if you want the service to send a result back, then the client that starts the service can create a PendingIntent for a broadcast (withgetBroadcast()) and deliver it to the service in the Intent that starts the service. The service can then use the broadcast to deliver a result.

Multiple requests to start the service result in multiple corresponding calls to the service’s onStartCommand(). However, only one request to stop the service (with stopSelf() or stopService()) is required to stop it.

Stopping a service

A started service must manage its own lifecycle. That is, the system does not stop or destroy the service unless it must recover system memory and the service continues to run after onStartCommand() returns. So, the service must stop itself by calling stopSelf() or another component can stop it by calling stopService().

Once requested to stop with stopSelf() or stopService(), the system destroys the service as soon as possible.

However, if your service handles multiple requests to onStartCommand() concurrently, then you shouldn’t stop the service when you’re done processing a start request, because you might have since received a new start request (stopping at the end of the first request would terminate the second one). To avoid this problem, you can use stopSelf(int) to ensure that your request to stop the service is always based on the most recent start request. That is, when you call stopSelf(int), you pass the ID of the start request (the startId delivered toonStartCommand()) to which your stop request corresponds. Then if the service received a new start request before you were able to call stopSelf(int), then the ID will not match and the service will not stop.

Caution: It’s important that your application stops its services when it’s done working, to avoid wasting system resources and consuming battery power. If necessary, other components can stop the service by calling stopService(). Even if you enable binding for the service, you must always stop the service yourself if it ever received a call to onStartCommand().

For more information about the lifecycle of a service, see the section below about Managing the Lifecycle of a Service.

Creating a Bound Service


A bound service is one that allows application components to bind to it by calling bindService() in order to create a long-standing connection (and generally does not allow components to start it by callingstartService()).

You should create a bound service when you want to interact with the service from activities and other components in your application or to expose some of your application’s functionality to other applications, through interprocess communication (IPC).

To create a bound service, you must implement the onBind() callback method to return an IBinder that defines the interface for communication with the service. Other application components can then call bindService() to retrieve the interface and begin calling methods on the service. The service lives only to serve the application component that is bound to it, so when there are no components bound to the service, the system destroys it (you do not need to stop a bound service in the way you must when the service is started throughonStartCommand()).

To create a bound service, the first thing you must do is define the interface that specifies how a client can communicate with the service. This interface between the service and a client must be an implementation ofIBinder and is what your service must return from the onBind() callback method. Once the client receives theIBinder, it can begin interacting with the service through that interface.

Multiple clients can bind to the service at once. When a client is done interacting with the service, it callsunbindService() to unbind. Once there are no clients bound to the service, the system destroys the service.

There are multiple ways to implement a bound service and the implementation is more complicated than a started service, so the bound service discussion appears in a separate document about Bound Services.

Sending Notifications to the User


Once running, a service can notify the user of events using Toast Notifications or Status Bar Notifications.

A toast notification is a message that appears on the surface of the current window for a moment then disappears, while a status bar notification provides an icon in the status bar with a message, which the user can select in order to take an action (such as start an activity).

Usually, a status bar notification is the best technique when some background work has completed (such as a file completed downloading) and the user can now act on it. When the user selects the notification from the expanded view, the notification can start an activity (such as to view the downloaded file).

See the Toast Notifications or Status Bar Notifications developer guides for more information.

Running a Service in the Foreground


A foreground service is a service that’s considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the “Ongoing” heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.

For example, a music player that plays music from a service should be set to run in the foreground, because the user is explicitly aware of its operation. The notification in the status bar might indicate the current song and allow the user to launch an activity to interact with the music player.

To request that your service run in the foreground, call startForeground(). This method takes two parameters: an integer that uniquely identifies the notification and the Notification for the status bar. For example:

Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
        System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
        getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION, notification);

To remove the service from the foreground, call stopForeground(). This method takes a boolean, indicating whether to remove the status bar notification as well. This method does not stop the service. However, if you stop the service while it’s still running in the foreground, then the notification is also removed.

Note: The methods startForeground() and stopForeground() were introduced in Android 2.0 (API Level 5). In order to run your service in the foreground on older versions of the platform, you must use the previoussetForeground() method—see the startForeground() documentation for information about how to provide backward compatibility.

For more information about notifications, see Creating Status Bar Notifications.

Managing the Lifecycle of a Service


The lifecycle of a service is much simpler than that of an activity. However, it’s even more important that you pay close attention to how your service is created and destroyed, because a service can run in the background without the user being aware.

The service lifecycle—from when it’s created to when it’s destroyed—can follow two different paths:

  • A started service

    The service is created when another component calls startService(). The service then runs indefinitely and must stop itself by calling stopSelf(). Another component can also stop the service by callingstopService(). When the service is stopped, the system destroys it..

  • A bound service

    The service is created when another component (a client) calls bindService(). The client then communicates with the service through an IBinder interface. The client can close the connection by callingunbindService(). Multiple clients can bind to the same service and when all of them unbind, the system destroys the service. (The service does not need to stop itself.)

These two paths are not entirely separate. That is, you can bind to a service that was already started withstartService(). For example, a background music service could be started by calling startService() with anIntent that identifies the music to play. Later, possibly when the user wants to exercise some control over the player or get information about the current song, an activity can bind to the service by calling bindService(). In cases like this, stopService() or stopSelf() does not actually stop the service until all clients unbind.

Implementing the lifecycle callbacks

Like an activity, a service has lifecycle callback methods that you can implement to monitor changes in the service’s state and perform work at the appropriate times. The following skeleton service demonstrates each of the lifecycle methods:

public class ExampleService extends Service {
    int mStartMode;       // indicates how to behave if the service is killed
    IBinder mBinder;      // interface for clients that bind
    boolean mAllowRebind; // indicates whether onRebind should be used

    @Override
    public void onCreate() {
        // The service is being created
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // The service is starting, due to a call to startService()
        return mStartMode;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // A client is binding to the service with bindService()
        return mBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // All clients have unbound with unbindService()
        return mAllowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }
    @Override
    public void onDestroy() {
        // The service is no longer used and is being destroyed
    }
}

Note: Unlike the activity lifecycle callback methods, you are not required to call the superclass implementation of these callback methods.

Figure 2. The service lifecycle. The diagram on the left shows the lifecycle when the service is created withstartService() and the diagram on the right shows the lifecycle when the service is created with bindService().

By implementing these methods, you can monitor two nested loops of the service’s lifecycle:

Note: Although a started service is stopped by a call to either stopSelf() or stopService(), there is not a respective callback for the service (there’s no onStop() callback). So, unless the service is bound to a client, the system destroys it when the service is stopped—onDestroy() is the only callback received.

Figure 2 illustrates the typical callback methods for a service. Although the figure separates services that are created by startService() from those created by bindService(), keep in mind that any service, no matter how it’s started, can potentially allow clients to bind to it. So, a service that was initially started withonStartCommand() (by a client calling startService()) can still receive a call to onBind() (when a client callsbindService()).

For more information about creating a service that provides binding, see the Bound Services document, which includes more information about the onRebind() callback method in the section about Managing the Lifecycle of a Bound Service.

Intent and Filters

http://developer.android.com/guide/components/intents-filters.html

Intents and Intent Filters

Three of the core components of an application — activities, services, and broadcast receivers — are activated through messages, calledintents. Intent messaging is a facility for late run-time binding between components in the same or different applications. The intent itself, anIntent object, is a passive data structure holding an abstract description of an operation to be performed — or, often in the case of broadcasts, a description of something that has happened and is being announced. There are separate mechanisms for delivering intents to each type of component:

In each case, the Android system finds the appropriate activity, service, or set of broadcast receivers to respond to the intent, instantiating them if necessary. There is no overlap within these messaging systems: Broadcast intents are delivered only to broadcast receivers, never to activities or services. An intent passed tostartActivity() is delivered only to an activity, never to a service or broadcast receiver, and so on.

This document begins with a description of Intent objects. It then describes the rules Android uses to map intents to components — how it resolves which component should receive an intent message. For intents that don’t explicitly name a target component, this process involves testing the Intent object against intent filtersassociated with potential targets.

Intent Objects


An Intent object is a bundle of information. It contains information of interest to the component that receives the intent (such as the action to be taken and the data to act on) plus information of interest to the Android system (such as the category of component that should handle the intent and instructions on how to launch a target activity). Principally, it can contain the following:

Component name
The name of the component that should handle the intent. This field is a ComponentName object — a combination of the fully qualified class name of the target component (for example “com.example.project.app.FreneticActivity“) and the package name set in the manifest file of the application where the component resides (for example, “com.example.project“). The package part of the component name and the package name set in the manifest do not necessarily have to match.

The component name is optional. If it is set, the Intent object is delivered to an instance of the designated class. If it is not set, Android uses other information in the Intent object to locate a suitable target — seeIntent Resolution, later in this document.

The component name is set by setComponent()setClass(), or setClassName() and read bygetComponent().

 

Action
A string naming the action to be performed — or, in the case of broadcast intents, the action that took place and is being reported. The Intent class defines a number of action constants, including these:

 

Constant Target component Action
ACTION_CALL activity Initiate a phone call.
ACTION_EDIT activity Display data for the user to edit.
ACTION_MAIN activity Start up as the initial activity of a task, with no data input and no returned output.
ACTION_SYNC activity Synchronize data on a server with data on the mobile device.
ACTION_BATTERY_LOW broadcast receiver A warning that the battery is low.
ACTION_HEADSET_PLUG broadcast receiver A headset has been plugged into the device, or unplugged from it.
ACTION_SCREEN_ON broadcast receiver The screen has been turned on.
ACTION_TIMEZONE_CHANGED broadcast receiver The setting for the time zone has changed.

See the Intent class description for a list of pre-defined constants for generic actions. Other actions are defined elsewhere in the Android API. You can also define your own action strings for activating the components in your application. Those you invent should include the application package as a prefix — for example: “com.example.project.SHOW_COLOR“.

The action largely determines how the rest of the intent is structured — particularly the data and extrasfields — much as a method name determines a set of arguments and a return value. For this reason, it’s a good idea to use action names that are as specific as possible, and to couple them tightly to the other fields of the intent. In other words, instead of defining an action in isolation, define an entire protocol for the Intent objects your components can handle.

The action in an Intent object is set by the setAction() method and read by getAction().

 

Data
The URI of the data to be acted on and the MIME type of that data. Different actions are paired with different kinds of data specifications. For example, if the action field is ACTION_EDIT, the data field would contain the URI of the document to be displayed for editing. If the action is ACTION_CALL, the data field would be a tel: URI with the number to call. Similarly, if the action is ACTION_VIEW and the data field is anhttp: URI, the receiving activity would be called upon to download and display whatever data the URI refers to.

When matching an intent to a component that is capable of handling the data, it’s often important to know the type of data (its MIME type) in addition to its URI. For example, a component able to display image data should not be called upon to play an audio file.

In many cases, the data type can be inferred from the URI — particularly content: URIs, which indicate that the data is located on the device and controlled by a content provider (see the separate discussion on content providers). But the type can also be explicitly set in the Intent object. The setData() method specifies data only as a URI, setType() specifies it only as a MIME type, and setDataAndType() specifies it as both a URI and a MIME type. The URI is read by getData() and the type by getType().

 

Category
A string containing additional information about the kind of component that should handle the intent. Any number of category descriptions can be placed in an Intent object. As it does for actions, the Intent class defines several category constants, including these:

Constant Meaning
CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message.
CATEGORY_GADGET The activity can be embedded inside of another activity that hosts gadgets.
CATEGORY_HOME The activity displays the home screen, the first screen the user sees when the device is turned on or when the Home button is pressed.
CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in the top-level application launcher.
CATEGORY_PREFERENCE The target activity is a preference panel.

See the Intent class description for the full list of categories.

The addCategory() method places a category in an Intent object, removeCategory() deletes a category previously added, and getCategories() gets the set of all categories currently in the object.

 

Extras
Key-value pairs for additional information that should be delivered to the component handling the intent. Just as some actions are paired with particular kinds of data URIs, some are paired with particular extras. For example, an ACTION_TIMEZONE_CHANGED intent has a “time-zone” extra that identifies the new time zone, and ACTION_HEADSET_PLUG has a “state” extra indicating whether the headset is now plugged in or unplugged, as well as a “name” extra for the type of headset. If you were to invent a SHOW_COLOR action, the color value would be set in an extra key-value pair.

The Intent object has a series of put...() methods for inserting various types of extra data and a similar set of get...() methods for reading the data. These methods parallel those for Bundle objects. In fact, the extras can be installed and read as a Bundle using the putExtras() and getExtras() methods.

 

Flags
Flags of various sorts. Many instruct the Android system how to launch an activity (for example, which task the activity should belong to) and how to treat it after it’s launched (for example, whether it belongs in the list of recent activities). All these flags are defined in the Intent class.

The Android system and the applications that come with the platform employ Intent objects both to send out system-originated broadcasts and to activate system-defined components. To see how to structure an intent to activate a system component, consult the list of intents in the reference.

Intent Resolution


Intents can be divided into two groups:

  • Explicit intents designate the target component by its name (the component name field, mentioned earlier, has a value set). Since component names would generally not be known to developers of other applications, explicit intents are typically used for application-internal messages — such as an activity starting a subordinate service or launching a sister activity.
  • Implicit intents do not name a target (the field for the component name is blank). Implicit intents are often used to activate components in other applications.

Android delivers an explicit intent to an instance of the designated target class. Nothing in the Intent object other than the component name matters for determining which component should get the intent.

A different strategy is needed for implicit intents. In the absence of a designated target, the Android system must find the best component (or components) to handle the intent — a single activity or service to perform the requested action or the set of broadcast receivers to respond to the broadcast announcement. It does so by comparing the contents of the Intent object to intent filters, structures associated with components that can potentially receive intents. Filters advertise the capabilities of a component and delimit the intents it can handle. They open the component to the possibility of receiving implicit intents of the advertised type. If a component does not have any intent filters, it can receive only explicit intents. A component with filters can receive both explicit and implicit intents.

Only three aspects of an Intent object are consulted when the object is tested against an intent filter:

action 
data (both URI and data type) 
category

The extras and flags play no part in resolving which component receives an intent.

Intent filters

To inform the system which implicit intents they can handle, activities, services, and broadcast receivers can have one or more intent filters. Each filter describes a capability of the component, a set of intents that the component is willing to receive. It, in effect, filters in intents of a desired type, while filtering out unwanted intents — but only unwanted implicit intents (those that don’t name a target class). An explicit intent is always delivered to its target, no matter what it contains; the filter is not consulted. But an implicit intent is delivered to a component only if it can pass through one of the component’s filters.

A component has separate filters for each job it can do, each face it can present to the user. For example, the NoteEditor activity of the sample Note Pad application has two filters — one for starting up with a specific note that the user can view or edit, and another for starting with a new, blank note that the user can fill in and save. (All of Note Pad’s filters are described in the Note Pad Example section, later.)

Filters and security

An intent filter cannot be relied on for security. While it opens a component to receiving only certain kinds of implicit intents, it does nothing to prevent explicit intents from targeting the component. Even though a filter restricts the intents a component will be asked to handle to certain actions and data sources, someone could always put together an explicit intent with a different action and data source, and name the component as the target.

An intent filter is an instance of the IntentFilter class. However, since the Android system must know about the capabilities of a component before it can launch that component, intent filters are generally not set up in Java code, but in the application’s manifest file (AndroidManifest.xml) as <intent-filter> elements. (The one exception would be filters for broadcast receivers that are registered dynamically by calling Context.registerReceiver(); they are directly created as IntentFilter objects.)

A filter has fields that parallel the action, data, and category fields of an Intent object. An implicit intent is tested against the filter in all three areas. To be delivered to the component that owns the filter, it must pass all three tests. If it fails even one of them, the Android system won’t deliver it to the component — at least not on the basis of that filter. However, since a component can have multiple intent filters, an intent that does not pass through one of a component’s filters might make it through on another.

Each of the three tests is described in detail below:

Action test
An <intent-filter> element in the manifest file lists actions as <action> subelements. For example:

<intent-filter . . . >
    <action android:name="com.example.project.SHOW_CURRENT" />
    <action android:name="com.example.project.SHOW_RECENT" />
    <action android:name="com.example.project.SHOW_PENDING" />
    . . .
</intent-filter>

As the example shows, while an Intent object names just a single action, a filter may list more than one. The list cannot be empty; a filter must contain at least one <action> element, or it will block all intents.

To pass this test, the action specified in the Intent object must match one of the actions listed in the filter. If the object or the filter does not specify an action, the results are as follows:

  • If the filter fails to list any actions, there is nothing for an intent to match, so all intents fail the test. No intents can get through the filter.
  • On the other hand, an Intent object that doesn’t specify an action automatically passes the test — as long as the filter contains at least one action.

Category test
An <intent-filter> element also lists categories as subelements. For example:

<intent-filter . . . >
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    . . .
</intent-filter>

Note that the constants described earlier for actions and categories are not used in the manifest file. The full string values are used instead. For instance, the “android.intent.category.BROWSABLE” string in the example above corresponds to the CATEGORY_BROWSABLE constant mentioned earlier in this document. Similarly, the string “android.intent.action.EDIT” corresponds to the ACTION_EDIT constant.

For an intent to pass the category test, every category in the Intent object must match a category in the filter. The filter can list additional categories, but it cannot omit any that are in the intent.

In principle, therefore, an Intent object with no categories should always pass this test, regardless of what’s in the filter. That’s mostly true. However, with one exception, Android treats all implicit intents passed tostartActivity() as if they contained at least one category: “android.intent.category.DEFAULT” (theCATEGORY_DEFAULT constant). Therefore, activities that are willing to receive implicit intents must include “android.intent.category.DEFAULT” in their intent filters. (Filters with “android.intent.action.MAIN” and “android.intent.category.LAUNCHER” settings are the exception. They mark activities that begin new tasks and that are represented on the launcher screen. They can include “android.intent.category.DEFAULT” in the list of categories, but don’t need to.) See Using intent matching, later, for more on these filters.)

Data test
Like the action and categories, the data specification for an intent filter is contained in a subelement. And, as in those cases, the subelement can appear multiple times, or not at all. For example:

<intent-filter . . . >
    <data android:mimeType="video/mpeg" android:scheme="http" . . . />
    <data android:mimeType="audio/mpeg" android:scheme="http" . . . />
    . . .
</intent-filter>

Each <data> element can specify a URI and a data type (MIME media type). There are separate attributes —schemehostport, and path — for each part of the URI:

scheme://host:port/path

For example, in the following URI,

content://com.example.project:200/folder/subfolder/etc

the scheme is “content“, the host is “com.example.project“, the port is “200“, and the path is “folder/subfolder/etc“. The host and port together constitute the URI authority; if a host is not specified, the port is ignored.

Each of these attributes is optional, but they are not independent of each other: For an authority to be meaningful, a scheme must also be specified. For a path to be meaningful, both a scheme and an authority must be specified.

When the URI in an Intent object is compared to a URI specification in a filter, it’s compared only to the parts of the URI actually mentioned in the filter. For example, if a filter specifies only a scheme, all URIs with that scheme match the filter. If a filter specifies a scheme and an authority but no path, all URIs with the same scheme and authority match, regardless of their paths. If a filter specifies a scheme, an authority, and a path, only URIs with the same scheme, authority, and path match. However, a path specification in the filter can contain wildcards to require only a partial match of the path.

The type attribute of a <data> element specifies the MIME type of the data. It’s more common in filters than a URI. Both the Intent object and the filter can use a “*” wildcard for the subtype field — for example, “text/*” or “audio/*” — indicating any subtype matches.

The data test compares both the URI and the data type in the Intent object to a URI and data type specified in the filter. The rules are as follows:

  1. An Intent object that contains neither a URI nor a data type passes the test only if the filter likewise does not specify any URIs or data types.
  2. An Intent object that contains a URI but no data type (and a type cannot be inferred from the URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not specify a type. This will be the case only for URIs like mailto: and tel: that do not refer to actual data.

  3. An Intent object that contains a data type but not a URI passes the test only if the filter lists the same data type and similarly does not specify a URI.

  4. An Intent object that contains both a URI and a data type (or a data type can be inferred from the URI) passes the data type part of the test only if its type matches a type listed in the filter. It passes the URI part of the test either if its URI matches a URI in the filter or if it has a content: or file: URI and the filter does not specify a URI. In other words, a component is presumed to support content: and file:data if its filter lists only a data type.

If an intent can pass through the filters of more than one activity or service, the user may be asked which component to activate. An exception is raised if no target can be found.

Common cases

The last rule shown above for the data test, rule (d), reflects the expectation that components are able to get local data from a file or content provider. Therefore, their filters can list just a data type and do not need to explicitly name the content: and file: schemes. This is a typical case. A <data> element like the following, for example, tells Android that the component can get image data from a content provider and display it:

<data android:mimeType="image/*" />

Since most available data is dispensed by content providers, filters that specify a data type but not a URI are perhaps the most common.

Another common configuration is filters with a scheme and a data type. For example, a <data> element like the following tells Android that the component can get video data from the network and display it:

<data android:scheme="http" android:type="video/*" />

Consider, for example, what the browser application does when the user follows a link on a web page. It first tries to display the data (as it could if the link was to an HTML page). If it can’t display the data, it puts together an implicit intent with the scheme and data type and tries to start an activity that can do the job. If there are no takers, it asks the download manager to download the data. That puts it under the control of a content provider, so a potentially larger pool of activities (those with filters that just name a data type) can respond.

Most applications also have a way to start fresh, without a reference to any particular data. Activities that can initiate applications have filters with “android.intent.action.MAIN” specified as the action. If they are to be represented in the application launcher, they also specify the “android.intent.category.LAUNCHER” category:

<intent-filter . . . >
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate, but also to discover something about the set of components on the device. For example, the Android system populates the application launcher, the top-level screen that shows the applications that are available for the user to launch, by finding all the activities with intent filters that specify the “android.intent.action.MAIN” action and “android.intent.category.LAUNCHER” category (as illustrated in the previous section). It then displays the icons and labels of those activities in the launcher. Similarly, it discovers the home screen by looking for the activity with “android.intent.category.HOME” in its filter.

Your application can use intent matching is a similar way. The PackageManager has a set of query...()methods that return all components that can accept a particular intent, and a similar series of resolve...()methods that determine the best component to respond to an intent. For example, queryIntentActivities()returns a list of all activities that can perform the intent passed as an argument, and queryIntentServices()returns a similar list of services. Neither method activates the components; they just list the ones that can respond. There’s a similar method, queryBroadcastReceivers(), for broadcast receivers.

Note Pad Example


The Note Pad sample application enables users to browse through a list of notes, view details about individual items in the list, edit the items, and add a new item to the list. This section looks at the intent filters declared in its manifest file. (If you’re working offline in the SDK, you can find all the source files for this sample application, including its manifest file, at <sdk>/samples/NotePad/index.html. If you’re viewing the documentation online, the source files are in the Tutorials and Sample Code section here.)

In its manifest file, the Note Pad application declares three activities, each with at least one intent filter. It also declares a content provider that manages the note data. Here is the manifest file in its entirety:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.android.notepad">
    <application android:icon="@drawable/app_notes"
                 android:label="@string/app_name" >

        <provider android:name="NotePadProvider"
                  android:authorities="com.google.provider.NotePad" />

        <activity android:name="NotesList" android:label="@string/title_notes_list">
            <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.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="android.intent.action.PICK" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>
       
        <activity android:name="NoteEditor"
                  android:theme="@android:style/Theme.Light"
                  android:label="@string/title_note" >
            <intent-filter android:label="@string/resolve_edit">
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="com.android.notepad.action.EDIT_NOTE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.INSERT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>
        </activity>
       
        <activity android:name="TitleEditor"
                  android:label="@string/title_edit_title"
                  android:theme="@android:style/Theme.Dialog">
            <intent-filter android:label="@string/resolve_title">
                <action android:name="com.android.notepad.action.EDIT_TITLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.ALTERNATIVE" />
                <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>
       
    </application>
</manifest>

The first activity, NotesList, is distinguished from the other activities by the fact that it operates on a directory of notes (the note list) rather than on a single note. It would generally serve as the initial user interface into the application. It can do three things as described by its three intent filters:

  1. <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    This filter declares the main entry point into the Note Pad application. The standard MAIN action is an entry point that does not require any other information in the Intent (no data specification, for example), and theLAUNCHER category says that this entry point should be listed in the application launcher.

  2. <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <action android:name="android.intent.action.EDIT" />
        <action android:name="android.intent.action.PICK" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
    </intent-filter>

    This filter declares the things that the activity can do on a directory of notes. It can allow the user to view or edit the directory (via the VIEW and EDIT actions), or to pick a particular note from the directory (via the PICKaction).

    The mimeType attribute of the <data> element specifies the kind of data that these actions operate on. It indicates that the activity can get a Cursor over zero or more items (vnd.android.cursor.dir) from a content provider that holds Note Pad data (vnd.google.note). The Intent object that launches the activity would include a content: URI specifying the exact data of this type that the activity should open.

    Note also the DEFAULT category supplied in this filter. It’s there because the Context.startActivity() andActivity.startActivityForResult() methods treat all intents as if they contained the DEFAULT category — with just two exceptions:

    • Intents that explicitly name the target activity
    • Intents consisting of the MAIN action and LAUNCHER category

    Therefore, the DEFAULT category is required for all filters — except for those with the MAIN action and LAUNCHERcategory. (Intent filters are not consulted for explicit intents.)

  3. <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
    </intent-filter>

    This filter describes the activity’s ability to return a note selected by the user without requiring any specification of the directory the user should choose from. The GET_CONTENT action is similar to the PICKaction. In both cases, the activity returns the URI for a note selected by the user. (In each case, it’s returned to the activity that called startActivityForResult() to start the NoteList activity.) Here, however, the caller specifies the type of data desired instead of the directory of data the user will be picking from.

    The data type, vnd.android.cursor.item/vnd.google.note, indicates the type of data the activity can return — a URI for a single note. From the returned URI, the caller can get a Cursor for exactly one item (vnd.android.cursor.item) from the content provider that holds Note Pad data (vnd.google.note).

    In other words, for the PICK action in the previous filter, the data type indicates the type of data the activity could display to the user. For the GET_CONTENT filter, it indicates the type of data the activity can return to the caller.

Given these capabilities, the following intents will resolve to the NotesList activity:

action: android.intent.action.MAIN
Launches the activity with no data specified.
action: android.intent.action.MAIN 
category: android.intent.category.LAUNCHER
Launches the activity with no data selected specified. This is the actual intent used by the Launcher to populate its top-level list. All activities with filters that match this action and category are added to the list.
action: android.intent.action.VIEW 
data: content://com.google.provider.NotePad/notes
Asks the activity to display a list of all the notes undercontent://com.google.provider.NotePad/notes. The user can then browse through the list and get information about the items in it.
action: android.intent.action.PICK 
data: content://com.google.provider.NotePad/notes
Asks the activity to display a list of the notes under content://com.google.provider.NotePad/notes. The user can then pick a note from the list, and the activity will return the URI for that item back to the activity that started the NoteList activity.
action: android.intent.action.GET_CONTENT 
data type: vnd.android.cursor.item/vnd.google.note
Asks the activity to supply a single item of Note Pad data.

The second activity, NoteEditor, shows users a single note entry and allows them to edit it. It can do two things as described by its two intent filters:

  1. <intent-filter android:label="@string/resolve_edit">
        <action android:name="android.intent.action.VIEW" />
        <action android:name="android.intent.action.EDIT" />
        <action android:name="com.android.notepad.action.EDIT_NOTE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
    </intent-filter>

    The first, primary, purpose of this activity is to enable the user to interact with a single note — to either VIEWthe note or EDIT it. (The EDIT_NOTE category is a synonym for EDIT.) The intent would contain the URI for data matching the MIME type vnd.android.cursor.item/vnd.google.note — that is, the URI for a single, specific note. It would typically be a URI that was returned by the PICK or GET_CONTENT actions of the NoteList activity.

    As before, this filter lists the DEFAULT category so that the activity can be launched by intents that don’t explicitly specify the NoteEditor class.

  2. <intent-filter>
        <action android:name="android.intent.action.INSERT" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
    </intent-filter>

    The secondary purpose of this activity is to enable the user to create a new note, which it will INSERT into an existing directory of notes. The intent would contain the URI for data matching the MIME typevnd.android.cursor.dir/vnd.google.note — that is, the URI for the directory where the note should be placed.

Given these capabilities, the following intents will resolve to the NoteEditor activity:

action: android.intent.action.VIEW 
data: content://com.google.provider.NotePad/notes/ID
Asks the activity to display the content of the note identified by ID. (For details on how content: URIs specify individual members of a group, see Content Providers.)
action: android.intent.action.EDIT 
data: content://com.google.provider.NotePad/notes/ID
Asks the activity to display the content of the note identified by ID, and to let the user edit it. If the user saves the changes, the activity updates the data for the note in the content provider.
action: android.intent.action.INSERT 
data: content://com.google.provider.NotePad/notes
Asks the activity to create a new, empty note in the notes list atcontent://com.google.provider.NotePad/notes and allow the user to edit it. If the user saves the note, its URI is returned to the caller.

The last activity, TitleEditor, enables the user to edit the title of a note. This could be implemented by directly invoking the activity (by explicitly setting its component name in the Intent), without using an intent filter. But here we take the opportunity to show how to publish alternative operations on existing data:

<intent-filter android:label="@string/resolve_title">
    <action android:name="com.android.notepad.action.EDIT_TITLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.ALTERNATIVE" />
    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
    <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
</intent-filter>

The single intent filter for this activity uses a custom action called “com.android.notepad.action.EDIT_TITLE“. It must be invoked on a specific note (data type vnd.android.cursor.item/vnd.google.note), like the previousVIEW and EDIT actions. However, here the activity displays the title contained in the note data, not the content of the note itself.

In addition to supporting the usual DEFAULT category, the title editor also supports two other standard categories: ALTERNATIVE and SELECTED_ALTERNATIVE. These categories identify activities that can be presented to users in a menu of options (much as the LAUNCHER category identifies activities that should be presented to user in the application launcher). Note that the filter also supplies an explicit label (viaandroid:label="@string/resolve_title") to better control what users see when presented with this activity as an alternative action to the data they are currently viewing. (For more information on these categories and building options menus, see the PackageManager.queryIntentActivityOptions() andMenu.addIntentOptions() methods.)

Given these capabilities, the following intent will resolve to the TitleEditor activity:

action: com.android.notepad.action.EDIT_TITLE 
data: content://com.google.provider.NotePad/notes/ID
Asks the activity to display the title associated with note ID, and allow the user to edit the title.

Cookies

http://en.wikipedia.org/wiki/HTTP_cookie

Session cookie

A user’s session cookie[14] (also known as an in-memory cookie or transient cookie) for a website exists in temporary memory only while the user is reading and navigating the website. When an expiry date or validity interval is not set at cookie creation time, a session cookie is created. Web browsers normally delete session cookies when the user closes the browser.[15][16]

[edit]Persistent cookie

A persistent cookie[14] will outlast user sessions. If a persistent cookie has its Max-Age set to 1 year, then, within the year, the initial value set in that cookie would be sent back to the server every time the user visited the server. This could be used to record a vital piece of information such as how the user initially came to this website. For this reason persistent cookies are also called tracking cookies.

[edit]Secure cookie

A secure cookie has the secure attribute enabled and is only used via HTTPS, ensuring that the cookie is always encrypted when transmitting from client to server. This makes the cookie less likely to be exposed to cookie theft via eavesdropping.

[edit]HttpOnly cookie

The HttpOnly cookie is supported by most modern browsers.[17][18] On a supported browser, an HttpOnly session cookie will be used only when transmitting HTTP (or HTTPS) requests, thus restricting access from other, non-HTTP APIs (such as JavaScript). This restriction mitigates but does not eliminate the threat of session cookie theft via cross-site scripting (XSS).[19] This feature applies only to session-management cookies, and not other browser cookies.

 

Third-party cookie

First-party cookies are cookies set with the same domain (or its subdomain) as your browser’s address bar. Third-party cookies are cookies set with domains different from the one shown on the address bar. The web pages on the first domain may feature content from a third-party domain, e.g. a banner advert run by http://www.advexample.com. Privacy setting options in most modern browsers allow you to block third-party tracking cookies.

As an example, suppose a user visits http://www.example1.com, which includes an advert which sets a cookie with the domain ad.foxytracking.com. When the user later visits http://www.example2.com, another advert can set another cookie with the domain ad.foxytracking.com. Eventually, both of these cookies will be sent to the advertiser when loading their ads or visiting their website. The advertiser can then use these cookies to build up a browsing history of the user across all the websites this advertiser has footprints on.

[edit]Supercookie

A “supercookie” is a cookie with an origin of a Top-Level Domain (TLD) or an effective Top-Level Domain. Some domains that are considered, “Top-Level” may in fact be a secondary or lower-level domain. For example, .co.uk ork12.ca.us are considered Top-Level even though they are multiple levels deep. These domains are referred to as Public Suffixes and are not open for reservation by end-users.

Most browsers, by default, allow first-party cookies—a cookie with domain to be the same or sub-domain of the requesting host. For example, a user visiting http://www.example.com can have a cookie set with domain http://www.example.comor .example.com. A so-called “supercookie” is a cookie originating from a Public Suffix or Top-Level Domain such as, .com. It is important that these cookies are blocked by browsers otherwise, an attacker in control of malicious website with domain .com could set a “supercookie” and potentially disrupt or impersonate legitimate user requests to example.com. Thus taking advantage of the fact that .com can set valid cookies for sub-domain example.com.

The Public Suffix List is a cross-vendor initiative to provide an accurate list of domain name suffixes changing. Older versions of browsers may not have the most up-to-date list, and will therefore be vulnerable to supercookies from certain domains.

[edit]Supercookie (other uses)

The term “supercookie” is sometimes used for tracking technologies that do not rely on HTTP cookies. Two such “supercookie” mechanisms were found on Microsoft websites: cookie syncing that respawned MUID cookies, and ETagcookies.[20] Due to media attention, Microsoft later disabled this code:

In response to recent attention on “supercookies” in the media, we wanted to share more detail on the immediate action we took to address this issue, as well as affirm our commitment to the privacy of our customers. According to researchers, including Jonathan Mayer at Stanford University, “supercookies” are capable of re-creating users’ cookies or other identifiers after people deleted regular cookies. Mr. Mayer identified Microsoft as one among others that had this code, and when he brought his findings to our attention we promptly investigated. We determined that the cookie behavior he observed was occurring under certain circumstances as a result of older code that was used only on our own sites, and was already scheduled to be discontinued. We accelerated this process and quickly disabled this code. At no time did this functionality cause Microsoft cookie identifiers or data associated with those identifiers to be shared outside of Microsoft.
—Mike Hintze[21]

[edit]Zombie cookie

Main articles: Zombie cookie and Evercookie

Some cookies are automatically recreated after a user has deleted them; these are called zombie cookies. This is accomplished by a script storing the content of the cookie in some other locations, such as the local storage available to Flash content, HTML5 storages and other client side mechanisms, and then recreating the cookie from backup stores when the cookie’s absence is detected.

SQL Injection Mitigation: Using Parameterized Queries

http://blogs.technet.com/b/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx

http://blogs.technet.com/b/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx  (not in this post)

Michael Howard wrote an excellent article yesterday on how the SDL addresses SQL injection.  He walks through three coding requirements/defenses:

  • Use SQL Parameterized Queries
  • Use Stored Procedures
  • Use SQL Execute-only Permissions

As Michael points out, only the first, parameterized queries, remedies the problem.  The other two provide additional defense.

The good news is that changing your ASP pages to use parameterized queries instead of just dynamically building the query is dead simple.  The bad news is that MSDN doesn’t have a lot of samples of how to do parameterized queries in ASP so I thought providing one would be helpful.

As an example, I’m sure that a lot of the websites that have been compromised recently via SQL injection have something like this:

Set objConnection = Server.CreateObject(“ADODB.Connection”)
objConnection.Open “Provider=SQLOLEDB;Data Source=SQLSERVER;” _
& “Initial Catalog=website;User Id=user;Password=password;” _
& “Connect Timeout=15;Network Library=dbmssocn;”
strSQL = “SELECT name, info FROM [companies] WHERE name =” & strSearch & “‘;”
Set objSearchResults = objConnection.Execute(strSQL)

This code is going to be extremely vulnerable to SQL injection since it’s just taking the user input (which was passed in via a query string from a web form) and pasting it into the SQL statement.

The good thing about parameterization is that it separates the ‘executable’ code (“SELECT name, info…”) from the ‘data’ (strSearch) we’re using.  With a few changes, we can make this code use parameters for the query and, with this small change, defend against being exploited in this way.

Set objConnection = Server.CreateObject(“ADODB.Connection”)
objConnection.Open “Provider=SQLOLEDB;Data Source=SQLSERVER;” _
& “Initial Catalog=website;User Id=user;Password=password;” _
& “Connect Timeout=15;Network Library=dbmssocn;”
strSql = “SELECT name, info FROM [companies] WHERE name = ?;”
set objCommand = Server.CreateObject(“ADODB.Command”)
objCommand.ActiveConnection = objConnection
objCommand.CommandText = strSql
objCommand.Parameters(0).value = strSearch
Set objSearchResults = objCommand.Execute()

All that we needed to do was:

  • Replace the query string in our SQL squery statement with a ? (which is the placeholder for a parameter).
  • Create a new Command object for our command.
  • Assign our active connection and command text to the Command object.
  • Set the first parameter in the parameters collection to our dynamic string.
  • Execute the command.

If we needed to use multiple parameters in our query, we’d add additional question marks to strSQL and additional parameters to the Parameters collection.  For example:

strSql = “SELECT name, info FROM [companies] WHERE name = ?” _
& “AND info = ?;”

objCommand.Parameters(0).value = strName
objCommand.Parameters(1).value = strInfo

There is a BIG caveat on this — the method I show above has a performance hit because I haven’t specified the types of the parameters.  This means that ADO has to make a roundtrip to the SQL server to figure out the type before actually using it.  You can fix this by creating parameters objects with the appropriate type which would have the added bonus of doing simple input validation as well.  If there’s interest, I’ll write a followup in the next few weeks with some samples of typed, parameterized queries.  (EDIT:  Written, it’s here.)

Additional info is available on MSDN here.  NomadPete has a fuller walkthrough here that covers parameterized queries and stored procedures.

As always, this is only part of the job in securing against SQL injection; however, it is probably the single most useful change you could make.

How and Why to Use Parameterized Queries

http://blogs.msdn.com/b/sqlphp/archive/2008/09/30/how-and-why-to-use-parameterized-queries.aspx

 

A parameterized query is a query in which placeholders are used for parameters and the parameter values are supplied at execution time. The most important reason to use parameterized queries is to avoid SQL injection attacks.

Let’s take a look at what can happen if we don’t use parameterized queries. Consider the following code that concatenates user input with SQL syntax:

$name = $_REQUEST[‘name’];

$email = $_REQUEST[’email’];

$sql = “INSERT INTO CustomerTable (Name, Email)

        VALUES (‘$name’, ‘$email’)”;

Now suppose a user enters the following data:

Image

The resulting SQL query (defined by $sql) is the following:

INSERT INTO CustomerTable (Name, Email)
    VALUES (‘Brian’, ‘bswan@microsoft.com’);
DROP TABLE CustomerTable;
PRINT ‘Gotcha!’–‘)

This is a perfectly valid SQL query, and, as you can see, the results of executing this on the server (with a function such as sqlsrv_query) would not be desired. This does assume that the user has some knowledge of your database (or that he guessed the table name correctly) and that credentials used to access the server have sufficient permissions to drop a table. However far-fetched these assumptions may seem, when you construct SQL queries by concatenating user input with SQL syntax you run the risk of the user supplying input that may cause your query to do something that you had not expected.

The simplest and most effective way to avoid the scenario described above is to use parameterized queries. Here is how the code above would look when using a parameterized query:

$name = $_REQUEST[‘name’];
$email = $_REQUEST[’email’];
$params = array($name, $email);
$sql = ‘INSERT INTO CustomerTable (Name, Email) VALUES (?, ?)’;

Now, to execute the query, we just pass an open connection ($conn), the SQL query ($sql), and the parameter array ($params) to the sqlsrv_query function:

$stmt = sqlsrv_query($conn, $tsql, $params);

(The sqlsrv_query function returns a PHP statement resource.)

The difference here (as opposed to concatenating user input with SQL syntax) is that a query plan is constructed on the server before the query is executed with parameter values. In other words, a query plan is constructed on the server for this query:

INSERT INTO CustomerTable (Name, Email) VALUES (?, ?)

When you execute this query using parameterized values and the same user input , only the INSERT query is executed. The server accepts the user input of

bswan@microsoft.com’; DROP TABLE CustomerTable; PRINT ‘Gotcha!’–

and inserts that entire value into the Email field. Using a parameterized query prevents the user input from leading to SQL injection. Plus, using a parameterized query allows you to handle less malicious scenarios, such as where the user supplies a value like “O’Leary” without forcing you to replace single quotes with double single quotes.

For more information about avoiding SQL injection attacks, see SQL Injection. For more information about how to execute parameterized queries, see How to: Perform Parameterized QueriesHow to: Execute a Single Query, and How to: Execute a Query Multiple Times in the driver documentation.

Regardless of which database server or driver you use, a best practice for writing code is to use parameterized queries for security reasons.