Basic Location API working.

Tested using deprecated LocationClient calls in DashClock
This commit is contained in:
mar-v-in 2015-01-22 03:07:09 +01:00
parent 745a1d0fef
commit 863c9693ac
20 changed files with 128 additions and 62 deletions

View File

@ -4,6 +4,7 @@ import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentSender;
import com.google.android.gms.common.api.GoogleApiClient;
/**

View File

@ -7,6 +7,8 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.util.Log;
import org.microg.gms.Constants;
/**
@ -17,6 +19,8 @@ import org.microg.gms.Constants;
* TODO: methods :)
*/
public class GooglePlayServicesUtil {
private static final String TAG = "GooglePlayServicesUtil";
public static final String GMS_ERROR_DIALOG = "GooglePlayServicesErrorDialog";
public static final String GOOGLE_PLAY_SERVICES_PACKAGE = "com.google.android.gms";
public static final int GOOGLE_PLAY_SERVICES_VERSION_CODE = Constants.MAX_REFERENCE_VERSION;
@ -27,12 +31,12 @@ public class GooglePlayServicesUtil {
}
public static Dialog getErrorDialog(int errorCode, Activity activity, int requestCode,
DialogInterface.OnCancelListener cancelListener) {
DialogInterface.OnCancelListener cancelListener) {
return null; // TODO
}
public static PendingIntent getErrorPendingIntent(int errorCode, Activity activity,
int requestCode) {
int requestCode) {
return null; // TODO
}
@ -49,7 +53,8 @@ public class GooglePlayServicesUtil {
}
public static int isGooglePlayServicesAvailable(Context context) {
// As we can't know right now if the later desired feature is available, we just pretend it to be.
Log.d(TAG, "As we can't know right now if the later desired feature is available, " +
"we just pretend it to be.");
return ConnectionResult.SUCCESS;
}
@ -62,17 +67,18 @@ public class GooglePlayServicesUtil {
}
public static boolean showErrorDialogFragment(int errorCode, Activity activity,
int requestCode) {
int requestCode) {
return false; // TODO
}
public static boolean showErrorDialogFragment(int errorCode, Activity activity,
Fragment fragment, int requestCode, DialogInterface.OnCancelListener cancelListener) {
Fragment fragment, int requestCode,
DialogInterface.OnCancelListener cancelListener) {
return false; // TODO
}
public static boolean showErrorDialogFragment(int errorCode, Activity activity, int requestCode,
DialogInterface.OnCancelListener cancelListener) {
DialogInterface.OnCancelListener cancelListener) {
return false; // TODO
}

View File

@ -15,9 +15,9 @@ import org.microg.gms.common.api.ApiBuilder;
* See {@link GoogleApiClient.Builder} for usage examples.
*/
public final class Api<O extends Api.ApiOptions> {
private final ApiBuilder<O> builder;
public Api(ApiBuilder<O> builder) {
this.builder = builder;
}

View File

@ -7,7 +7,9 @@ import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import com.google.android.gms.common.ConnectionResult;
import org.microg.gms.Constants;
import org.microg.gms.common.api.GoogleApiClientImpl;

View File

@ -21,12 +21,15 @@ import java.util.concurrent.TimeUnit;
*/
public interface PendingResult<R extends Result> {
/**
* Blocks until the task is completed. This is not allowed on the UI thread. The returned result object can have an additional failure mode of INTERRUPTED.
* Blocks until the task is completed. This is not allowed on the UI thread. The returned
* result object can have an additional failure mode of INTERRUPTED.
*/
public R await();
/**
* Blocks until the task is completed or has timed out waiting for the result. This is not allowed on the UI thread. The returned result object can have an additional failure mode of either INTERRUPTED or TIMEOUT.
* Blocks until the task is completed or has timed out waiting for the result. This is not
* allowed on the UI thread. The returned result object can have an additional failure mode
* of either INTERRUPTED or TIMEOUT.
*/
public R await(long time, TimeUnit unit);

View File

@ -1,7 +1,8 @@
package com.google.android.gms.common.api;
/**
* An interface for receiving a {@link Result} from a {@link PendingResult} as an asynchronous callback.
* An interface for receiving a {@link Result} from a {@link PendingResult} as an asynchronous
* callback.
*/
public interface ResultCallback<R extends Result> {
/**

View File

@ -3,8 +3,10 @@ package com.google.android.gms.location;
import android.app.PendingIntent;
import android.location.Location;
import android.os.Looper;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import org.microg.gms.Constants;
public interface FusedLocationProviderApi {

View File

@ -4,28 +4,25 @@ 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 extends AbstractPlayServicesClient {
public static final String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION";
public LocationClient(Context context, ConnectionCallbacks callbacks,
OnConnectionFailedListener connectionFailedListener) {
OnConnectionFailedListener connectionFailedListener) {
super(new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(new ForwardConnectionCallbacks(callbacks))
.addOnConnectionFailedListener(new ForwardConnectionFailedListener(connectionFailedListener))
.addOnConnectionFailedListener(new ForwardConnectionFailedListener
(connectionFailedListener))
.build());
}
@ -33,16 +30,22 @@ public class LocationClient extends AbstractPlayServicesClient {
return LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
}
public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener);
public PendingResult requestLocationUpdates(LocationRequest request,
LocationListener listener) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request,
listener);
}
public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener, Looper looper) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener, looper);
public PendingResult requestLocationUpdates(LocationRequest request,
LocationListener listener, Looper looper) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request,
listener, looper);
}
public PendingResult requestLocationUpdates(LocationRequest request, PendingIntent callbackIntent) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, callbackIntent);
public PendingResult requestLocationUpdates(LocationRequest request,
PendingIntent callbackIntent) {
return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request,
callbackIntent);
}
public PendingResult removeLocationUpdates(LocationListener listener) {
@ -50,7 +53,8 @@ public class LocationClient extends AbstractPlayServicesClient {
}
public PendingResult removeLocationUpdates(PendingIntent callbackIntent) {
return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, callbackIntent);
return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient,
callbackIntent);
}
public PendingResult setMockMode(boolean isMockMode) {

View File

@ -2,12 +2,13 @@ package com.google.android.gms.location;
import android.content.Context;
import android.os.Looper;
import com.google.android.gms.common.api.AccountInfo;
import com.google.android.gms.common.api.Api;
import org.microg.gms.common.api.ApiConnection;
import com.google.android.gms.common.api.GoogleApiClient;
import org.microg.gms.common.api.ApiBuilder;
import com.google.android.gms.common.api.GoogleApiClient;
import org.microg.gms.common.api.ApiConnection;
import org.microg.gms.location.FusedLocationProviderApiImpl;
import org.microg.gms.location.GeofencingApiImpl;
import org.microg.gms.location.LocationClientImpl;
@ -23,9 +24,10 @@ public class LocationServices {
Api.ApiOptions.NoOptions options,
AccountInfo accountInfo, GoogleApiClient.ConnectionCallbacks callbacks,
GoogleApiClient.OnConnectionFailedListener connectionFailedListener) {
return new LocationClientImpl(context);
return new LocationClientImpl(context, callbacks, connectionFailedListener);
}
});
public static final FusedLocationProviderApi FusedLocationApi = new FusedLocationProviderApiImpl();
public static final FusedLocationProviderApi FusedLocationApi = new
FusedLocationProviderApiImpl();
public static final GeofencingApi GeofencingApi = new GeofencingApiImpl();
}

View File

@ -1,9 +1,9 @@
package org.microg.gms.common;
import android.os.Bundle;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationClient;
public final class ForwardConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks {
private final GooglePlayServicesClient.ConnectionCallbacks callbacks;

View File

@ -7,22 +7,31 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import org.microg.gms.common.api.ApiConnection;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.internal.IGmsCallbacks;
import com.google.android.gms.common.internal.IGmsServiceBroker;
import org.microg.gms.common.api.ApiConnection;
public abstract class GmsClient<I extends IInterface> implements ApiConnection {
private static final String TAG = "GmsClient";
private final Context context;
private final GoogleApiClient.ConnectionCallbacks callbacks;
private final GoogleApiClient.OnConnectionFailedListener connectionFailedListener;
private ConnectionState state = ConnectionState.CONNECTED;
private ServiceConnection serviceConnection;
private I serviceInterface;
public GmsClient(Context context) {
public GmsClient(Context context, GoogleApiClient.ConnectionCallbacks callbacks,
GoogleApiClient.OnConnectionFailedListener connectionFailedListener) {
this.context = context;
this.callbacks = callbacks;
this.connectionFailedListener = connectionFailedListener;
}
protected abstract String getActionString();
@ -67,7 +76,7 @@ public abstract class GmsClient<I extends IInterface> implements ApiConnection {
public Context getContext() {
return context;
}
public I getServiceInterface() {
return serviceInterface;
}
@ -81,7 +90,9 @@ public abstract class GmsClient<I extends IInterface> implements ApiConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
try {
onConnectedToBroker(IGmsServiceBroker.Stub.asInterface(iBinder), new GmsCallbacks());
Log.d(TAG, "Connecting to broker for " + componentName);
onConnectedToBroker(IGmsServiceBroker.Stub.asInterface(iBinder),
new GmsCallbacks());
} catch (RemoteException e) {
disconnect();
}
@ -99,6 +110,7 @@ public abstract class GmsClient<I extends IInterface> implements ApiConnection {
public void onPostInitComplete(int statusCode, IBinder binder, Bundle params)
throws RemoteException {
serviceInterface = interfaceFromBinder(binder);
callbacks.onConnected(params);
}
}

View File

@ -21,13 +21,11 @@ import android.os.Message;
import android.os.RemoteException;
import com.google.android.gms.common.api.Api;
import org.microg.gms.common.api.AbstractPendingResult;
import org.microg.gms.common.api.ApiConnection;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.Result;
import org.microg.gms.common.api.AbstractPendingResult;
import org.microg.gms.common.api.ApiConnection;
import org.microg.gms.common.api.GoogleApiClientImpl;
public class GmsConnector<C extends ApiConnection, R extends Result, O extends Api.ApiOptions> {
@ -43,7 +41,7 @@ public class GmsConnector<C extends ApiConnection, R extends Result, O extends A
public AbstractPendingResult<R> connect() {
Looper looper = ((GoogleApiClientImpl) apiClient).getLooper();
Looper looper = apiClient.getLooper();
final AbstractPendingResult<R> result = new AbstractPendingResult<>(looper);
Message msg = new Message();
msg.obj = result;

View File

@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
import java.util.HashMap;
import java.util.HashSet;
@ -14,6 +15,8 @@ import java.util.Set;
import static org.microg.gms.Constants.GMS_PACKAGE_NAME;
public class MultiConnectionKeeper {
private static final String TAG = "GmsMultiConnectionKeeper";
private static MultiConnectionKeeper INSTANCE;
private final Context context;
@ -45,7 +48,7 @@ public class MultiConnectionKeeper {
}
return con.isBound();
}
public void unbind(String action, ServiceConnection connection) {
Connection con = connections.get(action);
if (con != null) {
@ -68,6 +71,7 @@ public class MultiConnectionKeeper {
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
binder = iBinder;
component = componentName;
Log.d(TAG, "bound to " + actionString);
for (ServiceConnection connection : connectionForwards) {
connection.onServiceConnected(componentName, iBinder);
}
@ -92,7 +96,8 @@ public class MultiConnectionKeeper {
public void bind() {
Intent intent = new Intent(actionString).setPackage(GMS_PACKAGE_NAME);
bound = context.bindService(intent, serviceConnection,
Context.BIND_ADJUST_WITH_ACTIVITY & Context.BIND_AUTO_CREATE);
Context.BIND_ADJUST_WITH_ACTIVITY | Context.BIND_AUTO_CREATE);
Log.d(TAG, "binding to " + actionString + ": " + bound);
if (!bound) {
context.unbindService(serviceConnection);
}
@ -108,6 +113,7 @@ public class MultiConnectionKeeper {
public void unbind() {
context.unbindService(serviceConnection);
Log.d(TAG, "unbinding from " + actionString);
bound = false;
}
@ -128,7 +134,7 @@ public class MultiConnectionKeeper {
public boolean forwardsConnection(ServiceConnection connection) {
return connectionForwards.contains(connection);
}
public boolean hasForwards() {
return !connectionForwards.isEmpty();
}

View File

@ -1,6 +1,7 @@
package org.microg.gms.common.api;
import android.os.Looper;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Result;
import com.google.android.gms.common.api.ResultCallback;
@ -85,11 +86,11 @@ public class AbstractPendingResult<R extends Result> implements PendingResult<R>
}
}
}
private void deliverResult(R result) {
this.result = result;
countDownLatch.countDown();
}
public void setResult(R result) {

View File

@ -23,10 +23,8 @@ import com.google.android.gms.common.api.AccountInfo;
import com.google.android.gms.common.api.Api;
import com.google.android.gms.common.api.GoogleApiClient;
import org.microg.gms.common.api.ApiConnection;
public interface ApiBuilder<O extends Api.ApiOptions> {
ApiConnection build(Context context, Looper looper, O options, AccountInfo accountInfo,
GoogleApiClient.ConnectionCallbacks callbacks,
GoogleApiClient.OnConnectionFailedListener connectionFailedListener);
GoogleApiClient.ConnectionCallbacks callbacks,
GoogleApiClient.OnConnectionFailedListener connectionFailedListener);
}

View File

@ -18,6 +18,8 @@ package org.microg.gms.common.api;
public interface ApiConnection {
public void connect();
public void disconnect();
public boolean isConnected();
}

View File

@ -2,7 +2,9 @@ package org.microg.gms.common.api;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.*;
@ -19,6 +21,7 @@ public class GoogleApiClientImpl implements GoogleApiClient {
private final AccountInfo accountInfo;
private final Map<Api, Api.ApiOptions> apis = new HashMap<>();
private final Map<Api, ApiConnection> apiConnections = new HashMap<>();
private final Handler handler;
private final Set<ConnectionCallbacks> connectionCallbacks = new HashSet<>();
private final Set<OnConnectionFailedListener> connectionFailedListeners = new HashSet<>();
private final int clientId;
@ -52,6 +55,7 @@ public class GoogleApiClientImpl implements GoogleApiClient {
Set<OnConnectionFailedListener> connectionFailedListeners, int clientId) {
this.context = context;
this.looper = looper;
this.handler = new Handler(looper);
this.accountInfo = accountInfo;
this.apis.putAll(apis);
this.connectionCallbacks.addAll(connectionCallbacks);
@ -156,4 +160,23 @@ public class GoogleApiClientImpl implements GoogleApiClient {
public void unregisterConnectionFailedListener(OnConnectionFailedListener listener) {
connectionFailedListeners.remove(listener);
}
private class Handler extends android.os.Handler {
private Handler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
if (msg.what == 0 && msg.obj instanceof Runnable) {
((Runnable) msg.obj).run();
} else {
super.handleMessage(msg);
}
}
public void sendRunnable(Runnable runnable) {
sendMessage(obtainMessage(1, runnable));
}
}
}

View File

@ -16,7 +16,6 @@ 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";
@ -33,8 +32,7 @@ public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
@Override
public PendingResult requestLocationUpdates(GoogleApiClient client,
final LocationRequest request,
final LocationListener listener) {
final LocationRequest request, final LocationListener listener) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
@ -45,9 +43,8 @@ public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
@Override
public PendingResult requestLocationUpdates(GoogleApiClient client,
final LocationRequest request,
final LocationListener listener,
final Looper looper) {
final LocationRequest request, final LocationListener listener,
final Looper looper) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
@ -58,8 +55,7 @@ public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
@Override
public PendingResult requestLocationUpdates(GoogleApiClient client,
final LocationRequest request,
final PendingIntent callbackIntent) {
final LocationRequest request, final PendingIntent callbackIntent) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
@ -70,7 +66,7 @@ public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
@Override
public PendingResult removeLocationUpdates(GoogleApiClient client,
final LocationListener listener) {
final LocationListener listener) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {
@ -81,7 +77,7 @@ public class FusedLocationProviderApiImpl implements FusedLocationProviderApi {
@Override
public PendingResult removeLocationUpdates(GoogleApiClient client,
final PendingIntent callbackIntent) {
final PendingIntent callbackIntent) {
return callVoid(client, new Runnable() {
@Override
public void run(LocationClientImpl client) throws RemoteException {

View File

@ -4,14 +4,18 @@ import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.internal.IGmsServiceBroker;
import com.google.android.gms.location.internal.IGoogleLocationManagerService;
import org.microg.gms.Constants;
import org.microg.gms.common.GmsClient;
public class GoogleLocationManagerClient extends GmsClient<IGoogleLocationManagerService> {
public GoogleLocationManagerClient(Context context) {
super(context);
public GoogleLocationManagerClient(Context context, GoogleApiClient.ConnectionCallbacks
callbacks, GoogleApiClient.OnConnectionFailedListener connectionFailedListener) {
super(context, callbacks, connectionFailedListener);
}
@Override

View File

@ -5,6 +5,7 @@ import android.content.Context;
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.location.ILocationListener;
@ -18,8 +19,12 @@ import java.util.HashMap;
import java.util.Map;
public class LocationClientImpl extends GoogleLocationManagerClient {
public LocationClientImpl(Context context) {
super(context);
private static final String TAG = "GmsLocationClientImpl";
public LocationClientImpl(Context context, GoogleApiClient.ConnectionCallbacks callbacks,
GoogleApiClient.OnConnectionFailedListener connectionFailedListener) {
super(context, callbacks, connectionFailedListener);
Log.d(TAG, "<init>");
}
public static LocationClientImpl get(GoogleApiClient apiClient) {
@ -55,7 +60,7 @@ public class LocationClientImpl extends GoogleLocationManagerClient {
}
public void requestLocationUpdates(LocationRequest request, LocationListener listener,
Looper looper) throws RemoteException {
Looper looper) throws RemoteException {
requestLocationUpdates(request, listener); // TODO
}