我正在编写一个应用程序,其中单击按钮时主要活动应绑定到服务。该服务应获取 GPS 位置。每当调试时,我都会不断收到消息“不幸的是,应用程序已停止”...
这是 AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MyApp"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="23"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher">
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name=".Main"
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:name=".GPSLocation" android:label="GPS Location"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:enabled="true">
</service>
</application>
</manifest>
这是 Main.java:
public class Main extends Activity {
// UI elements
private static Context context;
private TextView lblLocation;
private Button btnStartService;
private Button btnShowLocation;
private Button btnGetClosestBusStop;
GPSLocation mService;
Location location;
boolean mBound = false;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lblLocation = (TextView) findViewById(R.id.lblLocation);
btnStartService = (Button) findViewById(R.id.btnStartService);
btnShowLocation = (Button) findViewById(R.id.btnShowLocation);
btnGetClosestBusStop = (Button) findViewById(R.id.btnGetClosestBusStop);
}
@Override
protected void onStart() {
super.onStart();
final Intent intent = new Intent(Main.this, GPSLocation.class);
btnStartService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// First we need to check availability of play services
if (checkPlayServices()) {
//getApplicationContext().bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
}
}
});
btnShowLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mBound) {
displayLocation();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
checkPlayServices();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
/**
* Method to verify google play services on the device
* */
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(getApplicationContext(),
"This device is not supported.", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
/**
* Method to display the location on UI
* */
private void displayLocation() {
location = mService.mLastLocation;
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
lblLocation.setText(latitude + ", " + longitude);
} else {
lblLocation.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
}
private ServiceConnection myConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder binder) {
GPSLocation.MyBinder bin = (GPSLocation.MyBinder) binder;
mService = bin.getService();
location = bin.getLocation();
mBound = true;
Log.d("ServiceConnection", "connected");
}
@Override
public void onServiceDisconnected(ComponentName className) {
Log.d("ServiceConnection","disconnected");
mBound = false;
}
};
}
这是 GPSLocation.java:
public class GPSLocation extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private static final String TAG = GPSLocation.class.getSimpleName();
private final IBinder mBinder = new MyBinder();
private Messenger outMessenger;
public Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;
private LocationRequest mLocationRequest;
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FATEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 10; // 10 meters
public class MyBinder extends Binder {
GPSLocation getService() {
return GPSLocation.this;
}
Location getLocation() {
return GPSLocation.this.mLastLocation;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate() {
// Building the Google API client
buildGoogleApiClient();
createLocationRequest();
togglePeriodicLocationUpdates();
}
/**
* Creating Google API client object
* */
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
/**
* Creating location request object
* */
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
/**
* Method to toggle periodic location updates
* */
public void togglePeriodicLocationUpdates() {
if (!mRequestingLocationUpdates) {
mRequestingLocationUpdates = true;
// Starting the location updates
startLocationUpdates();
Log.d(TAG, "Periodic location updates started!");
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
}
/**
* Starting the location updates
* */
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
/**
* Stopping location updates
*/
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
/**
* Google API callback methods
*/
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
@Override
public void onConnected(Bundle arg0) {
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
@Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
// Assign the new location
mLastLocation = location;
}
}
这是 logcat 消息:
11-17 03:44:58.157 29408-29408/com.WaitOrWalk E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.MyApp, PID: 29408
java.lang.RuntimeException: Unable to create service com.MyApp.GPSLocation: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2912)
at android.app.ActivityThread.access$1800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1455)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5696)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.internal.zzlh.zzb(Unknown Source)
at com.google.android.gms.internal.zzli.zzb(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at com.MyApp.GPSLocation.startLocationUpdates(GPSLocation.java:107)
at com.MyApp.GPSLocation.togglePeriodicLocationUpdates(GPSLocation.java:87)
at com.MyApp.GPSLocation.onCreate(GPSLocation.java:55)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2894)
at android.app.ActivityThread.access$1800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1455)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5696)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
我真的很感激一些帮助,被困了一段时间......应用程序崩溃了bindService(intent, myConnection, Context.BIND_AUTO_CREATE);