透過選取手機內紀錄的Google帳號,再向GOOGLE取得Token,
接著取得其他基本資料。
程式分成2個畫面:
MainActivity.java是用來做選取帳號以及取得Token。
HomeActivity.java是用來顯示取得的基本資料。
以及取得資料所用的AsyncTask
GetUsernameTask.java
首先確認把google Play Service加入到專案build.gradle(Module: app )
dependencies {
compile 'com.google.android.gms:play-services-auth:8.4.0'
}
接下來是Layout
activity_main.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:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="7dp" >
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Home Page"
android:textSize="24sp" />
<TextView
android:id="@+id/textViewNameLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textViewTitle"
android:layout_marginTop="15dp"
android:text="Name:"
android:textSize="18sp" />
<TextView
android:id="@+id/textViewNameValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewTitle"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
android:layout_toRightOf="@id/textViewNameLabel"
android:text="Name:"
android:textSize="18sp" />
<TextView
android:id="@+id/textViewEmailLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/textViewNameLabel"
android:layout_marginTop="15dp"
android:text="Email:"
android:textSize="18sp" />
<TextView
android:id="@+id/textViewEmailValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewNameValue"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
android:layout_toRightOf="@id/textViewEmailLabel"
android:text="Email:"
android:textSize="18sp" />
<TextView
android:id="@+id/textViewGenderLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/textViewEmailLabel"
android:layout_marginTop="15dp"
android:text="Gender:"
android:textSize="18sp" />
<TextView
android:id="@+id/textViewGenderValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/textViewGenderLabel"
android:layout_alignLeft="@+id/textViewNameValue"
android:text="Gender:"
android:textSize="18sp" />
<TextView
android:id="@+id/textViewBirthdayLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/textViewGenderLabel"
android:layout_marginTop="15dp"
android:text="Birthday:"
android:textSize="18sp" />
<TextView
android:id="@+id/textViewBirthdayValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/textViewBirthdayLabel"
android:layout_alignBottom="@+id/textViewBirthdayLabel"
android:layout_toRightOf="@+id/textViewBirthdayLabel"
android:text="Birthday:"
android:textSize="18sp" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="@+id/textViewTitle"/>
</RelativeLayout>
context_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.example.boywhychen.googleaccountsignin.MainActivity"
tools:showIn="@layout/activity_main">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Please wait..."
android:textSize="25sp" />
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true" />
</RelativeLayout>
activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.example.boywhychen.googleaccountsignin.MainActivity"
tools:showIn="@layout/activity_main">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Please wait..."
android:textSize="25sp" />
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true" />
</RelativeLayout>
程式碼:
MainActivity.java
package com.example.boywhychen.googleaccountsignin;
import android.accounts.AccountManager;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Toast;
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.AccountPicker;
import com.google.android.gms.common.GooglePlayServicesUtil;
public class MainActivity extends AppCompatActivity {
Context mContext = MainActivity.this;
AccountManager mAccountManager;
String token;
int serverCode;
String SCOPE = "oauth2:https://www.googleapis.com/auth/userinfo.profile";
static final int REQUEST_CODE_PICK_ACCOUNT = 1000;
static final int REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR = 1001;
static final int REQUEST_CODE_RECOVER_FROM_AUTH_ERROR = 1002;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
pickUserAccount();
}
String mEmail; // Received from newChooseAccountIntent(); passed to getToken()
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
// Receiving a result from the AccountPicker
if (resultCode == RESULT_OK) {
mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
getUsername();
// With the account name acquired, go get the auth token
} else if (resultCode == RESULT_CANCELED) {
// The account picker dialog closed without selecting an account.
// Notify users that they must pick an account to proceed.
Toast.makeText(this, R.string.pick_account, Toast.LENGTH_SHORT).show();
} else if ((requestCode == REQUEST_CODE_RECOVER_FROM_AUTH_ERROR ||
requestCode == REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR)
&& resultCode == RESULT_OK) {
// Receiving a result that follows a GoogleAuthException, try auth again
getUsername();
}
}
}
private void pickUserAccount() {
String[] accountTypes = new String[]{"com.google"};
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
accountTypes, false, null, null, null, null);
startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
}
/**
* Attempts to retrieve the username.
* If the account is not yet known, invoke the picker. Once the account is known,
* start an instance of the AsyncTask to get the auth token and do work with it.
*/
private void getUsername() {
if (mEmail == null) {
pickUserAccount();
} else {
if (checkInternetConnection()) {
new GetUsernameTask(MainActivity.this, mEmail, SCOPE).execute();
} else {
Toast.makeText(this, R.string.not_online, Toast.LENGTH_LONG).show();
}
}
}
/**
* This method is a hook for background threads and async tasks that need to
* provide the user a response UI when an exception occurs.
*/
public void handleException(final Exception e) {
// Because this call comes from the AsyncTask, we must ensure that the following
// code instead executes on the UI thread.
runOnUiThread(new Runnable() {
@Override
public void run() {
if (e instanceof GooglePlayServicesAvailabilityException) {
// The Google Play services APK is old, disabled, or not present.
// Show a dialog created by Google Play services that allows
// the user to update the APK
int statusCode = ((GooglePlayServicesAvailabilityException) e)
.getConnectionStatusCode();
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(statusCode,
MainActivity.this,
REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
dialog.show();
} else if (e instanceof UserRecoverableAuthException) {
// Unable to authenticate, such as when the user has not yet granted
// the app access to the account, but the user can fix this.
// Forward the user to an activity in Google Play services.
Intent intent = ((UserRecoverableAuthException) e).getIntent();
startActivityForResult(intent,
REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
}
}
});
}
//check internet connetion
public boolean checkInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni != null && ni.isConnected()) {
return ni.isConnected();
} else {
return false;
}
}
}
HomeActivity.java
package com.example.boywhychen.googleaccountsignin;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
/**
* @author manish
*
*/
public class HomeActivity extends Activity {
ImageView imageProfile;
TextView textViewName, textViewEmail, textViewGender, textViewBirthday;
String textName, textEmail, textGender, textBirthday, userImageUrl;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
imageProfile = (ImageView) findViewById(R.id.imageView1);
textViewName = (TextView) findViewById(R.id.textViewNameValue);
textViewEmail = (TextView) findViewById(R.id.textViewEmailValue);
textViewGender = (TextView) findViewById(R.id.textViewGenderValue);
textViewBirthday = (TextView) findViewById(R.id.textViewBirthdayValue);
/**
* get user email using intent
*/
Intent intent = getIntent();
textEmail = intent.getStringExtra("email_id");
System.out.println(textEmail);
textViewEmail.setText(textEmail);
/**
* get user data from google account
*/
try {
System.out.println("On Home Page***"
+ GetUsernameTask.GOOGLE_USER_DATA);
JSONObject profileData = new JSONObject(
GetUsernameTask.GOOGLE_USER_DATA);
if (profileData.has("picture")) {
userImageUrl = profileData.getString("picture");
new GetImageFromUrl().execute(userImageUrl);
}
if (profileData.has("name")) {
textName = profileData.getString("name");
textViewName.setText(textName);
}
if (profileData.has("gender")) {
textGender = profileData.getString("gender");
textViewGender.setText(textGender);
}
if (profileData.has("birthday")) {
textBirthday = profileData.getString("birthday");
textViewBirthday.setText(textBirthday);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class GetImageFromUrl extends AsyncTask<String, Void, Bitmap> {
@Override
protected Bitmap doInBackground(String... urls) {
Bitmap map = null;
for (String url : urls) {
map = downloadImage(url);
}
return map;
}
// Sets the Bitmap returned by doInBackground
@Override
protected void onPostExecute(Bitmap result) {
imageProfile.setImageBitmap(result);
}
// Creates Bitmap from InputStream and returns it
private Bitmap downloadImage(String url) {
Bitmap bitmap = null;
InputStream stream = null;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
try {
stream = getHttpConnection(url);
bitmap = BitmapFactory.decodeStream(stream, null, bmOptions);
stream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return bitmap;
}
// Makes HttpURLConnection and returns InputStream
private InputStream getHttpConnection(String urlString)
throws IOException {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return stream;
}
}
}
參考資料:
http://www.androidhub4you.com/2013/09/google-account-integration-in-android.html