简体   繁体   English

以接受的用户权限启动我的Android服务

[英]Start my Android service with accepted user permissions

I have a little specific issue and I want some tips for that. 我有一个具体的问题,我想要一些提示。 I need to start just one time an Android service, and I can use these 2 options: 我只需要启动一次Android服务,就可以使用以下两个选项:

  1. Start the service from the onCreate() method of the MainActivity . MainActivityonCreate()方法启动服务。 The problem with this way is when the device is rotated with my app running, the onCreate() method is called again, because the MainActivity is restarted and I don't want that my service restarted because of this. 这种方式的问题是,当设备在运行我的应用程序的情况下旋转时,再次调用onCreate()方法,因为MainActivity已重新启动,因此我不希望我的服务重新启动。
  2. Start it from the Android Application class . 从Android Application 启动它。 The problem is that before start the service, I need to check if some permissions was accepted by the user. 问题是在启动服务之前,我需要检查用户是否接受了某些权限。 So the first time that my application is started in the Application class the permissions are not accepted yet. 因此,第一次在Application 类中启动我的应用程序时,该权限尚未被接受。

Reading this article Handle configuration changes I can see that is possible avoid the restart of my MainActivity but I don't know if this is a good practice. 阅读本文处理配置更改我可以看到有可能避免重新启动MainActivity但是我不知道这是否是一个好习惯。 So maybe exist some way to request user permissions from the Application 因此,可能存在一些从Application请求用户权限的方法

  1. onCreate with be called once during Service lifecycle, but onStartCommand will be called every time you call startService onCreate用在服务生命周期被调用一次,但onStartCommand将被调用每次调用时startService

  2. You can't request user permission outside Activity context. 您无法在Activity上下文之外请求用户权限。 So, you can run service but you are unable to do something that requires permission. 因此,您可以运行服务,但无法执行需要许可的操作。 You may register BroadcastReceiver inside your service for catching some "permission granted" intents. 您可以在服务内部注册BroadcastReceiver,以捕获某些“许可授予”意图。 But this intent should be created and sended to service via broadcast in Activity context at the moment when user grants permission. 但是,应在用户授予权限时创建此意图,并通过在Activity上下文中进行广播将其发送给服务。 Or you may use service commands instead 或者您可以改用服务命令

To prevent restarting your service just check in your MainActivity onCreate method is your service running 为了防止重新启动服务,只需检查MainActivity onCreate方法是否正在运行服务即可

Function for checking service running: 检查服务运行的功能:

private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

And after that you just need to call it in your onCreate method: 之后,您只需要在onCreate方法中调用它即可:

@Override
public void onCreate(Bundle savedInstanceState) {
if(!isMyServiceRunning(MyService.class)) {
   //start your service
}
}

I am not sure the reason why you would like to start the service only once but I am gonna try to suggest an alternative to achieve this. 我不确定您为什么只希望启动该服务的原因,但是我将尝试建议实现此目的的替代方法。

  1. Since you would like to ask for a user's permissions, the service cannot be started in the application class. 由于您想请求用户的权限,因此无法在应用程序类中启动该服务。 So the only place you can start it is in the activity class. 因此,您可以启动的唯一位置是活动类。 The key to solve this will be the onCreate and onStartCommand methods. 解决此问题的关键是onCreateonStartCommand方法。 If you define the service in the manifest file and then call Context.startService(context) multiple times, onCreate will be called only once as long as the system has not killed the service yet. 如果您在清单文件中定义服务,然后多次调用Context.startService(context) ,则只要系统尚未终止该服务, onCreate将仅被调用一次。 onStartCommand will be called every time you call Context.startService(context) . 每次调用Context.startService(context)时都会调用onStartCommand

Hence in this approach, write the block of code that you need to be executed once in the onCreate method. 因此,在这种方法中,请在onCreate方法中编写一次需要执行的代码块。 For all updates, execute them in the onStartCommand method. 对于所有更新,请在onStartCommand方法中执行它们。

  1. Another option would be to dig deeper into android architecture components (LiveData, LifeCycle and observers) 另一个选择是更深入地研究android体系结构组件(LiveData,LifeCycle和观察者)

I think the best way to deal with android's infamous rotation is to use ViewModel . 我认为处理android臭名昭著的旋转的最好方法是使用ViewModel As ViewModel survives device's rotation you can store a liveData of boolean initially set to true and observe it in onCreate() . ViewModel设备旋转后仍可生存时,您可以存储一个初始设置为trueboolean liveData ,并在onCreate()观察。 Start the service only if the observed value is true and set it to false once you have started the service. 仅当观察值是true时才启动服务,并在启动服务后将其设置为false Please see the following example, 请参见以下示例,

In ViewModel ViewModel中

val startService = MutableLiveData<Boolean>(true)

In Activity 's onCreate() ActivityonCreate()

viewModel.startService.observe(this, Observer {
        if (it) {
            startService()
            viewModel.startService.value = false
        }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM