Reorganize Service API demos.

This collapses multiple related files in one, to make it easier to deal
with in documentation and elsewhere.
This commit is contained in:
Dianne Hackborn
2009-12-04 15:31:04 -08:00
parent fa3d6b5411
commit 579c7f19ac
12 changed files with 642 additions and 763 deletions

View File

@@ -217,14 +217,17 @@
<service android:name=".app.LocalService" /> <service android:name=".app.LocalService" />
<activity android:name=".app.LocalServiceController" android:label="@string/activity_local_service_controller"> <activity android:name=".app.LocalService$Controller"
android:label="@string/activity_local_service_controller"
android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" /> <category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.LocalServiceBinding" android:label="@string/activity_local_service_binding"> <activity android:name=".app.LocalService$Binding"
android:label="@string/activity_local_service_binding">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" /> <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -243,14 +246,17 @@
</intent-filter> </intent-filter>
</service> </service>
<activity android:name=".app.RemoteServiceController" android:label="@string/activity_remote_service_controller"> <activity android:name=".app.RemoteService$Controller"
android:label="@string/activity_remote_service_controller"
android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" /> <category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.RemoteServiceBinding" android:label="@string/activity_remote_service_binding"> <activity android:name=".app.RemoteService$Binding"
android:label="@string/activity_remote_service_binding">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" /> <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -259,7 +265,9 @@
<service android:name=".app.ServiceStartArguments" /> <service android:name=".app.ServiceStartArguments" />
<activity android:name=".app.ServiceStartArgumentsController" android:label="@string/activity_service_start_arguments_controller"> <activity android:name=".app.ServiceStartArguments$Controller"
android:label="@string/activity_service_start_arguments_controller"
android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" /> <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -268,7 +276,9 @@
<service android:name=".app.ForegroundService" /> <service android:name=".app.ForegroundService" />
<activity android:name=".app.ForegroundServiceController" android:label="@string/activity_foreground_service_controller"> <activity android:name=".app.ForegroundService$Controller"
android:label="@string/activity_foreground_service_controller"
android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" /> <category android:name="android.intent.category.SAMPLE_CODE" />

View File

@@ -16,13 +16,18 @@
package com.example.android.apis.app; package com.example.android.apis.app;
import android.app.Activity;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -43,6 +48,7 @@ public class ForegroundService extends Service {
static final String ACTION_FOREGROUND = "com.example.android.apis.FOREGROUND"; static final String ACTION_FOREGROUND = "com.example.android.apis.FOREGROUND";
static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND"; static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND";
// BEGIN_INCLUDE(foreground_compatibility)
private static final Class[] mStartForegroundSignature = new Class[] { private static final Class[] mStartForegroundSignature = new Class[] {
int.class, Notification.class}; int.class, Notification.class};
private static final Class[] mStopForegroundSignature = new Class[] { private static final Class[] mStopForegroundSignature = new Class[] {
@@ -54,60 +60,6 @@ public class ForegroundService extends Service {
private Object[] mStartForegroundArgs = new Object[2]; private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1]; private Object[] mStopForegroundArgs = new Object[1];
@Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground",
mStartForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground",
mStopForegroundSignature);
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
}
// This is the old onStart method that will be called on the pre-2.0
// platform. On 2.0 or later we override onStartCommand() so this
// method will not be called.
@Override
public void onStart(Intent intent, int startId) {
handleCommand(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleCommand(intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
void handleCommand(Intent intent) {
if (ACTION_FOREGROUND.equals(intent.getAction())) {
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(R.string.foreground_service_started);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.stat_sample, text,
System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, ForegroundServiceController.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.local_service_label),
text, contentIntent);
startForegroundCompat(R.string.foreground_service_started, notification);
} else if (ACTION_BACKGROUND.equals(intent.getAction())) {
stopForegroundCompat(R.string.foreground_service_started);
}
}
/** /**
* This is a wrapper around the new startForeground method, using the older * This is a wrapper around the new startForeground method, using the older
* APIs if it is not available. * APIs if it is not available.
@@ -160,14 +112,119 @@ public class ForegroundService extends Service {
setForeground(false); setForeground(false);
} }
@Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground",
mStartForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground",
mStopForegroundSignature);
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
}
@Override @Override
public void onDestroy() { public void onDestroy() {
// Make sure our notification is gone. // Make sure our notification is gone.
stopForegroundCompat(R.string.foreground_service_started); stopForegroundCompat(R.string.foreground_service_started);
} }
// END_INCLUDE(foreground_compatibility)
// BEGIN_INCLUDE(start_compatibility)
// This is the old onStart method that will be called on the pre-2.0
// platform. On 2.0 or later we override onStartCommand() so this
// method will not be called.
@Override
public void onStart(Intent intent, int startId) {
handleCommand(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleCommand(intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
// END_INCLUDE(start_compatibility)
void handleCommand(Intent intent) {
if (ACTION_FOREGROUND.equals(intent.getAction())) {
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(R.string.foreground_service_started);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.stat_sample, text,
System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, Controller.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.local_service_label),
text, contentIntent);
startForegroundCompat(R.string.foreground_service_started, notification);
} else if (ACTION_BACKGROUND.equals(intent.getAction())) {
stopForegroundCompat(R.string.foreground_service_started);
}
}
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return null;
} }
// ----------------------------------------------------------------------
/**
* <p>Example of explicitly starting and stopping the {@link ForegroundService}.
*
* <p>Note that this is implemented as an inner class only keep the sample
* all together; typically this code would appear in some separate class.
*/
public static class Controller extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.foreground_service_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start_foreground);
button.setOnClickListener(mForegroundListener);
button = (Button)findViewById(R.id.start_background);
button.setOnClickListener(mBackgroundListener);
button = (Button)findViewById(R.id.stop);
button.setOnClickListener(mStopListener);
}
private OnClickListener mForegroundListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ForegroundService.ACTION_FOREGROUND);
intent.setClass(Controller.this, ForegroundService.class);
startService(intent);
}
};
private OnClickListener mBackgroundListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ForegroundService.ACTION_BACKGROUND);
intent.setClass(Controller.this, ForegroundService.class);
startService(intent);
}
};
private OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
stopService(new Intent(Controller.this,
ForegroundService.class));
}
};
}
} }

