Location API mainly done

This commit is contained in:
mar-v-in 2015-01-19 01:46:08 +01:00
parent 6af3c0b700
commit a5be10d11b
8 changed files with 288 additions and 112 deletions

View File

@ -8,8 +8,8 @@ import com.google.android.gms.common.api.PendingResult;
import org.microg.gms.Constants; import org.microg.gms.Constants;
public interface FusedLocationProviderApi { public interface FusedLocationProviderApi {
String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION"; public static final String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION";
String KEY_MOCK_LOCATION = Constants.KEY_MOCK_LOCATION; public static final String KEY_MOCK_LOCATION = Constants.KEY_MOCK_LOCATION;
public Location getLastLocation(GoogleApiClient client); public Location getLastLocation(GoogleApiClient client);

View File

@ -1,78 +1,63 @@
package com.google.android.gms.location; package com.google.android.gms.location;
import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.location.Location;
import android.os.Looper;
import android.os.RemoteException;
import com.google.android.gms.common.GooglePlayServicesClient; import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import org.microg.gms.common.ForwardConnectionCallbacks; import org.microg.gms.common.ForwardConnectionCallbacks;
import org.microg.gms.common.ForwardConnectionFailedListener; import org.microg.gms.common.ForwardConnectionFailedListener;
import org.microg.gms.common.api.AbstractPlayServicesClient;
import org.microg.gms.common.api.GoogleApiClientImpl;
import org.microg.gms.location.LocationClientImpl;
@Deprecated @Deprecated
public class LocationClient implements GooglePlayServicesClient { public class LocationClient extends AbstractPlayServicesClient {
private GoogleApiClient googleApiClient; public static final String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION";
public LocationClient(Context context, ConnectionCallbacks callbacks) { public LocationClient(Context context, ConnectionCallbacks callbacks,
googleApiClient = new GoogleApiClient.Builder(context) OnConnectionFailedListener connectionFailedListener) {
super(new GoogleApiClient.Builder(context)
.addApi(LocationServices.API) .addApi(LocationServices.API)
.addConnectionCallbacks(new ForwardConnectionCallbacks(callbacks)) .addConnectionCallbacks(new ForwardConnectionCallbacks(callbacks))
.build(); .addOnConnectionFailedListener(new ForwardConnectionFailedListener(connectionFailedListener))
.build());
} }
@Override public Location getLastLocation() {
public void connect() { return LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
googleApiClient.connect();
} }
@Override public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener) {
public void disconnect() { return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener);
googleApiClient.disconnect();
} }
@Override public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener, Looper looper) {
public boolean isConnected() { return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener, looper);
return googleApiClient.isConnected();
} }
@Override public PendingResult requestLocationUpdates(LocationRequest request, PendingIntent callbackIntent) {
public boolean isConnecting() { return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, callbackIntent);
return googleApiClient.isConnecting();
} }
@Override public PendingResult removeLocationUpdates(LocationListener listener) {
public void registerConnectionCallbacks(final ConnectionCallbacks listener) { return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, listener);
googleApiClient.registerConnectionCallbacks(new ForwardConnectionCallbacks(listener));
} }
@Override public PendingResult removeLocationUpdates(PendingIntent callbackIntent) {
public boolean isConnectionCallbacksRegistered(ConnectionCallbacks listener) { return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, callbackIntent);
return googleApiClient
.isConnectionCallbacksRegistered(new ForwardConnectionCallbacks(listener));
} }
@Override public PendingResult setMockMode(boolean isMockMode) {
public void unregisterConnectionCallbacks( return LocationServices.FusedLocationApi.setMockMode(googleApiClient, isMockMode);
ConnectionCallbacks listener) {
googleApiClient.unregisterConnectionCallbacks(new ForwardConnectionCallbacks(listener));
} }
@Override public PendingResult setMockLocation(Location mockLocation) {
public void registerConnectionFailedListener( return LocationServices.FusedLocationApi.setMockLocation(googleApiClient, mockLocation);
OnConnectionFailedListener listener) {
googleApiClient.registerConnectionFailedListener(
new ForwardConnectionFailedListener(listener));
} }
@Override
public boolean isConnectionFailedListenerRegistered(
OnConnectionFailedListener listener) {
return googleApiClient.isConnectionFailedListenerRegistered(
new ForwardConnectionFailedListener(listener));
}
@Override
public void unregisterConnectionFailedListener(
OnConnectionFailedListener listener) {
googleApiClient.unregisterConnectionFailedListener(
new ForwardConnectionFailedListener(listener));
}
} }

