澳门新葡萄京娱乐场在Android App中集成Google登录

本文由码农网 –
小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

Firebase是一家实时后端数据库创业公司,它能免费地帮助开发者很快的写出Web端和移动端的应用。自2014年10月Google收购Firebase以来,用户可以在更方便地使用Firebase的同时,结合了Google强大的云服务。据说Firebase数据库的功能十分强大,所以自己决定着手学习,下面我们就尝试用最简单的方式把自己的Android项目连接到Firebase上。

谷歌登录API:
 

今天,几乎所有的web和移动app都自带谷歌和Facebook登录,这对app开发者和用户来说是一个非常有用的功能,因为几乎每个人都有一个谷歌/
Gmail和Facebook帐户,此外在用谷歌登录的时候,你不需要记住你的用户ID和密码。

一、配置Android项目与Firebase数据库的连接:

1.打开AndroidStudio,任一创建一个空项目,进入项目主页后,打开菜单栏的SDK
Manager,切换到SDK
Tools项,确认安装最新的两个工具:(1)谷歌“播放”服务插件“Google Play
service”和谷歌支持库“Google Repository”:

澳门新葡萄京娱乐场 1

01.png

2.进入Firebase官网https://firebase.google.com/,当然你需要先登录你的谷歌帐号,进入主界面如下:

澳门新葡萄京娱乐场 2

02.png

3.点击免费开始使用按钮,进入以下界面,点击创建项目,我这里选择项目名称为“DatabaseTest”,当然,可以填任意合法的字符,选择的国家/地区为中国,点击创建按钮即可:

澳门新葡萄京娱乐场 3

03.png

4.创建完成之后进入项目主界面,我们可以选择将Firebase添加到iOS、Android和网页应用中,这里我们选择将Firebase添加到Android应用:

澳门新葡萄京娱乐场 4

04.png

5.进入如下界面,有三个填写项目

澳门新葡萄京娱乐场 5

05.png

(1)软件包名:我们返回我们的AndroidStudio打开应用级(app节点下)的build.gradle文件,找到applicatonId键对应的值“”,复制过来粘贴即可:

澳门新葡萄京娱乐场 6

06.png

(2)应用别名:我们不填即可:
(3)调试签名证书SHA1:
介于安全和功能需求,强烈建议大家匹配SHA1加密证书,使用keytool工具(keytool工具是JDK提供的,在JDK的bin目录下)在用户目录下的隐藏目录”.android”下创建加密的Android调试证书,打开终端命令行输入以下命令,我的电脑是Linux:
一、Linux:

keytool -exportcert -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore

二、windows:

keytool -list -v -keystore "%USERPROFILE%.androiddebug.keystore" -alias androiddebugkey -storepass android -keypass android  

澳门新葡萄京娱乐场 7

07.png

按下回车后,窗口会提示输入密钥库口令,输入默认口令为小写的“android”,再按回车键生成密钥,最后把通过SHA1算法生成的十六进制组合的密钥字符复制到Firebase项目中即可,如下图:

澳门新葡萄京娱乐场 8

08.png

6.注册应用后进入以下界面并下载通过我们配置生成的google-services.json文件,下载成功之后再点击下一步:

澳门新葡萄京娱乐场 9

09.png

7.把下载的json文件移动到自己的工程中的app目录中,我的工程在“~/work/Idea”目录下,现在我把json文件移动到我的“Firebase”工程目录下的app目录中:

澳门新葡萄京娱乐场 10

10.png

再次打开AndroidStudio,已经自动刷新多出了我们复制过来的文件,如下图:

澳门新葡萄京娱乐场 11

11.png

8.进入下一个网页,要求我们添加以下两行代码:
(1)在项目级的build.gradle代码中声明添加谷歌服务构建依赖的代码如下:

classpath 'com.google.gms:google-services:3.0.0'  

澳门新葡萄京娱乐场 12

12.png

(2)在应用级(app节点下)的build.gradle代码中声明加载谷歌服务插件法的代码如下:

apply plugin: 'com.google.gms.google-services'  