View File

@@ -1,74 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
// Need the following import to get access to the app resources, since this
// class is in a sub-package.
import com.example.android.apis.R;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* <p>Example of explicitly starting and stopping the {@link ForegroundService}.
*/
public class ForegroundServiceController extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.foreground_service_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start_foreground);
button.setOnClickListener(mForegroundListener);
button = (Button)findViewById(R.id.start_background);
button.setOnClickListener(mBackgroundListener);
button = (Button)findViewById(R.id.stop);
button.setOnClickListener(mStopListener);
}
private OnClickListener mForegroundListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ForegroundService.ACTION_FOREGROUND);
intent.setClass(ForegroundServiceController.this, ForegroundService.class);
startService(intent);
}
};
private OnClickListener mBackgroundListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ForegroundService.ACTION_BACKGROUND);
intent.setClass(ForegroundServiceController.this, ForegroundService.class);
startService(intent);
}
};
private OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
stopService(new Intent(ForegroundServiceController.this,
ForegroundService.class));
}
};
}

View File

@@ -16,15 +16,22 @@
package com.example.android.apis.app; package com.example.android.apis.app;
import android.app.Activity;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.Parcel;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; import android.widget.Toast;
// Need the following import to get access to the app resources, since this // Need the following import to get access to the app resources, since this
@@ -33,8 +40,8 @@ import com.example.android.apis.R;
/** /**
* This is an example of implementing an application service that runs locally * This is an example of implementing an application service that runs locally
* in the same process as the application. The {@link LocalServiceController} * in the same process as the application. The {@link Controller}
* and {@link LocalServiceBinding} classes show how to interact with the * and {@link Binding} classes show how to interact with the
* service. * service.
* *
* <p>Notice the use of the {@link NotificationManager} when interesting things * <p>Notice the use of the {@link NotificationManager} when interesting things
@@ -103,7 +110,7 @@ public class LocalService extends Service {
// The PendingIntent to launch our activity if the user selects this notification // The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, LocalServiceController.class), 0); new Intent(this, Controller.class), 0);
// Set the info for the views that show in the notification panel. // Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.local_service_label), notification.setLatestEventInfo(this, getText(R.string.local_service_label),
@@ -113,5 +120,127 @@ public class LocalService extends Service {
// We use a layout id because it is a unique number. We use it later to cancel. // We use a layout id because it is a unique number. We use it later to cancel.
mNM.notify(R.string.local_service_started, notification); mNM.notify(R.string.local_service_started, notification);
} }
// ----------------------------------------------------------------------
/**
* <p>Example of explicitly starting and stopping the local service.
* This demonstrates the implementation of a service that runs in the same
* process as the rest of the application, which is explicitly started and stopped
* as desired.</p>
*
* <p>Note that this is implemented as an inner class only keep the sample
* all together; typically this code would appear in some separate class.
*/
public static class Controller extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_service_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start);
button.setOnClickListener(mStartListener);
button = (Button)findViewById(R.id.stop);
button.setOnClickListener(mStopListener);
} }
private OnClickListener mStartListener = new OnClickListener() {
public void onClick(View v) {
// Make sure the service is started. It will continue running
// until someone calls stopService(). The Intent we use to find
// the service explicitly specifies our service component, because
// we want it running in our own process and don't want other
// applications to replace it.
startService(new Intent(Controller.this,
LocalService.class));
}
};
private OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
// Cancel a previous call to startService(). Note that the
// service will not actually stop at this point if there are
// still bound clients.
stopService(new Intent(Controller.this,
LocalService.class));
}
};
}
// ----------------------------------------------------------------------
/**
* Example of binding and unbinding to the local service.
* This demonstrates the implementation of a service which the client will
* bind to, receiving an object through which it can communicate with the service.</p>
*
* <p>Note that this is implemented as an inner class only keep the sample
* all together; typically this code would appear in some separate class.
*/
public static class Binding extends Activity {
private boolean mIsBound;
private LocalService mBoundService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_service_binding);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.bind);
button.setOnClickListener(mBindListener);
button = (Button)findViewById(R.id.unbind);
button.setOnClickListener(mUnbindListener);
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mBoundService = ((LocalService.LocalBinder)service).getService();
// Tell the user about this for our demo.
Toast.makeText(Binding.this, R.string.local_service_connected,
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
mBoundService = null;
Toast.makeText(Binding.this, R.string.local_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
private OnClickListener mBindListener = new OnClickListener() {
public void onClick(View v) {
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(Binding.this,
LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
};
private OnClickListener mUnbindListener = new OnClickListener() {
public void onClick(View v) {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
};
}
}

View File

@@ -1,103 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
import com.example.android.apis.R;
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.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
/**
* <p>Example of binding and unbinding to the {@link LocalService}.
* This demonstrates the implementation of a service which the client will
* bind to, receiving an object through which it can communicate with the service.</p>
*/
public class LocalServiceBinding extends Activity {
private boolean mIsBound;
private LocalService mBoundService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_service_binding);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.bind);
button.setOnClickListener(mBindListener);
button = (Button)findViewById(R.id.unbind);
button.setOnClickListener(mUnbindListener);
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mBoundService = ((LocalService.LocalBinder)service).getService();
// Tell the user about this for our demo.
Toast.makeText(LocalServiceBinding.this, R.string.local_service_connected,
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
mBoundService = null;
Toast.makeText(LocalServiceBinding.this, R.string.local_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
private OnClickListener mBindListener = new OnClickListener() {
public void onClick(View v) {
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(LocalServiceBinding.this,
LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
};
private OnClickListener mUnbindListener = new OnClickListener() {
public void onClick(View v) {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
};
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
// Need the following import to get access to the app resources, since this
// class is in a sub-package.
import com.example.android.apis.R;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* <p>Example of explicitly starting and stopping the {@link LocalService}.
* This demonstrates the implementation of a service that runs in the same
* process as the rest of the application, which is explicitly started and stopped
* as desired.</p>
*/
public class LocalServiceController extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_service_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start);
button.setOnClickListener(mStartListener);
button = (Button)findViewById(R.id.stop);
button.setOnClickListener(mStopListener);
}
private OnClickListener mStartListener = new OnClickListener() {
public void onClick(View v)
{
// Make sure the service is started. It will continue running
// until someone calls stopService(). The Intent we use to find
// the service explicitly specifies our service component, because
// we want it running in our own process and don't want other
// applications to replace it.
startService(new Intent(LocalServiceController.this,
LocalService.class));
}
};
private OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v)
{
// Cancel a previous call to startService(). Note that the
// service will not actually stop at this point if there are
// still bound clients.
stopService(new Intent(LocalServiceController.this,
LocalService.class));
}
};
}

View File

@@ -16,21 +16,28 @@
package com.example.android.apis.app; package com.example.android.apis.app;
import android.app.Activity;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.Process; import android.os.Process;
import android.os.RemoteCallbackList; import android.os.RemoteCallbackList;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import java.util.HashMap;
// Need the following import to get access to the app resources, since this // Need the following import to get access to the app resources, since this
// class is in a sub-package. // class is in a sub-package.
import com.example.android.apis.R; import com.example.android.apis.R;
@@ -39,8 +46,13 @@ import com.example.android.apis.R;
* This is an example of implementing an application service that runs in a * This is an example of implementing an application service that runs in a
* different process than the application. Because it can be in another * different process than the application. Because it can be in another
* process, we must use IPC to interact with it. The * process, we must use IPC to interact with it. The
* {@link RemoteServiceController} and {@link RemoteServiceBinding} classes * {@link Controller} and {@link Binding} classes
* show how to interact with the service. * show how to interact with the service.
*
* <p>Note that most applications <strong>do not</strong> need to deal with
* the complexity shown here. If your application simply has a service
* running in its own process, the {@link LocalService} sample shows a much
* simpler way to interact with it.
*/ */
public class RemoteService extends Service { public class RemoteService extends Service {
/** /**
@@ -172,7 +184,7 @@ public class RemoteService extends Service {
// The PendingIntent to launch our activity if the user selects this notification // The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, LocalServiceController.class), 0); new Intent(this, Controller.class), 0);
// Set the info for the views that show in the notification panel. // Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.remote_service_label), notification.setLatestEventInfo(this, getText(R.string.remote_service_label),
@@ -182,4 +194,266 @@ public class RemoteService extends Service {
// We use a string id because it is a unique number. We use it later to cancel. // We use a string id because it is a unique number. We use it later to cancel.
mNM.notify(R.string.remote_service_started, notification); mNM.notify(R.string.remote_service_started, notification);
} }
// ----------------------------------------------------------------------
/**
* <p>Example of explicitly starting and stopping the remove service.
* This demonstrates the implementation of a service that runs in a different
* process than the rest of the application, which is explicitly started and stopped
* as desired.</p>
*
* <p>Note that this is implemented as an inner class only keep the sample
* all together; typically this code would appear in some separate class.
*/
public static class Controller extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_service_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start);
button.setOnClickListener(mStartListener);
button = (Button)findViewById(R.id.stop);
button.setOnClickListener(mStopListener);
}
private OnClickListener mStartListener = new OnClickListener() {
public void onClick(View v) {
// Make sure the service is started. It will continue running
// until someone calls stopService().
// We use an action code here, instead of explictly supplying
// the component name, so that other packages can replace
// the service.
startService(new Intent(
"com.example.android.apis.app.REMOTE_SERVICE"));
}
};
private OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
// Cancel a previous call to startService(). Note that the
// service will not actually stop at this point if there are
// still bound clients.
stopService(new Intent(
"com.example.android.apis.app.REMOTE_SERVICE"));
}
};
}
// ----------------------------------------------------------------------
/**
* Example of binding and unbinding to the remote service.
* This demonstrates the implementation of a service which the client will
* bind to, interacting with it through an aidl interface.</p>
*
* <p>Note that this is implemented as an inner class only keep the sample
* all together; typically this code would appear in some separate class.
*/
// BEGIN_INCLUDE(calling_a_service)
public static class Binding extends Activity {
/** The primary interface we will be calling on the service. */
IRemoteService mService = null;
/** Another interface we use on the service. */
ISecondary mSecondaryService = null;
Button mKillButton;
TextView mCallbackText;
private boolean mIsBound;
/**
* Standard initialization of this activity. Set up the UI, then wait
* for the user to poke it before doing anything.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_service_binding);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.bind);
button.setOnClickListener(mBindListener);
button = (Button)findViewById(R.id.unbind);
button.setOnClickListener(mUnbindListener);
mKillButton = (Button)findViewById(R.id.kill);
mKillButton.setOnClickListener(mKillListener);
mKillButton.setEnabled(false);
mCallbackText = (TextView)findViewById(R.id.callback);
mCallbackText.setText("Not attached.");
}
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. We are communicating with our
// service through an IDL interface, so get a client-side
// representation of that from the raw service object.
mService = IRemoteService.Stub.asInterface(service);
mKillButton.setEnabled(true);
mCallbackText.setText("Attached.");
// We want to monitor the service for as long as we are
// connected to it.
try {
mService.registerCallback(mCallback);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
// As part of the sample, tell the user what happened.
Toast.makeText(Binding.this, R.string.remote_service_connected,
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mKillButton.setEnabled(false);
mCallbackText.setText("Disconnected.");
// As part of the sample, tell the user what happened.
Toast.makeText(Binding.this, R.string.remote_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
/**
* Class for interacting with the secondary interface of the service.
*/
private ServiceConnection mSecondaryConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// Connecting to a secondary interface is the same as any
// other interface.
mSecondaryService = ISecondary.Stub.asInterface(service);
mKillButton.setEnabled(true);
}
public void onServiceDisconnected(ComponentName className) {
mSecondaryService = null;
mKillButton.setEnabled(false);
}
};
private OnClickListener mBindListener = new OnClickListener() {
public void onClick(View v) {
// Establish a couple connections with the service, binding
// by interface names. This allows other applications to be
// installed that replace the remote service by implementing
// the same interface.
bindService(new Intent(IRemoteService.class.getName()),
mConnection, Context.BIND_AUTO_CREATE);
bindService(new Intent(ISecondary.class.getName()),
mSecondaryConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
mCallbackText.setText("Binding.");
}
};
private OnClickListener mUnbindListener = new OnClickListener() {
public void onClick(View v) {
if (mIsBound) {
// If we have received the service, and hence registered with
// it, then now is the time to unregister.
if (mService != null) {
try {
mService.unregisterCallback(mCallback);
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
// Detach our existing connection.
unbindService(mConnection);
unbindService(mSecondaryConnection);
mKillButton.setEnabled(false);
mIsBound = false;
mCallbackText.setText("Unbinding.");
}
}
};
private OnClickListener mKillListener = new OnClickListener() {
public void onClick(View v) {
// To kill the process hosting our service, we need to know its
// PID. Conveniently our service has a call that will return
// to us that information.
if (mSecondaryService != null) {
try {
int pid = mSecondaryService.getPid();
// Note that, though this API allows us to request to
// kill any process based on its PID, the kernel will
// still impose standard restrictions on which PIDs you
// are actually able to kill. Typically this means only
// the process running your application and any additional
// processes created by that app as shown here; packages
// sharing a common UID will also be able to kill each
// other's processes.
Process.killProcess(pid);
mCallbackText.setText("Killed service process.");
} catch (RemoteException ex) {
// Recover gracefully from the process hosting the
// server dying.
// Just for purposes of the sample, put up a notification.
Toast.makeText(Binding.this,
R.string.remote_call_failed,
Toast.LENGTH_SHORT).show();
}
}
}
};
// ----------------------------------------------------------------------
// Code showing how to deal with callbacks.
// ----------------------------------------------------------------------
/**
* This implementation is used to receive callbacks from the remote
* service.
*/
private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
/**
* This is called by the remote service regularly to tell us about
* new values. Note that IPC calls are dispatched through a thread
* pool running in each process, so the code executing here will
* NOT be running in our main thread like most other things -- so,
* to update the UI, we need to use a Handler to hop over there.
*/
public void valueChanged(int value) {
mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
}
};
private static final int BUMP_MSG = 1;
private Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
case BUMP_MSG:
mCallbackText.setText("Received from service: " + msg.arg1);
break;
default:
super.handleMessage(msg);
}
}
};
}
// END_INCLUDE(calling_a_service)
} }

