【问题标题】:How to start a service again after the app has been minimized and then opened again?应用最小化再打开后如何重新启动服务?
【发布时间】:2018-10-24 10:49:40
【问题描述】:

我在使用 android 服务时遇到问题。当应用程序启动时它工作正常,但如果应用程序被最小化,并且服务被破坏,当我重新打开应用程序时,我无法再次启动服务。

这里是activity中的oncreate和onstart:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    //Activates the custom toolbar
    setSupportActionBar(toolbar);

    ActionBarDrawerToggle navigationDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(navigationDrawerToggle);
    navigationDrawerToggle.syncState();

    //Checks first item in the navigation drawer initially
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.setCheckedItem(R.id.fragment_camera);

    //Open camera fragment initially when the app starts.
    if (savedInstanceState == null) {
        fragmentInterface = new FotoapparatFragment();
        replaceFragment(fragmentInterface);
    }

    setupConnectionToService();

    Intent backgroundReceiptService = new Intent(this, ReceiptService.class);
    startService(backgroundReceiptService);
}

@Override
protected void onStart() {
    super.onStart();
    Intent intent = new Intent(this, ReceiptService.class);
    bindService(intent, receiptConnection, Context.BIND_AUTO_CREATE);
    Log.d(MAIN_LOG, "Binded With ReceiptService");
}

这里是服务中的onStartCommand:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    receiptDatabase = ReceiptDatabase.getInstance(getApplicationContext());

    //Checks if the permission to use external storage on the phone has been granted
    if (PermissionUtil.checkPermission(getApplicationContext(), PermissionUtil.Permissions.EXTERNAL_READ) == PackageManager.PERMISSION_GRANTED) {
        callLatestReceiptData(null);
        initializeFileObserver();
        listInitialized = true;
    }

    //TODO: Needs to moved elsewhere, but are not sure where
    new Thread(new Runnable() {
        @Override
        public void run() {
            Period period = new Period();
            period.setMPeriodId(1);
            receiptDatabase.daoAccessPeriod().insertNewPeriod(period);
        }
    }).start();

    return super.onStartCommand(intent, flags, startId);
}

【问题讨论】:

  • 这与重新启动应用程序有什么关系?最小化它与终止它不同
  • 不,但是当应用程序最小化足够长的时间时,服务中的 onDestroy 会被调用,然后当我从最小化状态打开应用程序时,我似乎无法再次启动服务

标签: java android service minimize


【解决方案1】:

使用服务连接。

playerIntent = new Intent(ActPlayMusic.this, MusicPlayerService.class);

                    startService(playerIntent);
                    bindService(playerIntent, mConnection, Context.BIND_AUTO_CREATE);


  private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {

            MusicPlayerService.LocalBinder binder = (MusicPlayerService.LocalBinder) service;
            try {
                playerService = binder.getServiceInstance();
                playerService.registerClient(ActPlayMusic.this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
    }
};




 @Override
    protected void onResume() {
          bindService(playerIntent, mConnection, Context.BIND_AUTO_CREATE);
        super.onResume();
    }
    @Override
    protected void onStop() {
        unbindService(mConnection);
        super.onStop();
    }

【讨论】:

  • 我已经这样做了,但是在应用程序被最小化并再次打开后,我的活动中的 onCreate 不会再次被调用,但是 onStart 是,但它在我正在使用 ServiceConnection 的 oncreate 中。
  • 更新:我可以通过调试看到,服务正在通过serviceConnection再次连接并且服务再次绑定,但服务中的onStartCommand从未被调用
【解决方案2】:

好的,所以在您的服务类中,您需要覆盖 onStartCommand() 并返回标志 START_STICKY 这应该重新启动您的服务。有关更多信息,请访问有关此服务主题的 Android 开发人员页面。

 @Override
 public int onStartCommand(Intent intent,int flags, int startId){
    return super.onStartCommand(intent,0,START_STICKY);

}

【讨论】:

    【解决方案3】:

    我想你想从后台启动服务,对吧?我已经使用这种方法来完成我的跟踪要求。

    您可以使用BroadcastReceiverService。在服务中的onStartCommand 上使用return Service.START_STICKY

    onDestroyonTaskRemoved 中,您可以编写如下发送开始广播接收器 [in kotlin]。

    override fun onTaskRemoved(rootIntent: Intent?) {
        super.onTaskRemoved(rootIntent)
        Log.e("Api service on Task Removed Send Location Service")
        if (Global.getPreference(Constant.IS_USER_LOGIN, false)!!) {
            val broadcastIntent = Intent("com.myapp.project.restartSendLocationService")
            sendBroadcast(broadcastIntent)
        }
    }
    

    在接收器中,您可以再次启动您的服务,如下 [in kotlin]。

    class SendLocationReceiver : BroadcastReceiver() {
    
    override fun onReceive(_context: Context?, intent: Intent?) {
        if (_context != null) {
            val context = _context.applicationContext
            val intentDemo = Intent(_context.applicationContext, SendLocationService::class.java)
            Log.e("Smart Sales", "UpdateLocationService \$status")
            try {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                    context.startService(intentDemo)
                } else {
                    context.startForegroundService(intentDemo)
                }
            } catch (e: Exception) {
                Log.e("Smart Sales", e.toString())
            }
        }
    }
    

    }

    不要忘记添加清单。

    <receiver
            android:name=".ServiceStuff.kotlin.SendLocationReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.myapp.project.restartSendLocationService" />
            </intent-filter>
        </receiver>
    

    注意:在某些自定义操作系统中,服务不会在后台运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-26
      • 2011-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      相关资源
      最近更新 更多