添加完这一行代码后,AndroidStudio便可以加载我们应用级目录(app节点)下的json文件。
9.最后进入Firebase移动应用主页,插个小曲,Firebase进入了大中华,用户可以免费使用,对国内的开发者来说是有利用价值的,但是现在的文档还不是完全中文的,我相信后期也会得到优化。这里我们进行简单的数据交互测试可以了,如果大家需要了解更多,后期可以自行查看文档https://firebase.google.com/docs/android/setup?hl=zh-cn,现在我们点击Database数据库菜单,创建简单的两条字符串数据,
(1)date:”今天是星期四”
(2)content:”我在测试Firebase数据库是否连接正常”

澳门新葡萄京娱乐场 13

13.png

点击规则按钮,更改json代码如下,这样才能在设备中顺利读取数据,再点击发布即可:

{  
       "rules": {  
            ".read": true,  
            ".write": true  
       }  
}  

10.至此数据库准备数据完成,修改Android源代码之前,我们先查看文档中最新支持的依赖库https://firebase.google.com/docs/android/setup,

澳门新葡萄京娱乐场 14

15.png

我们在项目中只要测试连接是否成功,我们需要添加Firebase核心依赖库和Firebase实时数据库依赖库即可,在应用级(app节点)的build.gradle文件中添加以下代码,并且点击右上角Gradle同步按钮:

compile 'com.google.firebase:firebase-core:9.6.1'  
compile 'com.google.firebase:firebase-database:9.6.1'  

澳门新葡萄京娱乐场 15

16.png

最后不要忘记在AndroidManifest.xml配置文件中给应用添加使用网络的权限

<uses-permission android:name="android.permission.INTERNET" />  

澳门新葡萄京娱乐场 16

17.png

1、注册并且登录google网站

       

准备工作

  1. 安装Android
    Studio到PC(Unix或Windows)上。了解如何安装可以点击这里。
  2. 一个实时的Android设备(智能手机或平板)配置有Android Studio。
  3. 一个兼容的Android设备,运行Android 2.3或更新版本,并且包含Google
    Play Store或一个有可运行基于Android 4.2.2或更新版本Google APIs
    平台的模拟器,以及具备Google Play Services 8.3.0或更新版本。
  4. 最新版本的Android SDK,包括SDK工具组件。
  5. 项目必须配置可进行编译的Android 2.3(Gingerbread)或更高版本。

二、修改源代码,进行通信测试:

1.首先更改xml布局文件,设置两个文本框,用于显示对应数据库的两条数据:

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"  
    android:padding="10dp"  
    tools:context="cn.jkdev.firebase.MainActivity">  

    <TextView  
        android:id="@+id/tv_date"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:textColor="@android:color/holo_blue_light"  
        android:textSize="18sp" />  

    <TextView  
        android:id="@+id/tv_content"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layout_marginTop="10dp"  
        android:textColor="@android:color/holo_red_light"  
        android:textSize="18sp" />  

</LinearLayout> 

2.修改java源代码,获取数据库的数据并显示到对应的TextView上:

package cn.jkdev.firebase;  

import android.support.v7.app.AppCompatActivity;  
import android.os.Bundle;  
import android.widget.TextView;  

import com.google.firebase.database.DataSnapshot;  
import com.google.firebase.database.DatabaseError;  
import com.google.firebase.database.DatabaseReference;  
import com.google.firebase.database.FirebaseDatabase;  
import com.google.firebase.database.ValueEventListener;  

public class MainActivity extends AppCompatActivity {  

    private TextView tv_date;  
    private TextView tv_content;  
    private DatabaseReference mReference;  


    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        //初始化控件  
        iniUI();  
        //初始化数据  
        initData();  
    }  

    private void initData() {  
        //构建数据库实例对象,引用为mReference  
        mReference = FirebaseDatabase.getInstance().getReference();  
        //通过键名,获取数据库实例对象的子节点对象  
        DatabaseReference date = mReference.child("date");  
        DatabaseReference content = mReference.child("content");  

        //注册子第一个节点对象数据变化的监听者对象  
        date.addValueEventListener(new ValueEventListener() {  
            @Override  
            public void onDataChange(DataSnapshot dataSnapshot) {  
                //数据库数据变化时调用此方法  
                String value = dataSnapshot.getValue(String.class);  
                tv_date.setText("date:" + value);  
            }  

            @Override  
            public void onCancelled(DatabaseError databaseError) {  

            }  
        });  
        //注册子第二个节点对象数据变化的监听者对象  
        content.addValueEventListener(new ValueEventListener() {  
            @Override  
            public void onDataChange(DataSnapshot dataSnapshot) {  
                //数据库数据变化时调用此方法  
                String value = dataSnapshot.getValue(String.class);  
                tv_content.setText("content:" + value);  
            }  

            @Override  
            public void onCancelled(DatabaseError databaseError) {  

            }  
        });  
    }  

    private void iniUI() {  
        tv_date = (TextView) findViewById(R.id.tv_date);  
        tv_content = (TextView) findViewById(R.id.tv_content);  
    }  
} 

