如何在 Android 中创建未绑定服务?
How do I create an unbound service in Android?
Android 上的许多服务示例和教程都是针对 bound services 的,但是如果我想创建一个未绑定的服务并且根本不必处理绑定怎么办?
潜在反对者请注意
请在投反对票前仔细阅读 answering your own questions is a good thing 的原因。
首先要做的是将服务添加到您的清单中,在 <application>
标签内:
<application ...>
...
<service
android:name=".RecordingService"
android:exported="false">
</application>
然后我们创建实际的服务class:
public class RecordingService extends Service {
private int NOTIFICATION = 1; // Unique identifier for our notification
public static boolean isRunning = false;
public static RecordingService instance = null;
private NotificationManager notificationManager = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate(){
instance = this;
isRunning = true;
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
// Set the info for the views that show in the notification panel.
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher) // the status icon
.setTicker("Service running...") // the status text
.setWhen(System.currentTimeMillis()) // the time stamp
.setContentTitle("My App") // the label of the entry
.setContentText("Service running...") // the content of the entry
.setContentIntent(contentIntent) // the intent to send when the entry is clicked
.setOngoing(true) // make persistent (disable swipe-away)
.build();
// Start service in foreground mode
startForeground(NOTIFICATION, notification);
return START_STICKY;
}
@Override
public void onDestroy(){
isRunning = false;
instance = null;
notificationManager.cancel(NOTIFICATION); // Remove notification
super.onDestroy();
}
public void doSomething(){
Toast.makeText(getApplicationContext(), "Doing stuff from service...", Toast.LENGTH_SHORT).show();
}
}
此服务所做的只是在 运行 时显示通知,并且在调用其 doSomething()
方法时可以显示 toasts。
如您所见,它是作为 singleton 实现的,跟踪它自己的实例 - 但没有通常的静态单例工厂方法,因为服务自然是单例并且是由意图创建的。当它是 运行.
时,该实例对于外部获取服务的 "handle" 很有用
最后,我们需要从 activity:
启动和停止服务
public void startOrStopService(){
if( RecordingService.isRunning ){
// Stop service
Intent intent = new Intent(this, RecordingService.class);
stopService(intent);
}
else {
// Start service
Intent intent = new Intent(this, RecordingService.class);
startService(intent);
}
}
在此示例中,服务根据其当前状态通过相同的方法启动和停止。
我们还可以从 activity:
中调用 doSomething()
方法
public void makeServiceDoSomething(){
if( RecordingService.isRunning )
RecordingService.instance.doSomething();
}
Android 上的许多服务示例和教程都是针对 bound services 的,但是如果我想创建一个未绑定的服务并且根本不必处理绑定怎么办?
潜在反对者请注意
请在投反对票前仔细阅读 answering your own questions is a good thing 的原因。
首先要做的是将服务添加到您的清单中,在 <application>
标签内:
<application ...>
...
<service
android:name=".RecordingService"
android:exported="false">
</application>
然后我们创建实际的服务class:
public class RecordingService extends Service {
private int NOTIFICATION = 1; // Unique identifier for our notification
public static boolean isRunning = false;
public static RecordingService instance = null;
private NotificationManager notificationManager = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate(){
instance = this;
isRunning = true;
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
// Set the info for the views that show in the notification panel.
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher) // the status icon
.setTicker("Service running...") // the status text
.setWhen(System.currentTimeMillis()) // the time stamp
.setContentTitle("My App") // the label of the entry
.setContentText("Service running...") // the content of the entry
.setContentIntent(contentIntent) // the intent to send when the entry is clicked
.setOngoing(true) // make persistent (disable swipe-away)
.build();
// Start service in foreground mode
startForeground(NOTIFICATION, notification);
return START_STICKY;
}
@Override
public void onDestroy(){
isRunning = false;
instance = null;
notificationManager.cancel(NOTIFICATION); // Remove notification
super.onDestroy();
}
public void doSomething(){
Toast.makeText(getApplicationContext(), "Doing stuff from service...", Toast.LENGTH_SHORT).show();
}
}
此服务所做的只是在 运行 时显示通知,并且在调用其 doSomething()
方法时可以显示 toasts。
如您所见,它是作为 singleton 实现的,跟踪它自己的实例 - 但没有通常的静态单例工厂方法,因为服务自然是单例并且是由意图创建的。当它是 运行.
时,该实例对于外部获取服务的 "handle" 很有用最后,我们需要从 activity:
启动和停止服务public void startOrStopService(){
if( RecordingService.isRunning ){
// Stop service
Intent intent = new Intent(this, RecordingService.class);
stopService(intent);
}
else {
// Start service
Intent intent = new Intent(this, RecordingService.class);
startService(intent);
}
}
在此示例中,服务根据其当前状态通过相同的方法启动和停止。
我们还可以从 activity:
中调用doSomething()
方法
public void makeServiceDoSomething(){
if( RecordingService.isRunning )
RecordingService.instance.doSomething();
}