View File

@ -1,4 +1,18 @@
package com.google.android.gms.location; package com.google.android.gms.location;
import android.location.Location;
/**
* Used for receiving notifications from the {@link FusedLocationProviderApi} when the location has
* changed. The methods are called if the LocationListener has been registered with the location
* client.
*/
public interface LocationListener { public interface LocationListener {
/**
* Called when the location has changed.
*
* @param location The updated location.
*/
public void onLocationChanged(Location location);
} }

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2014-2015 µg Project Team
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<integer name="google_play_services_version">6599436</integer>
</resources>

View File

@ -30,14 +30,24 @@ import com.google.android.gms.common.api.Result;
import org.microg.gms.common.api.GoogleApiClientImpl; import org.microg.gms.common.api.GoogleApiClientImpl;
public class GmsConnector { public class GmsConnector<C extends ApiConnection, R extends Result, O extends Api.ApiOptions> {
public static <C extends ApiConnection, R extends Result, O extends Api.ApiOptions> private final GoogleApiClientImpl apiClient;
AbstractPendingResult<R> connect(GoogleApiClient apiClient, Api<O> api, Callback<C, R> callback) { private final Api<O> api;
private final Callback<C, R> callback;
public GmsConnector(GoogleApiClient apiClient, Api<O> api, Callback<C, R> callback) {
this.apiClient = (GoogleApiClientImpl) apiClient;
this.api = api;
this.callback = callback;
}
public AbstractPendingResult<R> connect() {
Looper looper = ((GoogleApiClientImpl) apiClient).getLooper(); Looper looper = ((GoogleApiClientImpl) apiClient).getLooper();
final AbstractPendingResult<R> result = new AbstractPendingResult<>(looper); final AbstractPendingResult<R> result = new AbstractPendingResult<>(looper);
Message msg = new Message(); Message msg = new Message();
msg.obj = new ConnectRequest<C, R, O>((GoogleApiClientImpl) apiClient, api, result, callback); msg.obj = result;
new Handler<C, R, O>(looper).sendMessage(msg); new Handler(looper).sendMessage(msg);
return result; return result;
} }
@ -45,35 +55,21 @@ public class GmsConnector {
public R onClientAvailable(C client) throws RemoteException; public R onClientAvailable(C client) throws RemoteException;
} }
private static class Handler<C extends ApiConnection, R extends Result, O extends Api.ApiOptions> extends android.os.Handler { private class Handler extends android.os.Handler {
private Handler(Looper looper) { private Handler(Looper looper) {
super(looper); super(looper);
} }
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
ConnectRequest<C, R, O> request = (ConnectRequest<C, R, O>) msg.obj; AbstractPendingResult<R> result = (AbstractPendingResult<R>) msg.obj;
ApiConnection apiConnection = request.apiClient.getApiConnection(request.api); ApiConnection apiConnection = apiClient.getApiConnection(api);
apiConnection.connect(); apiConnection.connect();
try { try {
request.result.setResult(request.callback.onClientAvailable((C) apiConnection)); result.setResult(callback.onClientAvailable((C) apiConnection));
} catch (RemoteException ignored) { } catch (RemoteException ignored) {
} }
} }
} }
private static class ConnectRequest<C extends ApiConnection, R extends Result, O extends Api.ApiOptions> {
GoogleApiClientImpl apiClient;
Api<O> api;
AbstractPendingResult<R> result;
Callback<C, R> callback;
private ConnectRequest(GoogleApiClientImpl apiClient, Api<O> api, AbstractPendingResult<R> result, Callback<C, R> callback) {
this.apiClient = apiClient;
this.api = api;
this.result = result;
this.callback = callback;
}
}
} }

View File