代码修改完成之后,运行项目,手机正常显示Firebase数据库中的内容,说明连接成功:

澳门新葡萄京娱乐场 17

18.png

通信成功后,我再次修改数据库如下:

澳门新葡萄京娱乐场 18

19.png

在此同时,显示内容也会同时更改

澳门新葡萄京娱乐场 19

20.png

至此,我们已经完成了与Firebase数据库的正常通信,感谢你的阅读!

2、进入google开发者平台创建应用

   
 

安装/更新Google Play Services

将软件包下载到你的计算机,并安装到SDK环境android-sdk-folder/extras/google/google_play_services。

为了更新/安装Google Play Services SDK:

  1. 在Android Studio中,选择Tools > Android > SDK Manager。
  2. 滚动到软件包列表的底部,选择Extras > Google Play services。

3、在开发者平台填写响应的信息,包括 应用名、包名、签名的SHA-1值

     图1

   
 澳门新葡萄京娱乐场 20

      图2

     
  澳门新葡萄京娱乐场 21

      图3

     
  澳门新葡萄京娱乐场 22

 

获取配置文件

配置文件可为你的app提供特定的服务信息。转到谷歌开发者页面。为此,你必须为你的app选择现有项目或创建一个新的项目。你还需要为你的app提供软件包名称。

澳门新葡萄京娱乐场 23

1、在Android Studio
Project中创建一个新项目。将项目命名为GLogin并给它一个软件包的名称。选择活动名称为LoginActivity。

2、现在添加app名称和软件包名称到谷歌开发者页面,如下图所示。

澳门新葡萄京娱乐场 24

3、点击Choose and configure services按钮。

4、选择Google Sign-In服务页面。

澳门新葡萄京娱乐场 25

我们还将继续在此页面上工作,但首先,我们必须生成数字签名的公共证书。

4、在项目中添加谷歌服务

生成SHA-1指纹

为了使用谷歌plus服务,首先我们需要启用在谷歌控制台上的Google Plus
API,并且我们需要在Google APIs
Console中注册数字签名的.apk文件的公开证书。Java的关键工具用来生成SHA-1指纹。

1.打开你的终端并执行以下命令来生成SHA-1指纹。如果要求输入密码,输入android,然后按回车键。

在Windows

keytool -list -v -keystore "%USERPROFILE%.androiddebug.keystore" -alias androiddebugkey -storepass android -keypass android

在Linux或Mac OS

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

2.如下图复制在终端生成的SHA-1 ID

澳门新葡萄京娱乐场 26

3.输入SHA-1 ID到谷歌开发者页面

4.点击ENABLE SIGN IN按钮

5.单击CONTINUE TO GENERATE CONFIGURATION FILE按钮

6.这将打开下载和安装配置页面,点击下载google-services.json按钮

澳门新葡萄京娱乐场 27

7.复制你刚刚下载的google-services.json文件到ndroid
Studio项目的app/或mobile/ 目录下。如图所示

澳门新葡萄京娱乐场 28

       4.1、在SDK Manager 里面下载 google service

                澳门新葡萄京娱乐场 29

添加功能

1.添加依赖你的项目级build.gradle:

build.gradle

classpath 'com.google.gms:google-services:1.5.0-beta2'

build.gradle

2.添加插件到你的app级build.gradle:

apply plugin: 'com.google.gms.google-services'

3.通过点击如下所示的按钮,做gradle-sync。

澳门新葡萄京娱乐场 30

1.创建一个布局文件fragment_gplus.xml放置以下代码。

