我有这个简单的服务,广播用户的当前位置。我想使用绑定机制来控制服务生命周期,但服务只是没有启动。
我做错了什么?
public class GPSActivity extends ListActivity {
...
protected void onResume() {
super.onResume();
Log.i("Service", "Service bound");
Intent intent = new Intent(this, LocationService.class);
bindService(intent, service_connection , Context.BIND_AUTO_CREATE);
}
protected void onPause() {
if (dataUpdateReceiver!=null)
unregisterReceiver(dataUpdateReceiver);
unbindService(service_connection);
super.onPause();
}
class LocationServiceConnection implements ServiceConnection{
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("Service", "Service Connected");
}
public void onServiceDisconnected(ComponentName name) {
}
}
}
LocalBinder.java
public class LocalBinder<S> extends Binder {
private String TAG = "LocalBinder";
private WeakReference<S> mService;
public LocalBinder(S service){
mService = new WeakReference<S>(service);
}
public S getService() {
return mService.get();
}
}
LocationService.java
public class LocationService extends Service {
public void onCreate() {
initLocationListener();
Log.i("Location Service","onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("Location Service", "Received start id " + startId + ": " + intent);
return START_NOT_STICKY;
}
private final IBinder mBinder = new LocalBinder<LocationService>(this);
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
AndroidManifest.xml
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
...
<service android:name=".LocationService">
</service>
</application>
编辑:感谢NickT的回答。
清单条目没有意图过滤器或正确的名称
<service
android:enabled="true"
android:name="com.android.gps.services.LocationService">
<intent-filter>
<action android:name="com.android.gps.services.LocationService" />
</intent-filter>
</service>
我用于绑定的意图就像你在开始活动时需要使用的那样。正确的是:
Intent intent = new Intent("com.android.gps.services.LocationService");
答案 0 :(得分:5)
onStartCommand只会在服务显式启动时执行,看起来你只想绑定它,这很好。我没有看到您已正确设置服务连接。我发布了我的存根程序,它显示了如何绑定到服务并通过绑定器调用服务中的方法。您可能希望运行此命令并查看各种日志消息的顺序。您显然需要添加BroadcastReceiver和onLocationChaged代码,以使其对您有用。
活动
package com.servtest.test;
import com.servtest.test.LocationService.LocalBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class ServiceTestActivity extends Activity {
boolean mServiceConnected = false;
boolean mBound = false;
private LocationService mLocnServ;
ServiceConnection mServconn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("SVTEST", "Activity service connected");
LocalBinder binder = (LocalBinder) service;
mLocnServ = binder.getService();
// Can't call this methodInTheService UNTIL IT'S BOUND!
mLocnServ.methodInTheService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("SVTEST", "Activity service disconnected");
mBound = false;
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public void onStart() {
super.onStart();
Log.d("SVTEST", "Activity onStart");
mServiceConnected = bindService(new Intent(
"com.servtest.test.LOCATIONSERVICE"), mServconn,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onResume() {
super.onResume();
Log.d("SVTEST", "Activity onResume");
}
@Override
public void onPause() {
Log.d("SVTEST", "Activity onPause");
super.onPause();
}
@Override
public void onStop() {
Log.d("SVTEST", "Activity onStop");
if (mBound) {
unbindService(mServconn);
mBound = false;
}
super.onStop();
}
}
服务
package com.servtest.test;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class LocationService extends Service implements LocationListener {
private final IBinder mBinder = new LocalBinder();
@Override
public void onLocationChanged(Location arg0) {}
@Override
public void onProviderDisabled(String arg0) {}
@Override
public void onProviderEnabled(String arg0) {}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
@Override
public IBinder onBind(Intent intent) {
Log.d("SVTEST", "Loc service ONBIND");
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.d("SVTEST", "Loc service ONUNBIND");
return super.onUnbind(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Won't run unless it's EXPLICITLY STARTED
Log.d("SVTEST", "Loc service ONSTARTCOMMAND");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("SVTEST", "Loc service ONDESTROY");
}
public class LocalBinder extends Binder {
LocationService getService() {
// Return this instance of LocalService so clients can call public methods
return LocationService.this;
}
}
public void methodInTheService() {
// A method you can call in the service
Log.d("SVTEST", "Loc service EXECUTING THE METHOD");
}
}
清单
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.servtest.test"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".ServiceTestActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:enabled="true"
android:name="LocationService">
<intent-filter>
<action android:name="com.servtest.test.LOCATIONSERVICE" />
</intent-filter>
</service>
</application>
</manifest>
希望这有帮助
答案 1 :(得分:0)
我有Activity
工具ServiceConnection
并且绑定如下:
bindService( new Intent( this, Service.class ), this, Context.BIND_AUTO_CREATE );
然后处理onServiceConnected()
onServiceDisconnected()
和Activity
的回调
答案 2 :(得分:0)
当您致电bindService
时,您可能会收到此错误:
ActivityManager java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.android.server.am.ActivityRecord$Token
检查logcat的输出。
这是Android的错误。
要解决此问题,请使用 getApplicationContext().bindService(...)