View File

@@ -1,241 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
import com.example.android.apis.R;
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.RemoteException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Process;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
// BEGIN_INCLUDE(exposing_a_service)
public class RemoteServiceBinding extends Activity {
/** The primary interface we will be calling on the service. */
IRemoteService mService = null;
/** Another interface we use on the service. */
ISecondary mSecondaryService = null;
Button mKillButton;
TextView mCallbackText;
private boolean mIsBound;
/**
* Standard initialization of this activity. Set up the UI, then wait
* for the user to poke it before doing anything.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_service_binding);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.bind);
button.setOnClickListener(mBindListener);
button = (Button)findViewById(R.id.unbind);
button.setOnClickListener(mUnbindListener);
mKillButton = (Button)findViewById(R.id.kill);
mKillButton.setOnClickListener(mKillListener);
mKillButton.setEnabled(false);
mCallbackText = (TextView)findViewById(R.id.callback);
mCallbackText.setText("Not attached.");
}
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. We are communicating with our
// service through an IDL interface, so get a client-side
// representation of that from the raw service object.
mService = IRemoteService.Stub.asInterface(service);
mKillButton.setEnabled(true);
mCallbackText.setText("Attached.");
// We want to monitor the service for as long as we are
// connected to it.
try {
mService.registerCallback(mCallback);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
// As part of the sample, tell the user what happened.
Toast.makeText(RemoteServiceBinding.this, R.string.remote_service_connected,
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mKillButton.setEnabled(false);
mCallbackText.setText("Disconnected.");
// As part of the sample, tell the user what happened.
Toast.makeText(RemoteServiceBinding.this, R.string.remote_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
/**
* Class for interacting with the secondary interface of the service.
*/
private ServiceConnection mSecondaryConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// Connecting to a secondary interface is the same as any
// other interface.
mSecondaryService = ISecondary.Stub.asInterface(service);
mKillButton.setEnabled(true);
}
public void onServiceDisconnected(ComponentName className) {
mSecondaryService = null;
mKillButton.setEnabled(false);
}
};
private OnClickListener mBindListener = new OnClickListener() {
public void onClick(View v) {
// Establish a couple connections with the service, binding
// by interface names. This allows other applications to be
// installed that replace the remote service by implementing
// the same interface.
bindService(new Intent(IRemoteService.class.getName()),
mConnection, Context.BIND_AUTO_CREATE);
bindService(new Intent(ISecondary.class.getName()),
mSecondaryConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
mCallbackText.setText("Binding.");
}
};
private OnClickListener mUnbindListener = new OnClickListener() {
public void onClick(View v) {
if (mIsBound) {
// If we have received the service, and hence registered with
// it, then now is the time to unregister.
if (mService != null) {
try {
mService.unregisterCallback(mCallback);
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
// Detach our existing connection.
unbindService(mConnection);
unbindService(mSecondaryConnection);
mKillButton.setEnabled(false);
mIsBound = false;
mCallbackText.setText("Unbinding.");
}
}
};
private OnClickListener mKillListener = new OnClickListener() {
public void onClick(View v) {
// To kill the process hosting our service, we need to know its
// PID. Conveniently our service has a call that will return
// to us that information.
if (mSecondaryService != null) {
try {
int pid = mSecondaryService.getPid();
// Note that, though this API allows us to request to
// kill any process based on its PID, the kernel will
// still impose standard restrictions on which PIDs you
// are actually able to kill. Typically this means only
// the process running your application and any additional
// processes created by that app as shown here; packages
// sharing a common UID will also be able to kill each
// other's processes.
Process.killProcess(pid);
mCallbackText.setText("Killed service process.");
} catch (RemoteException ex) {
// Recover gracefully from the process hosting the
// server dying.
// Just for purposes of the sample, put up a notification.
Toast.makeText(RemoteServiceBinding.this,
R.string.remote_call_failed,
Toast.LENGTH_SHORT).show();
}
}
}
};
// ----------------------------------------------------------------------
// Code showing how to deal with callbacks.
// ----------------------------------------------------------------------
/**
* This implementation is used to receive callbacks from the remote
* service.
*/
private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
/**
* This is called by the remote service regularly to tell us about
* new values. Note that IPC calls are dispatched through a thread
* pool running in each process, so the code executing here will
* NOT be running in our main thread like most other things -- so,
* to update the UI, we need to use a Handler to hop over there.
*/
public void valueChanged(int value) {
mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
}
};
private static final int BUMP_MSG = 1;
private Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
case BUMP_MSG:
mCallbackText.setText("Received from service: " + msg.arg1);
break;
default:
super.handleMessage(msg);
}
}
};
}
// END_INCLUDE(exposing_a_service)

