72

我创建了一项服务,并希望始终运行此服务,直到我的手机重新启动或强制关闭。该服务应在后台运行。

创建服务和启动服务的示例代码:

启动服务:

Intent service = new Intent(getApplicationContext(), MyService.class);
getApplicationContext().startService(service);

服务:

public class MyService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO do something useful
        HFLAG = true;
        //smsHandler.sendEmptyMessageDelayed(DISPLAY_DATA, 1000);
        return Service.START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO for communication return IBinder implementation
        return null;
    }
}

清单声明:

<service
    android:name=".MyService"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
</service>

是否可以在应用程序暂停和其他任何情况下始终运行此服务。一段时间后,我的应用程序暂停,服务也暂停或停止。那么我如何才能始终在后台运行此服务。

4

9 回答 9

93

“是否可以在应用程序暂停和其他任何情况下始终运行此服务?”

是的。

  1. 在服务的 onStartCommand 方法中返回 START_STICKY。

    public int onStartCommand(Intent intent, int flags, int startId) {
            return START_STICKY;
    }
    
  2. 使用 startService(MyService) 在后台启动服务,这样无论绑定客户端的数量如何,它都始终保持活动状态。

    Intent intent = new Intent(this, PowerMeterService.class);
    startService(intent);
    
  3. 创建活页夹。

    public class MyBinder extends Binder {
            public MyService getService() {
                    return MyService.this;
            }
    }
    
  4. 定义服务连接。

    private ServiceConnection m_serviceConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className, IBinder service) {
                    m_service = ((MyService.MyBinder)service).getService();
            }
    
            public void onServiceDisconnected(ComponentName className) {
                    m_service = null;
            }
    };
    
  5. 使用 bindService 绑定到服务。

            Intent intent = new Intent(this, MyService.class);
            bindService(intent, m_serviceConnection, BIND_AUTO_CREATE);
    
  6. 对于您的服务,您可能希望在关闭后启动相应活动的通知。

    private void addNotification() {
            // create the notification
            Notification.Builder m_notificationBuilder = new Notification.Builder(this)
                    .setContentTitle(getText(R.string.service_name))
                    .setContentText(getResources().getText(R.string.service_status_monitor))
                    .setSmallIcon(R.drawable.notification_small_icon);
    
            // create the pending intent and add to the notification
            Intent intent = new Intent(this, MyService.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
            m_notificationBuilder.setContentIntent(pendingIntent);
    
            // send the notification
            m_notificationManager.notify(NOTIFICATION_ID, m_notificationBuilder.build());
    }
    
  7. 您需要修改清单以在单顶模式下启动活动。

              android:launchMode="singleTop"
    
  8. 请注意,如果系统需要资源并且您的服务不是很活跃,它可能会被终止。如果这是不可接受的,则使用 startForeground 将服务带到前台。

            startForeground(NOTIFICATION_ID, m_notificationBuilder.build());
    
于 2013-04-02T23:00:54.373 回答
8

为了在自己的进程中启动服务,您必须在 xml 声明中指定以下内容。

<service
  android:name="WordService"
  android:process=":my_process" 
  android:icon="@drawable/icon"
  android:label="@string/service_name"
  >
</service> 

在这里你可以找到一个对我非常有用的好教程

http://www.vogella.com/articles/AndroidServices/article.html

希望这可以帮助

于 2013-04-02T08:22:22.343 回答
3

如果您已经有一项服务并希望它一直工作,您需要添加 2 件事:

  1. 在服务本身:

    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }
    
  2. 在清单中:

    android:launchMode="singleTop"
    

除非您在服务中需要它,否则无需添加绑定。

于 2016-11-20T04:45:07.700 回答
3

一个简单的解决方案是在系统停止服务时重新启动服务。

我发现这个方法的这个非常简单的实现:

如何使android服务不可阻挡

于 2016-07-15T16:05:28.287 回答
2

您可以startForeground为该服务实施,即使它死了,您也可以使用START_STICKYon重新启动它startCommand()。不确定这是不是正确的实现。

于 2013-04-02T08:25:01.500 回答
0

我找到了一种简单而清晰的方法来保持Service始终运行。

这家伙解释得很清楚,并且使用了一个很好的算法。他的方法是在服务即将被杀死时发送一个广播,然后使用它来重新启动服务。

你应该看看: http: //fabcirablog.weebly.com/blog/creating-a-never-ending-background-service-in-android

于 2017-03-01T07:35:26.270 回答
0

您不需要广播接收器。如果有人愿意从 Stephen Donecker 的上述示例中复制一个 api(serviceconnection) 并将其粘贴到谷歌中,你会得到这个,https: //www.concretepage.com/android/android-local-bound-service-带有绑定器和服务连接的示例

于 2018-10-27T09:06:47.833 回答
-1

将此添加到清单中。

      <service
        android:name=".YourServiceName"
        android:enabled="true"
        android:exported="false" />

添加服务类。

public class YourServiceName extends Service {


    @Override
    public void onCreate() {
        super.onCreate();

      // Timer task makes your service will repeat after every 20 Sec.
       TimerTask doAsynchronousTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                       // Add your code here.

                     }

               });
            }
        };
  //Starts after 20 sec and will repeat on every 20 sec of time interval.
        timer.schedule(doAsynchronousTask, 20000,20000);  // 20 sec timer 
                              (enter your own time)
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO do something useful

      return START_STICKY;
    }

}
于 2017-12-05T11:13:02.453 回答
-1

我已经克服了这个问题,我的示例代码如下。

在您的 Main Activity 中添加以下行,这里 BackGroundClass 是服务类。您可以在New -> JavaClass中创建此类(在此类中,添加您需要在后台发生的进程(任务))。为方便起见,先用通知铃声表示它们作为后台进程。

 startService(new Intent(this, BackGroundClass .class));

在 BackGroundClass 中,只需包含我的编码,您就可以看到结果。

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.widget.Toast;

public class BackgroundService  extends Service {
    private MediaPlayer player;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     player = MediaPlayer.create(this,Settings.System.DEFAULT_RINGTONE_URI);
        player.setLooping(true);
         player.start();
        return START_STICKY;
    }
 @Override
    public void onDestroy() {
        super.onDestroy();
         player.stop();
    }
}

在 AndroidManifest.xml 中,尝试添加这个。

<service android:name=".BackgroundService"/>

运行程序,只需打开应用程序,您可能会在后台找到通知警报。甚至,您可能会退出应用程序,但您仍然可能会听到铃声警报,除非您关闭应用程序或卸载应用程序。这表示通知警报处于后台进程。像这样,您可以为背景添加一些进程。

请注意:请不要使用 TOAST 进行验证,因为它只会运行一次,即使它处于后台进程。

希望它会有所帮助......!

于 2018-04-03T10:19:47.300 回答