Git Product home page Git Product logo

easygoogle's Introduction

EasyGoogle

Project status

status: inactive

This project is no longer actively maintained, and remains here as an archive of this work.

EasyGoogle was created as an experimental improvement to the developer experience for certain Google APIs. In the time since its creation, most of these APIs have improved (and many in ways that resemble EasyGoogle). For this reason it no longer makes sense to maintain this library. Thank you to everyone who submitted issues or gave feedback, your thoughts influenced API development at Google.

Introduction

EasyGoogle is a wrapper library to simplify basic integrations with Google Play Services. The library wraps the following APIs (for now):

Installation

EasyGoogle is installed by adding the following dependency to your build.gradle file:

dependencies {
  compile 'pub.devrel:easygoogle:0.2.5+'
}

Usage

Enabling Services

Before you begin, visit this page to select Google services and add them to your Android app. Make sure to enable any services you plan to use and follow all of the steps, including modifying your build.gradle files to enable the google-services plugin.

Once you have a google-services.json file in the proper place you can proceed to use EasyGoogle.

Basic

EasyGoogle makes use of Fragments to manage the lifecycle of the GoogleApiClient, so any Activity which uses EasyGoogle must extend FragmentActivity.

All interaction with EasyGoogle is through the Google class, which is instantiated like this:

public class MainActivity extends AppCompatActivity {

  private Google mGoogle;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mGoogle = new Google.Builder(this).build();
  }

}

Of course, instantiating a Google object like this won't do anything at all, you need to enable features individually.

Sign-In

To enable Google Sign-In, call the appropriate method on Google.Builder and implement the SignIn.SignInListener interface:

 public class MainActivity extends AppCompatActivity implements
   SignIn.SignInListener {

   private Google mGoogle;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     // This is optional, pass 'null' if no ID token is required.
     String serverClientId = getString(R.string.default_web_client_id);

     mGoogle = new Google.Builder(this)
       .enableSignIn(this, serverClientId)
       .build();
   }

   @Override
   public void onSignedIn(GoogleSignInAccount account) {
       // Sign in was successful.
   }

   @Override
   public void onSignedOut() {
       // Sign out was successful.
   }

   @Override
   public void onSignInFailed() {
       // Sign in failed for some reason and should not be attempted again
       // unless the user requests it.
   }

 }

Then, use the SignIn object from mGoogle.getSignIn() to access API methods like SignIn#getCurrentUser(), SignIn#signIn, and SignIn#signOut.

Cloud Messaging

To enable Cloud Messaging, you will have to implement a simple Service in your application.

First, pick a unique permission name and make the following string resource in your strings.xml file. It is important to pick a unique name:

<string name="gcm_permission">your.unique.gcm.permission.name.here</string>

Next, add the following to your AndroidManifest.xml inside the application tag, making sure that the value of the android:permission element is the same value you specified in your strings.xml file above:

 <!-- This allows the app to receive GCM through EasyGoogle -->
 <service
     android:name=".MessagingService"
     android:enabled="true"
     android:exported="false"
     android:permission="your.unique.gcm.permission.name.here" />

Next, add the following permission to your AndroidManifest.xml file before the application tag, replacing <your-package-name> with your Android package name:

    <permission android:name="<your-package-name>.permission.C2D_MESSAGE"
                android:protectionLevel="signature" />
    <uses-permission android:name="<your-package-name>.permission.C2D_MESSAGE" />

Then implement a class called MessagingService that extends EasyMessageService. Below is one example of such a class:

public class MessagingService extends EasyMessageService {

  @Override
  public void onMessageReceived(String from, Bundle data) {
      // If there is a running Activity that implements MessageListener, it should handle
      // this message.
      if (!forwardToListener(from, data)) {
          // There is no active MessageListener to get this, I should fire a notification with
          // a PendingIntent to an activity that can handle this.
          PendingIntent pendingIntent = createMessageIntent(from, data, MainActivity.class);
          Notification notif = new NotificationCompat.Builder(this)
                  .setContentTitle("Message from: " + from)
                  .setContentText(data.getString("message"))
                  .setSmallIcon(R.mipmap.ic_launcher)
                  .setContentIntent(pendingIntent)
                  .setAutoCancel(true)
                  .build();

          NotificationManager notificationManager =
                  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
          notificationManager.notify(0, notif);
      }
  }

  @Override
  public void onNewToken(String token) {
      // Send a registration message to the server with our new token
      String senderId = getString(R.string.gcm_defaultSenderId);
      sendRegistrationMessage(senderId, token);
  }
}

Note the use of the helper methods forwardToListener and createMessageIntent, which make it easier for you to either launch an Activity or create a Notification to handle the message.

The forwardToListener method checks to see if there is an Activity that implements Messaging.MessagingListener in the foreground. If there is, it sends the GCM message to the Activity to be handled. To implement Messaging.MessagingListener, call the appropriate method on Google.Builder in your Activity and implement the interface:

public class MainActivity extends AppCompatActivity implements
  Messaging.MessagingListener {

  private Google mGoogle;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mGoogle = new Google.Builder(this)
      .enableMessaging(this, getString(R.string.gcm_defaultSenderId))
      .build();
  }

  @Override
  public void onMessageReceived(String from, Bundle message) {
      // GCM message received.
  }
}

Then, use the Messaging object from mGoogle.getMessaging() to access API methodslike Messaging#send.

App Invites

To enable App Invites, call the appropriate method on Google.Builder and implement the AppInvites.AppInviteListener interface:

public class MainActivity extends AppCompatActivity implements
  AppInvites.AppInviteListener {

  private Google mGoogle;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mGoogle = new Google.Builder(this)
      .enableAppInvites(this)
      .build();
  }

  @Override
  public void onInvitationReceived(String invitationId, String deepLink) {
      // Invitation recieved in the app.
  }

  @Override
  public void onInvitationsSent(String[] ids) {
      // The user selected contacts and invitations sent successfully.
  }

  @Override
  public void onInvitationsFailed() {
      // The user either canceled sending invitations or they failed to
      // send due to some configuration error.
  }

}

Then, use the AppInvites object from mGoogle.getAppInvites() to access API methods like AppInvites#sendInvitation.

SmartLock for Passwords

To enable Smart Lock for Passwords, call the appropriate method on Google.Builder and implement the SmartLock.SmartLockListener interface:

public class MainActivity extends AppCompatActivity implements
  SmartLock.SmartLockListener {

  private Google mGoogle;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mGoogle = new Google.Builder(this)
      .enableSmartLock(this)
      .build();
  }

  @Override
  public void onCredentialRetrieved(Credential credential) {
    // Successfully retrieved a Credential for the current device user.
  }

  @Override
  public void onShouldShowCredentialPicker() {
    // In order to retrieve a Credential, the app must show the picker dialog
    // using the SmartLock#showCredentialPicker() method.
  }

  @Override
  public void onCredentialRetrievalFailed() {
    // The user has no stored credentials, or the retrieval operation failed or
    // was canceled.
  }

}

Then, use the SmartLock object from mGoogle.getSmartLock() to access API methods like SmartLock#getCredentials() and SmartLock#save().

Advanced Usage

If you would like to perform some action using one of the enabled Google services but it is not properly wrapped by the EasyGoogle library, just call Google#getGoogleApiClient() to get access to the underlying GoogleApiClient held by the Google object.

easygoogle's People

Contributors

aliafshar avatar ersin-ertan avatar jfschmakeit avatar mightyfrog avatar samtstern avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easygoogle's Issues

ServerClientId needed for GoogleSignInOptions Web server OAuth

TL;DR The issue is with not having the ability to include a serverClientId in the GoogleSignInOptions.

This problem appeared when GoogleSignInAccount.getIdToken(); (which is required for my backend's google plus login) was returning null.

Sign in was a clean abstraction and was great to work with, however, I believe the use case with registering OAuth clients for Google Sign-In states that "Web server OAuth client registration" is needed with android by requesting/ "an ID token in your GoogleSignInOptions, supplying the web client ID for your server".

GoogleSignInOptions gso =
    new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(serverClientId)
        .requestEmail()
        .build();

EasyGoogle does not have us directly implement the GoogleSignInOptions class. From what I understand, the IdTokenActivity is the original solution, which voids the use of easygoogle. See line #55.

R.string.gcm_permission when not using GCM?

I'm mainly wanting to use this library to implement Google+ Sign-in, but after setting everything up, it crashes saying I haven't declared R.string.gcm_permission. Why do I need to do this if I'm not using GCM?

Invalid permission declaration

Correct me if I am wrong, but i think using this library in production builds would give issues with the declaration of permissions. Since Android 5.0 it is not allowed to have two apps declare the same permission if they are signed with a different keystore. The installation of the app will fail.

Unnecessary cast to MessagingListener

When running an app with Sign-In only, I get:

8-19 13:41:28.442 11971 11971 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.android.gms.pickmeup/com.google.android.gms.pickmeup.MainActivity}: java.lang.ClassCastException: com.google.android.gms.pickmeup.MainActivity@598140d must implement MessagingListener
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at android.app.ActivityThread.-wrap11(ActivityThread.java)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:102)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:148)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:5417)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
08-19 13:41:28.442 11971 11971 E AndroidRuntime: Caused by: java.lang.ClassCastException: com.google.android.gms.pickmeup.MainActivity@598140d must implement MessagingListener
08-19 13:41:28.442 11971 11971 E AndroidRuntime:    at pub.devrel.easygoogle.gcm.MessagingFragment.onAttach(MessagingFragment.java:86)

EasyGoogle should never cast the Activity to any listener, and Messaging should only check for a MessagingListener when enabled.

getCurrentUser's getGooogleApiClient dealing with null

With the calling code of:

        if (google != null) {
            SignIn signIn = google.getSignIn();
            if (signIn != null) {
                boolean isS = signIn.isSignedIn();
                if (isS) { ...

And SignIn.class code of:

   public GoogleSignInAccount getCurrentUser() {
        OptionalPendingResult opr = Auth.GoogleSignInApi.silentSignIn(this.getFragment().getGoogleApiClient());
        return opr.isDone()?((GoogleSignInResult)opr.get()).getSignInAccount():null;
    }

    public boolean isSignedIn() {
        return this.getCurrentUser() != null;
    }

The GacFragment.class

    public GoogleApiClient getGoogleApiClient() {
        return this.mGoogleApiClient;
    }

is returning null and crashing.

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.common.api.Api$zzb com.google.android.gms.common.api.GoogleApiClient.zza(com.google.android.gms.common.api.Api$zzc)' on a null object reference
                      at com.google.android.gms.auth.api.signin.internal.zzc.zza(Unknown Source)
                      at com.google.android.gms.auth.api.signin.internal.zzc.silentSignIn(Unknown Source)
                      at pub.devrel.easygoogle.gac.SignIn.getCurrentUser(SignIn.java:181)
                      at pub.devrel.easygoogle.gac.SignIn.isSignedIn(SignIn.java:195)

Shouldn't it return false?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.