View File

@@ -1,65 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
// Need the following import to get access to the app resources, since this
// class is in a sub-package.
import com.example.android.apis.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class RemoteServiceController extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_service_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start);
button.setOnClickListener(mStartListener);
button = (Button)findViewById(R.id.stop);
button.setOnClickListener(mStopListener);
}
private OnClickListener mStartListener = new OnClickListener() {
public void onClick(View v) {
// Make sure the service is started. It will continue running
// until someone calls stopService().
// We use an action code here, instead of explictly supplying
// the component name, so that other packages can replace
// the service.
startService(new Intent(
"com.example.android.apis.app.REMOTE_SERVICE"));
}
};
private OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
// Cancel a previous call to startService(). Note that the
// service will not actually stop at this point if there are
// still bound clients.
stopService(new Intent(
"com.example.android.apis.app.REMOTE_SERVICE"));
}
};
}

View File

@@ -16,6 +16,7 @@
package com.example.android.apis.app; package com.example.android.apis.app;
import android.app.Activity;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
@@ -29,13 +30,16 @@ import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.Process; import android.os.Process;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; import android.widget.Toast;
import com.example.android.apis.R; import com.example.android.apis.R;
/** /**
* This is an example of implementing an application service that runs locally * This is an example of implementing an application service that runs locally
* in the same process as the application. The {@link ServiceStartArgumentsController} * in the same process as the application. The {@link Controller}
* class shows how to interact with the service. * class shows how to interact with the service.
* *
* <p>Notice the use of the {@link NotificationManager} when interesting things * <p>Notice the use of the {@link NotificationManager} when interesting things
@@ -44,7 +48,7 @@ import com.example.android.apis.R;
* calling startActivity(). * calling startActivity().
* *
* <p>For applications targeting Android 1.5 or beyond, you may want consider * <p>For applications targeting Android 1.5 or beyond, you may want consider
* using the android.app.IntentService class, which takes care of all the * using the {@link android.app.IntentService} class, which takes care of all the
* work of creating the extra thread and dispatching commands to it. * work of creating the extra thread and dispatching commands to it.
*/ */
public class ServiceStartArguments extends Service { public class ServiceStartArguments extends Service {
@@ -59,8 +63,7 @@ public class ServiceStartArguments extends Service {
} }
@Override @Override
public void handleMessage(Message msg) public void handleMessage(Message msg) {
{
Bundle arguments = (Bundle)msg.obj; Bundle arguments = (Bundle)msg.obj;
String txt = arguments.getString("name"); String txt = arguments.getString("name");
@@ -105,7 +108,7 @@ public class ServiceStartArguments extends Service {
// This is who should be launched if the user selects our persistent // This is who should be launched if the user selects our persistent
// notification. // notification.
mInvokeIntent = new Intent(this, ServiceStartArgumentsController.class); mInvokeIntent = new Intent(this, Controller.class);
// Start up the thread running the service. Note that we create a // Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's // separate thread because the service normally runs in the process's
@@ -177,7 +180,7 @@ public class ServiceStartArguments extends Service {
// The PendingIntent to launch our activity if the user selects this notification // The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, AlarmService.class), 0); new Intent(this, Controller.class), 0);
// Set the info for the views that show in the notification panel. // Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.service_start_arguments_label), notification.setLatestEventInfo(this, getText(R.string.service_start_arguments_label),
@@ -194,5 +197,76 @@ public class ServiceStartArguments extends Service {
private void hideNotification() { private void hideNotification() {
mNM.cancel(R.string.service_created); mNM.cancel(R.string.service_created);
} }
// ----------------------------------------------------------------------
/**
* Example of explicitly starting the {@link ServiceStartArguments}.
*
* <p>Note that this is implemented as an inner class only keep the sample
* all together; typically this code would appear in some separate class.
*/
public static class Controller extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.service_start_arguments_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start1);
button.setOnClickListener(mStart1Listener);
button = (Button)findViewById(R.id.start2);
button.setOnClickListener(mStart2Listener);
button = (Button)findViewById(R.id.start3);
button.setOnClickListener(mStart3Listener);
button = (Button)findViewById(R.id.startfail);
button.setOnClickListener(mStartFailListener);
button = (Button)findViewById(R.id.kill);
button.setOnClickListener(mKillListener);
}
private OnClickListener mStart1Listener = new OnClickListener() {
public void onClick(View v) {
startService(new Intent(Controller.this,
ServiceStartArguments.class)
.putExtra("name", "One"));
}
};
private OnClickListener mStart2Listener = new OnClickListener() {
public void onClick(View v) {
startService(new Intent(Controller.this,
ServiceStartArguments.class)
.putExtra("name", "Two"));
}
};
private OnClickListener mStart3Listener = new OnClickListener() {
public void onClick(View v) {
startService(new Intent(Controller.this,
ServiceStartArguments.class)
.putExtra("name", "Three")
.putExtra("redeliver", true));
}
};
private OnClickListener mStartFailListener = new OnClickListener() {
public void onClick(View v) {
startService(new Intent(Controller.this,
ServiceStartArguments.class)
.putExtra("name", "Failure")
.putExtra("fail", true));
}
};
private OnClickListener mKillListener = new OnClickListener() {
public void onClick(View v) {
// This is to simulate the service being killed while it is
// running in the background.
Process.killProcess(Process.myPid());
}
};
}
} }

View File

@@ -1,95 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
// Need the following import to get access to the app resources, since this
// class is in a sub-package.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Process;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.example.android.apis.R;
/**
* Example of explicitly starting the {@link ServiceStartArguments}.
*/
public class ServiceStartArgumentsController extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.service_start_arguments_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start1);
button.setOnClickListener(mStart1Listener);
button = (Button)findViewById(R.id.start2);
button.setOnClickListener(mStart2Listener);
button = (Button)findViewById(R.id.start3);
button.setOnClickListener(mStart3Listener);
button = (Button)findViewById(R.id.startfail);
button.setOnClickListener(mStartFailListener);
button = (Button)findViewById(R.id.kill);
button.setOnClickListener(mKillListener);
}
private OnClickListener mStart1Listener = new OnClickListener() {
public void onClick(View v) {
startService(new Intent(ServiceStartArgumentsController.this,
ServiceStartArguments.class)
.putExtra("name", "One"));
}
};
private OnClickListener mStart2Listener = new OnClickListener() {
public void onClick(View v) {
startService(new Intent(ServiceStartArgumentsController.this,
ServiceStartArguments.class)
.putExtra("name", "Two"));
}
};
private OnClickListener mStart3Listener = new OnClickListener() {
public void onClick(View v) {
startService(new Intent(ServiceStartArgumentsController.this,
ServiceStartArguments.class)
.putExtra("name", "Three")
.putExtra("redeliver", true));
}
};
private OnClickListener mStartFailListener = new OnClickListener() {
public void onClick(View v) {
startService(new Intent(ServiceStartArgumentsController.this,
ServiceStartArguments.class)
.putExtra("name", "Failure")
.putExtra("fail", true));
}
};
private OnClickListener mKillListener = new OnClickListener() {
public void onClick(View v) {
// This is to simulate the service being killed while it is
// running in the background.
Process.killProcess(Process.myPid());
}
};
}

