我的 Android 应用程序上有一个后台服务,它可以获取我的 GPS 位置并将其发送到远程数据库。效果很好。
问题是当我想停止服务时......它不会停止:S。 logcat 上也没有出现异常或错误......它根本就不会停止。
这是启动我的服务的代码(带有按钮):
startService(new Intent(GPSLoc.this, MyService.class)); //enciendo el service
这是我停止它的代码(在 onactivityresult 方法上):
stopService(new Intent(GPSLoc.this, MyService.class));
我已经调试了应用程序,并且我检查了每次调试它时都调用了 stopService 代码行,但它并没有停止......
我确信它没有停止,因为当我按下按钮停止服务时,我的数据库仍然从模拟器接收 GPS 位置。
我做错了什么?
你实施了吗
onDestroy()
?如果没有,我相信这可能是解决方案 - 并且您停止 Timer
或您用来在 onDestroy()
内运行服务的任何内容。
可以通过调用 stopSelf() 方法或调用 Context.stopService() 来停止服务。
请参阅此链接了解更多信息。
我确信它没有停止,因为当我按下按钮停止服务时,我的数据库仍然从模拟器接收 GPS 位置。
您可能没有取消注册您的
LocationListener
。
我也有同样的问题。我发现,如果服务已连接
GoogleApiClient
并且仍然获得位置更新,则 stopService()
完全没有效果,不会调用该服务的 Industry() 。
为了解决这个问题,我在服务代码中创建了一个函数来停止定位服务。从活动中调用 stopLocationService()
,然后调用 stopService。这是代码示例:
public class myLocationService extends Service{
...
public void stopLocationUpdates() {
LocationService.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
mGoogleApiClient.disconnect();
}
...
}
活动中,
{
...
if(mService != null && isBound) {
mService.stopLocationUpdates();
doUnbindService();
stopService(new Intent(this, myLocationService.class));
}
...
}
这种情况很常见,我需要在完成该过程之前停止服务。在某些情况下,stopService(intent) 还不够。您应该记住我的服务中的 onDestroy() 实现。示例:
public class MyIntentService extends IntentService {
// Defines and instantiates an object for handling status updates.
private BroadcastNotifier mBroadcaster = null;
private int progress = 0; //THIS IS MY COUNTER FOR EXAMPLE!!!
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
progress = 0;
int tiempo_disponible = intent.getIntExtra("minutos_disponible", 0);
if (mBroadcaster == null){
mBroadcaster = new BroadcastNotifier(this);
}
// Broadcasts an Intent indicating that processing has started.
mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_STARTED);
mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_RUNNING);
while (progress < tiempo_disponible) {
progress++;
try {
Log.i(Constants.TAG, "Procesing " + progress);
mBroadcaster.notifyProgress(progress);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Reports that the feed retrieval is complete.
mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_COMPLETE);
}
@Override
public void onDestroy() {
progress = 1000000; // WHITH THAT YOU FINISH THE CICLE IF tiempo_disponible NEVER IS MAYOR THAT 1000000, YOU CAN USE OTHER CONDITIONAL!!!!!!
super.onDestroy();
}
}
这样,当您使用 stopService 方法停止服务时,您也将停止计数器的进程。
public void stopService(){
context.stopService(intent);
LocalBroadcastManager.getInstance(context).unregisterReceiver(responseReceiver);
responseReceiver = null;
intent = null;
}
保重! @yaircarreno
如果您正在跟踪 GPS 位置,您可能使用过
GoogleApiClient
。
这个概念是服务不会停止,
如果
GoogleApiClient
实例仍在其中连接。
(或者任何其他需要先销毁/取消注册的问题)
因此,要使其发挥作用,请在您的服务中实施
onDestroy()
:
@Override
public void onDestroy()
{
// Unregistered or disconnect what you need to
// For example: mGoogleApiClient.disconnect();
super.onDestroy();
}
我发现停止服务的最佳方法是停止服务本身。这样您就可以确定它实际上会停止并保持数据完整性。如果您想从外部(活动)执行此操作,我通常使用全局静态属性。
每个示例(Kotlin)如果我有
MyService
、MyActivity
和 MyObject
我的对象
object MyObject{
abort = false
}
我的服务
override fun onHandleIntent(intent: Intent?) {
startForeground(id,notification)
for (i in range){
if (MyObject.abort) break
// RUN SOME CODE HERE
}
stopForeground(true)
stopSelf()
}
我的活动
fun startService() {
startForegroundService(Intent(this, OptimizationService::class.java))
}
fun stopService() {
MyObject.abort = true
}
可能您每次调用停止服务时都会创建一个新的 Intent。
stopService(new Intent(GPSLoc.this, MyService.class));
也许尝试一下:
Intent intnet = new Intent(GPSLoc.this, MyService.class); // create el service
startService(intenet);
stopService(intent);
对于那些想要定期向服务器发送请求的人,这是我的解决方案。您应该在您的 Activity 或 Fragment Activity 中包含此内容
{
private static final Long UPDATE_LOCATION_TIME = 30 * 60 * 1000l; // 30 minute
private AlarmManager alarm;
private PendingIntent pIntent;
...
@Override
protected void onResume() {
super.onResume();
// Run background service in order to update users location
startUserLocationService();
Log.e(TAG, "onResume");
}
@Override
protected void onStop() {
super.onStop();
stopUserLocationService();
Log.e(TAG, "onStop");
}
private void startUserLocationService() {
Log.i(TAG, "Starting service...");
Intent intent = new Intent(MainFragmentHolder.this, ServiceUserLocation.class);
pIntent = PendingIntent.getService(this, 0, intent, 0);
alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), UPDATE_LOCATION_TIME, pIntent);
}
private void stopUserLocationService() {
alarm.cancel(pIntent);
Intent intent = new Intent(MainFragmentHolder.this, ServiceUserLocation.class);
stopService(intent);
}
}
我的问题通过删除添加的视图解决了
WindowManager
ondestroy
public void onDestroy() {
isRunning = false;
super.onDestroy();
if (checkBox!=null) {
windowManager.removeView(getlayoutparm(fabsetting,fabrateus,fabexit,true));
windowManager.removeView(checkBox);
}
}
在我的例子中,几乎同时调用
stopService
和 startService
,因此没有服务可以停止。尝试延迟 stopService
几秒钟。 :)
@覆盖
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.d(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
我在服务中使用语音识别时遇到了同样的问题。我什至在 Service.onDestroy 中调用了 this.stopSelf() ,但它也不起作用。调用 onDestroy 方法,但服务继续工作,就像什么也没发生一样。
通过在 Service.onDestroy 中添加 SpeechRecognizer.destroy() 解决了这个问题:
@Override
public void onDestroy() {
this.speechRecognizer.destroy ();
super.onDestroy ();
}
我的解释是 SpeechRecognizer 类使用到语音服务器的连接,并且关闭所有连接似乎在这里至关重要。