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;
public interface FusedLocationProviderApi {
String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION";
String KEY_MOCK_LOCATION = Constants.KEY_MOCK_LOCATION;
public static final String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION";
public static final String KEY_MOCK_LOCATION = Constants.KEY_MOCK_LOCATION;
public Location getLastLocation(GoogleApiClient client);

View File

@ -1,78 +1,63 @@
package com.google.android.gms.location;
import android.app.PendingIntent;
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.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import org.microg.gms.common.ForwardConnectionCallbacks;
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
public class LocationClient implements GooglePlayServicesClient {
private GoogleApiClient googleApiClient;
public class LocationClient extends AbstractPlayServicesClient {
public static final String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION";
public LocationClient(Context context, ConnectionCallbacks callbacks) {
googleApiClient = new GoogleApiClient.Builder(context)
public LocationClient(Context context, ConnectionCallbacks callbacks,
OnConnectionFailedListener connectionFailedListener) {
super(new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(new ForwardConnectionCallbacks(callbacks))
.build();
.addOnConnectionFailedListener(new ForwardConnectionFailedListener(connectionFailedListener))
.build());
}
@Override
public void connect() {
googleApiClient.connect();
public Location getLastLocation() {
return LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
}
@Override
public void disconnect() {
googleApiClient.disconnect();
public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener);
}
@Override
public boolean isConnected() {
return googleApiClient.isConnected();
public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener, Looper looper) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener, looper);
}
@Override
public boolean isConnecting() {
return googleApiClient.isConnecting();
public PendingResult requestLocationUpdates(LocationRequest request, PendingIntent callbackIntent) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, callbackIntent);
}
@Override
public void registerConnectionCallbacks(final ConnectionCallbacks listener) {
googleApiClient.registerConnectionCallbacks(new ForwardConnectionCallbacks(listener));
public PendingResult removeLocationUpdates(LocationListener listener) {
return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, listener);
}
@Override
public boolean isConnectionCallbacksRegistered(ConnectionCallbacks listener) {
return googleApiClient
.isConnectionCallbacksRegistered(new ForwardConnectionCallbacks(listener));
public PendingResult removeLocationUpdates(PendingIntent callbackIntent) {
return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, callbackIntent);
}
@Override
public void unregisterConnectionCallbacks(
ConnectionCallbacks listener) {
googleApiClient.unregisterConnectionCallbacks(new ForwardConnectionCallbacks(listener));
public PendingResult setMockMode(boolean isMockMode) {
return LocationServices.FusedLocationApi.setMockMode(googleApiClient, isMockMode);
}
@Override
public void registerConnectionFailedListener(
OnConnectionFailedListener listener) {
googleApiClient.registerConnectionFailedListener(
new ForwardConnectionFailedListener(listener));
public PendingResult setMockLocation(Location mockLocation) {
return LocationServices.FusedLocationApi.setMockLocation(googleApiClient, mockLocation);
}
@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;
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 {
/**
* 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;
public class GmsConnector {
public static <C extends ApiConnection, R extends Result, O extends Api.ApiOptions>
AbstractPendingResult<R> connect(GoogleApiClient apiClient, Api<O> api, Callback<C, R> callback) {
public class GmsConnector<C extends ApiConnection, R extends Result, O extends Api.ApiOptions> {
private final GoogleApiClientImpl apiClient;
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();
final AbstractPendingResult<R> result = new AbstractPendingResult<>(looper);
Message msg = new Message();
msg.obj = new ConnectRequest<C, R, O>((GoogleApiClientImpl) apiClient, api, result, callback);
new Handler<C, R, O>(looper).sendMessage(msg);
msg.obj = result;
new Handler(looper).sendMessage(msg);
return result;
}
@ -45,35 +55,21 @@ public class GmsConnector {
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) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
ConnectRequest<C, R, O> request = (ConnectRequest<C, R, O>) msg.obj;
ApiConnection apiConnection = request.apiClient.getApiConnection(request.api);
AbstractPendingResult<R> result = (AbstractPendingResult<R>) msg.obj;
ApiConnection apiConnection = apiClient.getApiConnection(api);
apiConnection.connect();
try {
request.result.setResult(request.callback.onClientAvailable((C) apiConnection));
result.setResult(callback.onClientAvailable((C) apiConnection));
} 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,13 +5,18 @@ import android.location.Location;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.common.api.GoogleApiClient;
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.LocationListener;
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.api.ApiConnection;
public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
private static final String TAG = "GmsFusedApiImpl";
@ -27,49 +32,98 @@ public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
}
@Override
public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request,
LocationListener listener) {
//LocationClientImpl.get(client).requestLocationUpdates(request, listener);
return null;
public PendingResult requestLocationUpdates(GoogleApiClient client,
final LocationRequest request,
final LocationListener listener) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
client.requestLocationUpdates(request, listener);
}
});
}
@Override
public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request,
LocationListener listener, Looper looper) {
//LocationClientImpl.get(client).requestLocationUpdates(request, listener, looper);
return null;
public PendingResult requestLocationUpdates(GoogleApiClient client,
final LocationRequest request,
final LocationListener listener,
final Looper looper) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
client.requestLocationUpdates(request, listener, looper);
}
});
}
@Override
public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request,
PendingIntent callbackIntent) {
//LocationClientImpl.get(client).requestLocationUpdates(request, callbackIntent);
return null;
}
public PendingResult requestLocationUpdates(GoogleApiClient client,
final LocationRequest request,
final PendingIntent callbackIntent) {
return callVoid(client, new Runnable() {
@Override
public PendingResult removeLocationUpdates(GoogleApiClient client, LocationListener listener) {
//LocationClientImpl.get(client).removeLocationUpdates(listener);
return null;
public void run(LocationClientImpl client) throws RemoteException {
client.requestLocationUpdates(request, callbackIntent);
}
});
}
@Override
public PendingResult removeLocationUpdates(GoogleApiClient client,
PendingIntent callbackIntent) {
//LocationClientImpl.get(client).removeLocationUpdates(callbackIntent);
return null;
final LocationListener listener) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
client.removeLocationUpdates(listener);
}
});
}
@Override
public PendingResult setMockMode(GoogleApiClient client, boolean isMockMode) {
//LocationClientImpl.get(client).setMockMode(isMockMode);
return null;
public PendingResult removeLocationUpdates(GoogleApiClient client,
final PendingIntent callbackIntent) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
client.removeLocationUpdates(callbackIntent);
}
});
}
@Override
public PendingResult setMockLocation(GoogleApiClient client, Location mockLocation) {
//LocationClientImpl.get(client).setMockLocation(mockLocation);
return null;
public PendingResult setMockMode(GoogleApiClient client, final boolean isMockMode) {
return callVoid(client, new Runnable() {
@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.os.Looper;
import android.os.RemoteException;
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.LocationRequest;
import com.google.android.gms.location.LocationServices;
import org.microg.gms.common.api.GoogleApiClientImpl;
import java.util.HashMap;
import java.util.Map;
public class LocationClientImpl extends GoogleLocationManagerClient {
public LocationClientImpl(Context context) {
super(context);
@ -24,38 +30,49 @@ public class LocationClientImpl extends GoogleLocationManagerClient {
return null;
}
private Map<LocationListener, ILocationListener> listenerMap = new HashMap<>();
public Location getLastLocation() throws RemoteException {
return getServiceInterface().getLastLocation();
}
public void requestLocationUpdates(LocationRequest request, LocationListener listener)
public void requestLocationUpdates(LocationRequest request, final LocationListener listener)
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)
throws RemoteException {
getServiceInterface().requestLocationUpdatesWithIntent(request, pendingIntent);
}
public void requestLocationUpdates(LocationRequest request, LocationListener listener,
Looper looper) throws RemoteException {
requestLocationUpdates(request, listener); // TODO
}
public void removeLocationUpdates(LocationListener listener) throws RemoteException {
getServiceInterface().removeLocationUpdatesWithListener(listenerMap.get(listener));
listenerMap.remove(listener);
}
public void removeLocationUpdates(PendingIntent pendingIntent) throws RemoteException {
getServiceInterface().removeLocationUpdatesWithIntent(pendingIntent);
}
public void setMockMode(boolean isMockMode) throws RemoteException {
getServiceInterface().setMockMode(isMockMode);
}
public void setMockLocation(Location mockLocation) throws RemoteException {
getServiceInterface().setMockLocation(mockLocation);
}
}