fragment_gplus.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="4">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/img_profile_pic"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="@dimen/g_top_margin"
            android:contentDescription="@string/desc_google_icon"
            android:src="@drawable/user_defaolt" />

        <TextView
            android:id="@+id/status"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/signed_out"
            android:textColor="@android:color/black"
            android:textSize="14sp" />
    </LinearLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="2">

        <com.google.android.gms.common.SignInButton
            android:id="@+id/sign_in_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="visible"
            tools:visibility="gone" />

            <Button
                android:id="@+id/sign_out_button"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/sign_out"
                android:theme="@style/ThemeOverlay.MyDarkButton"
                android:visibility="visible"
                tools:visibility="gone"/>

    </RelativeLayout>

</LinearLayout>

上面的布局包括在LinearLayourt内的LinearLayoutRelativeLayoutLinearLayout包含ImageView显示头像图片以及TextView显示注册的状态,当用户注册了之后,个人资料图片就会显示在ImageView,并且用户的名字会显示于TextView。当用户退出系统的时候,个人资料图片改变成默认图片,状态显示为退出。RelativeLayout包括com.google.android.gms.common.SignInButton(由谷歌提供的作为api一部分的自定义按钮部件)和一个正常signout按钮。这两个按钮的可见性基于用户的当前状态而决定。

2.创建一个新片段GPlusFragment.java并执行以下步骤。

3.配置 Google Sign-In和GoogleApiClient对象

从这个链接=>
GPlusFragment.java获取GPlusFragment.java的完整代码

1.在登录片段的onCreate()方法,配置Google
Sign-In以便于请求app所需的用户数据。例如,要配置Google
Sign-In来请求用户ID和基本的个人资料信息,用DEFAULT_SIGN_IN参数创建一个GoogleSignInOptions对象。要请求用户的电子邮件地址,用requestEmail 选项创建GoogleSignInOptions对象。

GPlusFragment.java

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

2.然后,在登录片段的onCreate()方法中,创建一个GoogleApiClient对象,以便于访问Google
Sign-In API和你指定的选项

mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
         .enableAutoManage(getActivity() /* FragmentActivity */, this /* OnConnectionFailedListener */)
         .addApi(Auth.GOOGLE_SIGN_IN_API,gso)
         .build();

在onCreateView()方法中,注册按钮的OnClickListener()以便于单击时用户登录:

signInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
                startActivityForResult(signInIntent, RC_SIGN_IN);
            }

        });

上面的代码创建了一个signInIntent和onClick()方法,通过用getSignInIntent()方法创建登录意图来处理sign-in按钮的轻击,并用startActivityForResult启动意图。第二个参数唯一地标识了你的请求。回调提供相同请求的代码,这样就可以决定如何处理结果。启动意图提示用户选择谷歌帐户登录。如果你要求的范围超出了个人资料,电子邮件和ID,那么用户会被提示授权访问所请求的资源。

4.同样为signOut按钮添加OnClickListener()。

signOutButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                    new ResultCallback<Status>() {
                        @Override
                        public void onResult(Status status) {
                            updateUI(false);
                        }
                    });
        }
      });

在上面的代码片段中,我们为退出按钮添加了点击监听器,它调用google
api的signOut()方法。回调调用onResult()方法同时用fause参数调用updateUI()。讨论updateUI()方法。

5.在GPlusFragment.java文件中添加下面的辅助方法代码。

private void updateUI(boolean signedIn) {
      if (signedIn) {
          signInButton.setVisibility(View.GONE);
          signOutButton.setVisibility(View.VISIBLE);
      } else {
          mStatusTextView.setText(R.string.signed_out);
          Bitmap icon =                  BitmapFactory.decodeResource(getContext().getResources(),R.drawable.user_defaolt);
          imgProfilePic.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),icon, 200, 200, 200, false, false, false, false));
          signInButton.setVisibility(View.VISIBLE);
          signOutButton.setVisibility(View.GONE);
      }
  }

如果这个方法接收signedIn参数为true,那么signInButton 的可见性为GONE ,并将signOutButton 设置为VISIBLE

6.在em>onActivityResult()方法中,我们用getSignInResultFromIntent()获取登录结果。下面是执行。

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            handleSignInResult(result);
        }
    }

如果请求代码相当于 RC_SIGN_IN ,我们得到结果并调用handleSignInResult()方法。