View File

@@ -41,55 +41,44 @@
<h3>Service</h3> <h3>Service</h3>
<dl> <dl>
<dt><a href="LocalServiceController.html">Local Service Controller</a></dt> <dt><a href="LocalService.html">Local Service Controller and
<dd>Starts and stops the service class Local Service Binding</a></dt>
<a href="LocalService.html">LocalService</a> that runs in the same <dd>Demonstrate the implementation of a service that runs in the same
process as the activity, to demonstrate a service's process as its client(s). Shows how those clients can either start/stop it
lifecycle when using {@link android.content.Context#startService with {@link android.content.Context#startService
Context.startService} and {@link android.content.Context#stopService Context.startService} and {@link android.content.Context#stopService
Context.stopService}.</dd> Context.stopService}, or bind and call it with
<dt><a href="LocalServiceBinding.html">Local Service Binding</a></dt>
<dd>Demonstrates binding to a service class
<a href="LocalService.html">LocalService</a> that runs in the same
process as the activity, to demonstrate using the
{@link android.content.Context#bindService Context.bindService} and {@link android.content.Context#bindService Context.bindService} and
{@link android.content.Context#unbindService Context.unindService} {@link android.content.Context#unbindService Context.unindService}.
methods with a service. This also shows how you can simplify working This also shows how you can simplify working
with a service when you know it will only run in your own process.</dd> with a service when you know it will only run in your own process.</dd>
<dt><a href="RemoteServiceController.html">Remote Service Controller</a></dt> <dt><a href="RemoteService.html">Remote Service Controller and
Remove Service Binding</a></dt>
<dd>Demonstrates starting a service in a separate process, by assigning <dd>Demonstrates starting a service in a separate process, by assigning
<code>android:process=&quot;:remote&quot;</code> to the service in the <code>android:process=&quot;:remote&quot;</code> to the service in the
AndroidManifest.xml file. </dd> AndroidManifest.xml file. Shows how those clients can either start/stop it
with {@link android.content.Context#startService
<dt><a href="RemoteServiceBinding.html">Remote Service Binding</a></dt> Context.startService} and {@link android.content.Context#stopService
<dd>Demonstrates binding to a remote service, similar to the Local Service Context.stopService}, or bind and call it with
Binding sample, but illustrating the additional work (defining aidl {@link android.content.Context#bindService Context.bindService} and
{@link android.content.Context#unbindService Context.unindService}.
Binding is similar to the local service sample,
but illustrates the additional work (defining aidl
interfaces) needed to interact with a service in another process. Also interfaces) needed to interact with a service in another process. Also
shows how a service can publish multiple interfaces and implement shows how a service can publish multiple interfaces and implement
callbacks to its clients.</dd> callbacks to its clients.</dd>
<dt><a href="ServiceStartArgumentsController.html">Service Start Arguments Controller</a></dt> <dt><a href="ServiceStartArguments.html">Service Start Arguments Controller</a></dt>
<dd>Demonstrates how you can use a Service as a job queue, where you <dd>Demonstrates how you can use a Service as a job queue, where you
submit jobs to it with {@link android.content.Context#startService submit jobs to it with {@link android.content.Context#startService
Context.startService} instead of binding to the service. Such a service Context.startService} instead of binding to the service. Such a service
automatically stops itself once all jobs have been processed. This can be automatically stops itself once all jobs have been processed. This can be
a very convenient way to interact with a service when you do not need a very convenient way to interact with a service when you do not need
a result back from it. a result back from it.</dd>
<dl>
<dt>Code:
<dd> <a href="ServiceStartArgumentsController.html">ServiceStartArgumentsController.java</a>
<dd> <a href="ServiceStartArguments.html">ServiceStartArguments.java</a>
<dt>Layout:
<dd> <a href="/guide/samples/ApiDemos/res/layout/service_start_arguments_controller.html">
service_start_arguments_controller.xml</a>
</dl>
</dd>
<dt><a href="ForegroundServiceController.html">Foreground Service Controller</a></dt> <dt><a href="ForegroundService.html">Foreground Service Controller</a></dt>
<dd>Controls the service class <dd>Shows how you
<a href="ForegroundService.html">ForegroundService</a>, which shows how you
can write a Service that runs in the foreground and works on both pre-2.0 can write a Service that runs in the foreground and works on both pre-2.0
and post-2.0 versions of the platform. This example will selectively use and post-2.0 versions of the platform. This example will selectively use
the new foreground APIs that were introduced in Android 2.0 if they are the new foreground APIs that were introduced in Android 2.0 if they are