@ -0,0 +1,90 @@
/*
* Copyright 2014-2015 µg Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.common.api;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.api.GoogleApiClient;
import org.microg.gms.common.ForwardConnectionCallbacks;
import org.microg.gms.common.ForwardConnectionFailedListener;
public class AbstractPlayServicesClient implements GooglePlayServicesClient {
protected final GoogleApiClient googleApiClient;
public AbstractPlayServicesClient(GoogleApiClient googleApiClient) {
this.googleApiClient = googleApiClient;
}
@Override
public void connect() {
googleApiClient.connect();
}
@Override
public void disconnect() {
googleApiClient.disconnect();
}
@Override
public boolean isConnected() {
return googleApiClient.isConnected();
}
@Override
public boolean isConnecting() {
return googleApiClient.isConnecting();
}
@Override
public void registerConnectionCallbacks(final ConnectionCallbacks listener) {
googleApiClient.registerConnectionCallbacks(new ForwardConnectionCallbacks(listener));
}
@Override
public boolean isConnectionCallbacksRegistered(ConnectionCallbacks listener) {
return googleApiClient
.isConnectionCallbacksRegistered(new ForwardConnectionCallbacks(listener));
}
@Override
public void unregisterConnectionCallbacks(
ConnectionCallbacks listener) {
googleApiClient.unregisterConnectionCallbacks(new ForwardConnectionCallbacks(listener));
}
@Override
public void registerConnectionFailedListener(
OnConnectionFailedListener listener) {
googleApiClient.registerConnectionFailedListener(
new ForwardConnectionFailedListener(listener));
}
@Override
public boolean isConnectionFailedListenerRegistered(
OnConnectionFailedListener listener) {
return googleApiClient.isConnectionFailedListenerRegistered(
new ForwardConnectionFailedListener(listener));
}
@Override
public void unregisterConnectionFailedListener(
OnConnectionFailedListener listener) {
googleApiClient.unregisterConnectionFailedListener(
new ForwardConnectionFailedListener(listener));
}
}

View File

@ -5,17 +5,22 @@ import android.location.Location;
import android.os.Looper; import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Result;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.FusedLocationProviderApi; import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import org.microg.gms.common.GmsConnector; import org.microg.gms.common.GmsConnector;
import org.microg.gms.common.api.ApiConnection;
public class FusedLocationProviderApiImpl implements FusedLocationProviderApi { public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
private static final String TAG = "GmsFusedApiImpl"; private static final String TAG = "GmsFusedApiImpl";
@Override @Override
public Location getLastLocation(GoogleApiClient client) { public Location getLastLocation(GoogleApiClient client) {
try { try {
@ -27,49 +32,98 @@ public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
} }
@Override @Override
public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request, public PendingResult requestLocationUpdates(GoogleApiClient client,
LocationListener listener) { final LocationRequest request,
final LocationListener listener) {
//LocationClientImpl.get(client).requestLocationUpdates(request, listener); return callVoid(client, new Runnable() {
return null; @Override
public void run(LocationClientImpl client) throws RemoteException {
client.requestLocationUpdates(request, listener);
}
});
} }
@Override @Override
public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request, public PendingResult requestLocationUpdates(GoogleApiClient client,
LocationListener listener, Looper looper) { final LocationRequest request,
//LocationClientImpl.get(client).requestLocationUpdates(request, listener, looper); final LocationListener listener,
return null; final Looper looper) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
client.requestLocationUpdates(request, listener, looper);
}
});
} }
@Override @Override
public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request, public PendingResult requestLocationUpdates(GoogleApiClient client,
PendingIntent callbackIntent) { final LocationRequest request,
//LocationClientImpl.get(client).requestLocationUpdates(request, callbackIntent); final PendingIntent callbackIntent) {
return null; return callVoid(client, new Runnable() {
} @Override
public void run(LocationClientImpl client) throws RemoteException {
@Override client.requestLocationUpdates(request, callbackIntent);
public PendingResult removeLocationUpdates(GoogleApiClient client, LocationListener listener) { }
//LocationClientImpl.get(client).removeLocationUpdates(listener); });
return null;
} }
@Override @Override
public PendingResult removeLocationUpdates(GoogleApiClient client, public PendingResult removeLocationUpdates(GoogleApiClient client,
PendingIntent callbackIntent) { final LocationListener listener) {
//LocationClientImpl.get(client).removeLocationUpdates(callbackIntent); return callVoid(client, new Runnable() {
return null; @Override
public void run(LocationClientImpl client) throws RemoteException {
client.removeLocationUpdates(listener);
}
});
} }
@Override @Override
public PendingResult setMockMode(GoogleApiClient client, boolean isMockMode) { public PendingResult removeLocationUpdates(GoogleApiClient client,
//LocationClientImpl.get(client).setMockMode(isMockMode); final PendingIntent callbackIntent) {
return null; return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
client.removeLocationUpdates(callbackIntent);
}
});
} }
@Override @Override
public PendingResult setMockLocation(GoogleApiClient client, Location mockLocation) { public PendingResult setMockMode(GoogleApiClient client, final boolean isMockMode) {
//LocationClientImpl.get(client).setMockLocation(mockLocation); return callVoid(client, new Runnable() {
return null; @Override
public void run(LocationClientImpl client) throws RemoteException {
client.setMockMode(isMockMode);
}
});
} }
@Override
public PendingResult setMockLocation(GoogleApiClient client, final Location mockLocation) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
client.setMockLocation(mockLocation);
}
});
}
private PendingResult callVoid(GoogleApiClient client, final Runnable runnable) {
return new GmsConnector<>(client, LocationServices.API,
new GmsConnector.Callback<LocationClientImpl, Result>() {
@Override
public Result onClientAvailable(LocationClientImpl client) throws
RemoteException {
runnable.run(client);
return Status.SUCCESS;
}
}).connect();
}
private interface Runnable {
public void run(LocationClientImpl client) throws RemoteException;
}
} }

View File

@ -5,12 +5,18 @@ import android.content.Context;
import android.location.Location; import android.location.Location;
import android.os.Looper; import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.ILocationListener;
import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.LocationServices;
import org.microg.gms.common.api.GoogleApiClientImpl; import org.microg.gms.common.api.GoogleApiClientImpl;
import java.util.HashMap;
import java.util.Map;
public class LocationClientImpl extends GoogleLocationManagerClient { public class LocationClientImpl extends GoogleLocationManagerClient {
public LocationClientImpl(Context context) { public LocationClientImpl(Context context) {
super(context); super(context);
@ -24,38 +30,49 @@ public class LocationClientImpl extends GoogleLocationManagerClient {
return null; return null;
} }
private Map<LocationListener, ILocationListener> listenerMap = new HashMap<>();
public Location getLastLocation() throws RemoteException { public Location getLastLocation() throws RemoteException {
return getServiceInterface().getLastLocation(); return getServiceInterface().getLastLocation();
} }
public void requestLocationUpdates(LocationRequest request, LocationListener listener) public void requestLocationUpdates(LocationRequest request, final LocationListener listener)
throws RemoteException { throws RemoteException {
ILocationListener iLocationListener = new ILocationListener.Stub() {
@Override
public void onLocationChanged(Location location) throws RemoteException {
listener.onLocationChanged(location);
}
};
listenerMap.put(listener, iLocationListener);
getServiceInterface().requestLocationUpdatesWithPackage(request,
iLocationListener, getContext().getPackageName());
} }
public void requestLocationUpdates(LocationRequest request, PendingIntent pendingIntent) public void requestLocationUpdates(LocationRequest request, PendingIntent pendingIntent)
throws RemoteException { throws RemoteException {
getServiceInterface().requestLocationUpdatesWithIntent(request, pendingIntent);
} }
public void requestLocationUpdates(LocationRequest request, LocationListener listener, public void requestLocationUpdates(LocationRequest request, LocationListener listener,
Looper looper) throws RemoteException { Looper looper) throws RemoteException {
requestLocationUpdates(request, listener); // TODO
} }
public void removeLocationUpdates(LocationListener listener) throws RemoteException { public void removeLocationUpdates(LocationListener listener) throws RemoteException {
getServiceInterface().removeLocationUpdatesWithListener(listenerMap.get(listener));
listenerMap.remove(listener);
} }
public void removeLocationUpdates(PendingIntent pendingIntent) throws RemoteException { public void removeLocationUpdates(PendingIntent pendingIntent) throws RemoteException {
getServiceInterface().removeLocationUpdatesWithIntent(pendingIntent);
} }
public void setMockMode(boolean isMockMode) throws RemoteException { public void setMockMode(boolean isMockMode) throws RemoteException {
getServiceInterface().setMockMode(isMockMode);
} }
public void setMockLocation(Location mockLocation) throws RemoteException { public void setMockLocation(Location mockLocation) throws RemoteException {
getServiceInterface().setMockLocation(mockLocation);
} }
} }