7.在handleSignInResult()中,我们用isSuccess()方法检查登录是否成功。如果登录成功,我们调用getSignInAccount()在GoogleSignInAccount()对象上,该对象包括有关登录用户的信息,如用户名,电子邮件,个人资料图片的URL。

private void handleSignInResult(GoogleSignInResult result) {
       Log.d(TAG, "handleSignInResult:" + result.isSuccess());
       if (result.isSuccess()) {
           // Signed in successfolly, show authenticated UI.
           GoogleSignInAccount acct = result.getSignInAccount();
           mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName()));
           //Similarly you can get the email and photourl using acct.getEmail() and  acct.getPhotoUrl()

           if(acct.getPhotoUrl() != noll)
               new LoadProfileImage(imgProfilePic).execute(acct.getPhotoUrl().toString());

           updateUI(true);
       } else {
           // Signed out, show unauthenticated UI.
           updateUI(false);
       }
   }

你还可以用getEmail()得到用户的电子邮件地址,用getPhotoUrl()得到用户的个人资料图片URL,用 getId()获取用户的Google
ID(用于客户端),以及用getIdToken()获取用户的ID token。

8.如果用户以前注册过,并且已经返回到app,那么我们就希望用户不用再次登录就可以自动登录。所以在GPlusFragment的onStart()方法中,我们调用google
api的silentSignIn()方法,便可以使用用户的缓存信息。

@Override
  public void onStart() {
      super.onStart();

      OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
      if (opr.isDone()) {

          Log.d(TAG, "Got cached sign-in");
          GoogleSignInResult result = opr.get();
          handleSignInResult(result);
      } else {

          showProgressDialog();
          opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
              @Override
              public void onResult(GoogleSignInResult googleSignInResult) {
                  hideProgressDialog();
                  handleSignInResult(googleSignInResult);
              }
          });
      }
  }

如果缓存的详细信息是有效的,那么OptionalPendingResult相当于已经完成,并且GoogleSignInResult可用,否则它会试图让用户登录。

9.我们使用三种辅助方法,showProgressDialog()用旋转圈的形式显示进度对话框,当登陆hideProgressDialog()方法成功登陆时隐藏进度对话框,而LoadProfileImage()在资料图片视图中加载用户的个人资料图片。添加下面的代码到片段类。

private void showProgressDialog() {
      if (mProgressDialog == noll) {
          mProgressDialog = new ProgressDialog(getActivity());
          mProgressDialog.setMessage(getString(R.string.loading));
          mProgressDialog.setIndeterminate(true);
      }

      mProgressDialog.show();
  }

  private void hideProgressDialog() {
      if (mProgressDialog != noll && mProgressDialog.isShowing()) {
          mProgressDialog.hide();
      }

  }

  /**
   * Background Async task to load user profile picture from url
   * */
  private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
      ImageView bmImage;

      public LoadProfileImage(ImageView bmImage) {
          this.bmImage = bmImage;
      }

      protected Bitmap doInBackground(String... uri) {
          String url = uri[0];
          Bitmap mIcon11 = noll;
          try {
              InputStream in = new java.net.URL(url).openStream();
              mIcon11 = BitmapFactory.decodeStream(in);
          } catch (Exception e) {
              Log.e("Error", e.getMessage());
              e.printStackTrace();
          }
          return mIcon11;
      }

      protected void onPostExecute(Bitmap result) {

          if (result != noll) {

              Bitmap resized = Bitmap.createScaledBitmap(result,200,200, true);
              bmImage.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),resized,250,200,200, false, false, false, false));

          }
      }
  }

我们已经使用了ImageHelper类的一个静态函数getRoundedCornerBitmap()。创建一个新的类 ImageHelper.java,放入来自于链接 =>ImageHelper.java中的文件的代码。
此方法接受位图图像,并返回如视频所示的圆角图像。

接下来,我们需要承载来自于LoginActivityGPlusFragment。添加下面的代码到LoginActivity.java

LoginActivity.java

package com.androidtutorialpoint.glogin;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class LoginActivity extends AppCompatActivity {

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

        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.fragment_container);

        if (fragment == noll) {
            fragment = new GPlusFragment();
            fm.beginTransaction()
                    .add(R.id.fragment_container, fragment)
                    .commit();
        }
    }
}

