Android服务需要始终运行(永远不要暂停或停止)


70

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

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

启动服务:

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>

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


1
不使其成为系统映像的一部分是不可能的。在某些情况下,Android可能会完全杀死您的应用程序。当您的应用程序被杀死时,其服务将无法运行。
StarPinkER

2
感谢您的答复,我如何使我的应用程序成为系统映像的一部分。
Ashekur Ra​​hman Molla Asik

您需要修改固件。如果可以接受,我可以写一个答案。
StarPinkER

您可以这样做..就像来电一样,请检查您的服务是否正在运行,如果没有,则再次启动它...以同样的方式使用媒体扫描器进行编译,引导执行,接收短信...等等。您必须检查每个服务运行的时间或与Watsup Massage服务不同。但是我不建议你这样做。有关更多详细信息,请检查:stackoverflow.com/a/6091362/1168654stackoverflow.com/a/4353653/1168654
Dhaval Parmar,

Answers:


92

“是否有可能始终在应用程序暂停或其他任何时候运行此服务?”

是。

  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());
    

一段时间后,此服务会自动使用此服务进入睡眠状态。
Ashekur Ra​​hman Molla Asik

1
一个很好的答案-效果很好。尽管这一问题已经完成,但对类似问题的许多其他答案还是局部的。
安德鲁·阿尔科克

23
您能否详细说明#8?这在哪里执行?关于#5,此操作是否与启动服务的位置相同?而且我是否正确理解您使用通知使服务始终处于活动状态的信息?
2014年

2
@Stephen Donecker为什么我必须绑定它?
Silvia H

2
@SilviaHisham你不知道。绑定通常在服务需要与活动进行通信时完成
蒂姆

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

希望这可以帮助


android:name =“ WordService”是MyService的意思
Ashekur Ra​​hman Molla Asik

1
是的,您可以使用自己的名字
Juan


@DhavalSodhaParmar那正是mi点我不明白你的意思
Juan

@Juan:这意味着您的服务在单独的线程中运行。这并不意味着您不能停止它。
Dhaval Parmar



2

如果您已经有了一项服务,并且希望它一直运行,那么您需要添加两件事:

  1. 在服务本身中:

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

    android:launchMode="singleTop"
    

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




-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;
    }

}

-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进行验证,因为即使处于后台进程中,它也只会运行一次。

希望对您有帮助... !!


没有上述代码
不起作用..onstartcommand

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.