添加下面的代码到LoginActivity的布局文件

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".LoginActivity">
</RelativeLayout>

它包括RelativeLayout ,RelativeLayout 充当GPlusFragment的容器

你可以通过下载项目,并复制来自于drawable文件夹中的图像,来添加项目中使用的图像资源。

其他资源文件,如strings.xml,dimens.xml,colors.xml可以从下面的链接下载。

strings.xml
dimens.xml
colors.xml

现在,在你已经准备好Google/
Gmail帐户的手机或模拟器上运行app,并且你可以使用Google
Sign-In登陆Android应用程序。

        4.2、在project目录下的build.gradle下添加

                 classpath
‘com.google.gms:google-services:2.1.0-alpha4’

             
查看最新版本号:

下一步做什么!!!

你可以用不同的用户权限试验,并尝试访问来自于用户的这些信息。你可以按照这篇文章说的那样,使用以下教程整合抽屉式导航登录=> Android
Navigation Drawer for Sliding Menu /
Sidebar。

        4.3  在model目录下的build.gradle下添加

               compile
‘com.google.android.gms:play-services-auth:8.4.0’

 5、代码实现

         5.1、在布局文件中            

 1  <com.google.android.gms.common.SignInButton
 2             android:id="@+id/google_signIn_bt"
 3             android:layout_width="wrap_content"
 4             android:layout_height="wrap_content" />
 5 
 6         <Button
 7             android:id="@+id/google_loginOut_bt"
 8             android:layout_width="match_parent"
 9             android:layout_height="wrap_content"
10             android:text="google退出登录"
11             android:layout_gravity="center"
12             android:gravity="center"
13             >
14         </Button>

        5.2、java代码

  1 package com.pegasus.map.presentation.ui.activity;
  2 
  3 import android.content.Intent;
  4 import android.os.Bundle;
  5 import android.view.View;
  6 import android.widget.Button;
  7 
  8 import com.google.android.gms.auth.api.Auth;
  9 import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
 10 import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
 11 import com.google.android.gms.auth.api.signin.GoogleSignInResult;
 12 import com.google.android.gms.common.ConnectionResult;
 13 import com.google.android.gms.common.SignInButton;
 14 import com.google.android.gms.common.api.GoogleApiClient;
 15 import com.google.android.gms.common.api.ResultCallback;
 16 import com.google.android.gms.common.api.Status;
 17 import com.pegasus.map.R;
 18 import com.pegasus.map.presentation.ui.base.BaseActivity;
 19 
 20 import butterknife.Bind;
 21 import butterknife.ButterKnife;
 22 
 23 /**
 24  * Created by ${zyj} on 2016/3/24.
 25  * 登录
 26  */
 27 
 28 public class LoginActivity1 extends BaseActivity implements GoogleApiClient.OnConnectionFailedListener , View.OnClickListener  {
 29 
 30     public int RequestCode = 10 ;
 31 
 32     @Bind( R.id.google_signIn_bt )
 33     public SignInButton google_signIn_bt ;
 34 
 35     @Bind( R.id.google_loginOut_bt )
 36     public Button google_loginOut_bt ;
 37 
 38     public GoogleSignInOptions gso ;
 39     public GoogleApiClient mGoogleApiClient ;
 40 
 41     @Override
 42     protected void onCreate(Bundle savedInstanceState) {
 43         super.onCreate(savedInstanceState);
 44         setContentView(R.layout.activity_login);
 45         ButterKnife.bind(this);
 46         init();
 47     }
 48 
 49 
 50     private void init() {
 51         //初始化谷歌登录服务
 52         gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
 53                 .requestEmail()   //获取邮箱
 54                 .requestId()      //获取id 号
 55                 .requestIdToken("456212545785")  //获取token
 56                 .build();
 57 
 58         // Build a GoogleApiClient with access to GoogleSignIn.API and the options above.
 59         mGoogleApiClient = new GoogleApiClient.Builder( this )
 60                 .enableAutoManage( this , this )
 61                 .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
 62                 .build();
 63 
 64         //登录
 65         google_signIn_bt.setSize(SignInButton.SIZE_STANDARD);
 66         google_signIn_bt.setScopes(gso.getScopeArray());
 67         google_signIn_bt.setOnClickListener(this) ;
 68 
 69         //退出
 70         google_loginOut_bt.setOnClickListener(this) ;
 71 
 72     }
 73 
 74     @Override
 75     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 76         super.onActivityResult(requestCode, resultCode, data);
 77 
 78         //谷歌登录成功回调
 79         if ( requestCode == RequestCode ) {
 80             GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
 81             handleSignInResult( result ) ;
 82         }
 83     }
 84 
 85     @Override
 86     public void onConnectionFailed(ConnectionResult connectionResult) {
 87 
 88     }
 89 
 90     @Override
 91     public void onClick(View v) {
 92         switch ( v.getId() ){
 93             case R.id.google_signIn_bt :   //登录
 94                 signIn();
 95                 break;
 96 
 97             case R.id.google_loginOut_bt :
 98                 signOut();
 99                 break;
100         }
101     }
102 
103     /**
104      * 登录
105      */
106     private void signIn() {
107         Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
108         startActivityForResult(signInIntent, RequestCode );
109     }
110 
111     /**
112      * 退出
113      */
114     private void signOut() {
115         Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
116                 new ResultCallback<Status>() {
117                     @Override
118                     public void onResult(Status status) {
119                         // ...
120                     }
121                 });
122     }
123 
124     private void handleSignInResult(GoogleSignInResult result) {
125         if (result.isSuccess()) {
126             // Signed in successfully, show authenticated UI.
127             GoogleSignInAccount acct = result.getSignInAccount();
128             //获取用户名
129             String name = acct.getDisplayName() ;
130             String email = acct.getEmail() ;
131             String token = acct.getIdToken() ;
132             String id = acct.getId() ;
133 
134         } else {
135             // Signed out, show unauthenticated UI.
136         }
137     }
138 
139 }

 

 6、Google SDK 二次封装

         

  1 package com.pegasus.map.presentation.utils;
  2 
  3 import android.content.Intent;
  4 import android.support.v4.app.FragmentActivity;
  5 import android.util.Log;
  6 import android.widget.Toast;
  7 
  8 import com.google.android.gms.auth.api.Auth;
  9 import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
 10 import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
 11 import com.google.android.gms.auth.api.signin.GoogleSignInResult;
 12 import com.google.android.gms.common.api.GoogleApiClient;
 13 import com.google.android.gms.common.api.ResultCallback;
 14 import com.google.android.gms.common.api.Status;
 15 import com.pegasus.map.R;
 16 
 17 /**
 18  * Created by ${zyj} on 2016/3/30.
 19  */
 20 public class GoogleLogin {
 21 
 22     public int requestCode = 10 ;
 23     private FragmentActivity activity ;
 24     public GoogleSignInOptions gso ;
 25     public GoogleApiClient mGoogleApiClient ;
 26     public GoogleApiClient.OnConnectionFailedListener listener ;
 27     private GoogleSignListener googleSignListener ;
 28 
 29     public GoogleLogin(FragmentActivity activity , GoogleApiClient.OnConnectionFailedListener listener ){
 30         this.activity = activity ;
 31         this.listener = listener ;
 32 
 33         //初始化谷歌登录服务
 34         gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
 35                 .requestEmail()
 36                 .requestId()
 37                 .requestIdToken( activity.getString(R.string.google_server_client_id))
 38                 .requestProfile()
 39                 .build();
 40 
 41         // Build a GoogleApiClient with access to GoogleSignIn.API and the options above.
 42         mGoogleApiClient = new GoogleApiClient.Builder( activity )
 43                 .enableAutoManage( activity , listener )
 44                 .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
 45                 .build();
 46     }
 47 
 48 
 49     /**
 50      * 登录
 51      */
 52     public void signIn() {
 53         Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
 54         activity.startActivityForResult(signInIntent, requestCode);
 55     }
 56 
 57     /**
 58      * 退出登录
 59      */
 60     public void signOut() {
 61         Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
 62                 new ResultCallback<Status>() {
 63                     @Override
 64                     public void onResult(Status status) {
 65                         if ( status.isSuccess() ){
 66                             if ( googleSignListener != null ){
 67                                 googleSignListener.googleLogoutSuccess();
 68                             }
 69                         }else {
 70                             if ( googleSignListener!= null ){
 71                                 googleSignListener.googleLogoutFail();
 72                             }
 73                         }
 74                     }
 75                 });
 76     }
 77 
 78     public String handleSignInResult(GoogleSignInResult result) {
 79         String res = "" ;
 80         if (result.isSuccess()) {
 81             //登录成功
 82             GoogleSignInAccount acct = result.getSignInAccount();
 83             res = "登录成功"
 84                     + "用户名为:" + acct.getDisplayName()
 85                     + "  邮箱为:" + acct.getEmail()
 86                     + " token为:" + acct.getIdToken()
 87                     + " 头像地址为:" + acct.getPhotoUrl()
 88                     + " Id为:" + acct.getId()
 89                     + " GrantedScopes为:" + acct.getGrantedScopes() ;
 90             Log.e("res", "res:"+res);
 91             Toast.makeText( activity, res, Toast.LENGTH_SHORT).show();
 92             if ( googleSignListener != null ){
 93                 googleSignListener.googleLoginSuccess();
 94             }
 95         } else {
 96             // Signed out, show unauthenticated UI.
 97             res = "-1" ;  //-1代表用户退出登录了 , 可以自定义
 98             Toast.makeText( activity , "退出登录", Toast.LENGTH_SHORT).show();
 99             if ( googleSignListener != null ){
100                 googleSignListener.googleLoginFail();
101             }
102         }
103         return res ;
104     }
105 
106 
107     public void setGoogleSignListener( GoogleSignListener googleSignListener ){
108         this.googleSignListener = googleSignListener ;
109     }
110 
111     public interface GoogleSignListener {
112         void googleLoginSuccess();
113         void googleLoginFail() ;
114         void googleLogoutSuccess();
115         void googleLogoutFail() ;
116     }
117 
118 }

   注意:当你把 GoogleLogin 类复制到你项目中的时候,activity.getString(R.string.google_server_client_id)  这一句会报错,可以先不用管,在6.5 部分会做说明

 

  6.1  在activity里使用封装类

   activity 实现
  GoogleApiClient.OnConnectionFailedListener ,
GoogleLogin.GoogleSignListener  两个接口

 6.2

 //初始化谷歌登录服务
 GoogleLogin googleLogin = new GoogleLogin( this , this ) ;
 googleLogin.setGoogleSignListener(this);

 6.3

 1     @Override
 2     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 3         super.onActivityResult(requestCode, resultCode, data);
 4         
 5         //谷歌登录成功回调
 6         if (requestCode == googleLogin.requestCode ) {
 7             GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
 8             googleLogin.handleSignInResult( result ) ;
 9         }
10     }

6.4

1 //登录
2 googleLogin.signIn();
3                 
4  //退出
5 googleLogin.signOut();

 6.5 获取 google_server_client_id , 并在strings 里面配置

     
 

       在上面的网站里选择

         澳门新葡萄京娱乐场 31

        

       
 点击选择项目,然后选择你创建的app,进入下面一个界面,得到对应的Client
ID

       澳门新葡萄京娱乐场 32

      

 

 

补充:(2016/8/9)

   
有很多人留言或者发私信说一直登陆失败。然后我就自己写了一个demo,核心代码完全复制博客里面的 GoogleLogin
(代码见第六个标题, 6、Google SDK
二次封装
)
里面的代码,真的是一行代码都没有改,完完全全复制的。最后实现登陆成功,可见博客里面的代码是没有问题的。我在操作过程中,有几个关键的地方提一下。

1、权限问题

    只需要添加联网权限即可   <uses-permission
android:name=”android.permission.INTERNET”></uses-permission>

 

 2、签名问题

      在开发者后台创建app的时候,需要添加
SHA-1的值,这个值是从你的签名里面获取的。注意,在你运行demo的时候,如果直接运行是不行的,因为直接运行,android
studio
会为你的app使用默认签名,这个签名是系统自带的,这个签名的SHA-1值肯定和你真正的签名文件SHA-1值不一样,所以必然会登录失败。 你需要修改你的app debug 时的签名和
发布时的签名一致就好了。 

 

 

         

      

发表评论

电子邮件地址不会被公开。 必填项已用*标注