Logging in with Google + in my app - android

I am currently working on a new project that will allow users to log in through Email, Google+ and Facebook. Currently my Google+ login button clicks, but not operational. I looked at demos from Google and other Samples and still can't figure this thing out. Please Help!!
GoogleActivity
package com.wny.wecare;
import java.io.InputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;
public class GoogleActivity extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener {
private static final int RC_SIGN_IN = 0;
// Logcat tag
private static final String TAG = "MainActivity";
// Profile pic image size in pixels
private static final int PROFILE_PIC_SIZE = 400;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
/**
* A flag indicating that a PendingIntent is in progress and prevents us
* from starting further intents.
*/
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout llProfileLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSignIn = (SignInButton) findViewById(R.id.btnGplus);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
txtName = (TextView) findViewById(R.id.txtName);
txtEmail = (TextView) findViewById(R.id.txtEmail);
llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
// Button click listeners
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
#Override
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get user's information
getProfileInformation();
// Update the UI after signin
updateUI(true);
}
/**
* Updating the UI, showing/hiding buttons and profile layout
* */
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
}
}
/**
* Fetching user's information name, email, profile pic
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(email);
// by default the profile url gives 50x50 px image only
// we can replace the value with whatever dimension we want by
// replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0,
personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* Button on click listener
* */
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnGplus:
// Signin button clicked
signInWithGplus();
break;
}
}
/**
* Sign-in into google
* */
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Sign-out from google
* */
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
/**
* Revoking access from google
* */
private void revokeGplusAccess() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status arg0) {
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
/**
* 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... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
MainActivity
package com.wny.wecare;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.app.Activity;
public class MainActivity extends Activity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wny.wecare"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".GoogleActivity"
android:label="Login Account">
</activity>
<activity android:name="com.facebook.LoginActivity">
</activity>
<activity android:name=".HomeActivity"
android:label="Home Activity">
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
</application>
</manifest>
Login_activity
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".GoogleActivity"
android:background="#drawable/wnylogo">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="65dp"
android:background="#drawable/linearlayout_bg"
android:orientation="vertical"
android:padding="10dp" >
<Button
android:id="#+id/btnGplus"
style="#style/ButtonText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="#drawable/layers_gplus_button_bg"
android:paddingBottom="10dp"
android:paddingLeft="30dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="#string/common_signin_button_text_long" />
<com.facebook.widget.LoginButton
android:id="#+id/btnFb"
style="#style/ButtonText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="#drawable/layers_fb_button_bg"
android:paddingBottom="10dp"
android:paddingLeft="30dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="Sign in with Facebook" />
</LinearLayout>
<TextView
android:id="#+id/welcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="17dp"
android:textSize="25sp"
android:textStyle="bold" />
<LinearLayout
android:id="#+id/llProfile"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal"
android:weightSum="3"
android:visibility="gone">
<ImageView
android:id="#+id/imgProfilePic"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:layout_weight="2" >
<TextView
android:id="#+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="20dp" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18dp" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="#+id/userLink"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/welcome"
android:layout_centerHorizontal="true"
android:autoLink="all"
android:textAppearance="?android:attr/textAppearanceLarge" >
</TextView>
</RelativeLayout>

Follow this link. It seems you are not filling Email Address and Product Name in "Consent Screen" of Google API Console.

Related

listview not showing my message after launching activity [duplicate]

This question already has answers here:
FirebaseListAdapter not pushing individual items for chat app - Firebase-Ui 3.1
(2 answers)
Closed 4 years ago.
anyone is thier who can help me ? listview not showing my message after launching activity ,i am trying to create chatting application , i have created chat application successfully , then later for advertising i have added some dependencis and it start to give me error in adapter code ..
first i think something problem in list adapter please check my main activity and other classes
package com.intraday.geeks;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.text.format.DateFormat;
import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.database.FirebaseListAdapter;
import com.firebase.ui.database.FirebaseListOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
public class MainActivity extends AppCompatActivity {
private static int SIGN_IN_REQUEST_CODE = 1;
private FirebaseListAdapter<ChatMessage> adapter;
RelativeLayout activity_Main;
FloatingActionButton fab;
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.menu_sign_out)
{
AuthUI.getInstance().signOut(this).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Snackbar.make(activity_Main,"You have been signed out.", Snackbar.LENGTH_SHORT).show();
finish();
}
});
}
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == SIGN_IN_REQUEST_CODE)
{
if(resultCode == RESULT_OK)
{
Snackbar.make(activity_Main,"Successfully signed in.Welcome!", Snackbar.LENGTH_SHORT).show();
displayChatMessage();
}
else{
Snackbar.make(activity_Main,"We couldn't sign you in.Please try again later", Snackbar.LENGTH_SHORT).show();
finish();
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activity_Main = (RelativeLayout)findViewById(R.id.layoutmain);
fab=(FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
EditText input =findViewById(R.id.input);
FirebaseDatabase.getInstance().getReference().push().setValue(new ChatMessage(input.getText().toString(),
FirebaseAuth.getInstance().getCurrentUser().getEmail()));
input.setText("");
}
});
if(FirebaseAuth.getInstance().getCurrentUser()==null) {
startActivityForResult(AuthUI.getInstance().createSignInIntentBuilder().build(),SIGN_IN_REQUEST_CODE);
}
else{
Snackbar.make(activity_Main,"Welcome "+FirebaseAuth.getInstance().getCurrentUser().getEmail(),Snackbar.LENGTH_SHORT).show();
//Load content
displayChatMessage();
}
}
private void displayChatMessage() {
ListView listOfMessage = (ListView)findViewById(R.id.list_of_message);
Query query = FirebaseDatabase.getInstance().getReference().child("chats");
FirebaseListOptions<ChatMessage> options =
new FirebaseListOptions.Builder<ChatMessage>()
.setQuery(query, ChatMessage.class)
.setLayout(android.R.layout.simple_list_item_1)
.build();
adapter = new FirebaseListAdapter<ChatMessage>(options)
{
#Override
protected void populateView(View v, ChatMessage model, int position) {
//Get references to the views of list_item.xml
TextView messageText, messageUser, messageTime;
messageText = (TextView) v.findViewById(R.id.message_Text);
messageUser = (TextView) v.findViewById(R.id.message_user);
messageTime = (TextView) v.findViewById(R.id.message_time);
messageText.setText(model.getMessageText());
messageUser.setText(model.getMessageuser());
messageTime.setText(DateFormat.format("dd-MM-yyyy (HH:mm:ss)", model.getMessageTime()));
}
};
listOfMessage.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
this is my chatMessage class
package com.intraday.geeks;
import java.util.Date;
/**
* Created by Administrator on 6/8/2018.
*/
public class ChatMessage {
private String MessageText;
private String Messageuser;
private Long MessageTime;
public ChatMessage(String messageText, String messageuser) {
this.MessageText = messageText;
this.Messageuser = messageuser;
MessageTime= new Date().getTime();
}
public ChatMessage() {
}
public String getMessageText() {
return MessageText;
}
public void setMessageText(String messageText) {
MessageText = messageText;
}
public String getMessageuser() {
return Messageuser;
}
public void setMessageuser(String messageuser) {
Messageuser = messageuser;
}
public Long getMessageTime() {
return MessageTime;
}
public void setMessageTime(Long messageTime) {
MessageTime = messageTime;
}
}
this is my MainActivity Layout
<?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:id="#+id/layoutmain"
android:layout_width="match_parent"
android:background="#drawable/gg"
android:layout_height="match_parent"
tools:context="com.intraday.geeks.MainActivity">
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:src="#drawable/ic_send"
android:id="#+id/fab"
android:tint="#android:color/white"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
app:fabSize="mini"/>
<EditText
android:id="#+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/textInputLayout"
android:layout_alignParentStart="true"
android:hint="message"
android:textColor="#ffff"
android:textColorHint="#ffff"
/>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/fab"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:id="#+id/textInputLayout" />
<ListView
android:id="#+id/list_of_message"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_above="#id/fab"
android:stackFromBottom="true"
android:dividerHeight="20dp"
android:divider="#android:color/transparent"
android:layout_width="match_parent"
android:layout_marginBottom="16dp"
android:layout_height="match_parent"></ListView>
</RelativeLayout>
**this is my list_iteam . 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:id="#+id/scroll"
android:background="#drawable/border_style"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="10dp"
android:id="#+id/message_user"
android:visibility="invisible"/>
<TextView
android:id="#+id/message_time"
android:layout_width="fill_parent"
android:layout_height="18dp"
android:layout_alignParentBottom="#id/message_Text"
android:textColor="#ffff"
android:textSize="15dp"
/>
<TextView
android:id="#+id/message_Text"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/message_time"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"
android:textColor="#ffff"
android:textSize="20sp"
android:textStyle="bold"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="90dp" />
</RelativeLayout>
this is my Menifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.intraday.geeks">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- This meta-data tag is required to use Google Play Services. -->
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<!-- Include the AdActivity configChanges and theme. -->
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
</application>
</manifest>
Add this
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}

About Get google services [duplicate]

Since Android 4.2.2 it's possible to run Google Services on the Android Emulator. I'm currently making an Android app and made a test project to see if I can get Google+ sign-in and sign-out to work.
I've followed the following tutorial:
http://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/
With extra info used from the following tutorials/sites:
https://developers.google.com/+/mobile/android/getting-started
https://developers.google.com/+/mobile/android/sign-in
http://developer.android.com/google/play-services/setup.html#Setup
This generated the following code:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testproject_gmaillogin"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name="com.example.testproject_gmaillogin.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TestProject_GmailLogin</string>
<string name="action_settings">Settings</string>
<string name="profile_pic_description">Google Profile Picture</string>
<string name="btn_logout_from_google">Logout from Google</string>
<string name="btn_revoke_access">Revoke Access</string>
</resources>
activity_main.xml:
<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="16dp"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/profile_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal"
android:weightSum="3"
android:visibility="gone">
<ImageView
android:id="#+id/img_profile_pic"
android:contentDescription="#string/profile_pic_description"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:layout_weight="2" >
<TextView
android:id="#+id/txt_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="20sp" />
<TextView
android:id="#+id/txt_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
<com.google.android.gms.common.SignInButton
android:id="#+id/btn_sign_in"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"/>
<Button
android:id="#+id/btn_sign_out"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_logout_from_google"
android:visibility="gone"
android:layout_marginBottom="10dp"/>
<Button
android:id="#+id/btn_revoke_access"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_revoke_access"
android:visibility="gone" />
</LinearLayout>
MainActivity.java:
package com.example.testproject_gmaillogin;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;
import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, OnClickListener
{
// Logcat tag
private static final String TAG = "MainActivity";
// Profile pix image size in pixels
private static final int PROFILE_PIC_SIZE = 400;
// Request code used to invoke sign in user interactions
private static final int RC_SIGN_IN = 0;
// Client used to interact with Google APIs
private GoogleApiClient mGoogleApiClient;
// A flag indicating that a PendingIntent is in progress and prevents
// us from starting further intents
private boolean mIntentInProgress;
// Track whether the sign-in button has been clicked so that we know to resolve
// all issues preventing sign-in without waiting
private boolean mSignInClicked;
// Store the connection result from onConnectionFailed callbacks so that we can
// resolve them when the user clicks sign-in
private ConnectionResult mConnectionResult;
// The used UI-elements
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout profileLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the UI-elements
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
imgProfilePic = (ImageView) findViewById(R.id.img_profile_pic);
txtName = (TextView) findViewById(R.id.txt_name);
txtEmail = (TextView) findViewById(R.id.txt_email);
profileLayout = (LinearLayout) findViewById(R.id.profile_layout);
// Set the Button onClick-listeners
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build();
}
#Override
protected void onStart(){
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop(){
super.onStop();
if(mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
#Override
public void onClick(View view){
switch(view.getId()){
case R.id.btn_sign_in:
signInWithGPlus();
break;
case R.id.btn_sign_out:
signOutFromGPlus();
break;
case R.id.btn_revoke_access:
revokeGPlusAccess();
break;
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if(!result.hasResolution()){
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
return;
}
if(!mIntentInProgress){
// Store the ConnectionResult so that we can use it later when the user clicks 'sign-in'
mConnectionResult = result;
if(mSignInClicked)
// The user has already clicked 'sign-in' so we attempt to resolve all
// errors until the user is signed in, or they cancel
resolveSignInErrors();
}
}
#Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent){
if(requestCode == RC_SIGN_IN && responseCode == RESULT_OK)
SignInClicked = true;
mIntentInProgress = false;
if(!mGoogleApiClient.isConnecting())
mGoogleApiClient.connect();
}
}
#Override
public void onConnected(Bundle connectionHint) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get all the user's information
getProfileInformation();
// Update the UI after sign-in
updateUI(true);
}
#Override
public void onConnectionSuspended(int cause){
mGoogleApiClient.connect();
updateUI(false);
}
// Updating the UI, showing/hiding buttons and profile layout
private void updateUI(boolean isSignedIn){
if(isSignedIn){
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
profileLayout.setVisibility(View.VISIBLE);
}
else{
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
profileLayout.setVisibility(View.GONE);
}
}
// Sign-in into Google
private void signInWithGPlus(){
if(!mGoogleApiClient.isConnecting()){
mSignInClicked = true;
resolveSignInErrors();
}
}
// Method to resolve any sign-in errors
private void resolveSignInErrors(){
if(mConnectionResult.hasResolution()){
try{
mIntentInProgress = true;
//Toast.makeText(this, "Resolving Sign-in Errors", Toast.LENGTH_SHORT).show();
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
}
catch(SendIntentException e){
// The intent was cancelled before it was sent. Return to the default
// state and attempt to connect to get an updated ConnectionResult
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
// Fetching the user's infromation name, email, profile pic
private void getProfileInformation(){
try{
if(Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null){
Person currentPerson = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String personEmail = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", "
+ "plusProfile: " + personGooglePlusProfile + ", "
+ "email: " + personEmail + ", "
+ "image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(personEmail);
// by default the profile url gives 50x50 px image,
// but we can replace the value with whatever dimension we
// want by replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0, personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
}
else{
Toast.makeText(getApplicationContext(), "Person information is null", Toast.LENGTH_LONG).show();
}
}
catch(Exception ex){
ex.printStackTrace();
}
}
// Sign-out from Google
private void signOutFromGPlus(){
if(mGoogleApiClient.isConnected()){
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
// Revoking access from Google
private void revokeGPlusAccess(){
if(mGoogleApiClient.isConnected()){
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>(){
#Override
public void onResult(Status s){
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings)
return true;
return super.onOptionsItemSelected(item);
}
}
LoadProfileImage.java:
package com.example.testproject_gmaillogin;
import java.io.InputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
/**
* Background async task to load user profile picture from url
**/
public class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
private ImageView bmImage;
public LoadProfileImage(ImageView bmImage){
this.bmImage = bmImage;
}
#Override
protected Bitmap doInBackground(String... urls){
String urlDisplay = urls[0];
Bitmap mIcon11 = null;
try{
InputStream in = new java.net.URL(urlDisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
}
catch(Exception ex){
Log.e("Error", ex.getMessage());
ex.printStackTrace();
}
return mIcon11;
}
#Override
protected void onPostExecute(Bitmap result){
bmImage.setImageBitmap(result);
}
}
The other steps I did were:
At https://console.developers.google.com/project I've created a project with:
Google+ API on:
And a Client ID created with the correct SHA1 and exact same namespace as the project:
At Eclipse:
I've installed the google-play-services library:
And added it to the project:
I've also created an Emulator with version 4.4.2:
But when I run the app I get the following error, and this error keeps popping up when I click on the button:
Anyone has any idea where it goes wrong? Thanks in advance for the responses.
Ok, after trying some things it turned out I had one last option not correctly checked, which wasn't mentioned anywhere in the tutorial(s)..
Instead of Android 4.4.2 as Project Build Target & Emulator Target, I've selected Google APIs 4.4.2. Now I don't get the error of Google Play services anymore.
I do get a NullPointerException though, but at least I can continue.. ;)
EDIT: Fixed the NullPointerException and modified the code in my original post. Everything works as it should now and I hope this post helps other people with the same (or other) errors using google play services sign-in using an Android Emulator.
Try using the Goole APIs API level 19 as emulator target instead of normal API level 19.

how to solve unable to instantiate activity with google play service?

i follow this tutorial : http://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/
but i always get this error
08-28 23:37:38.557: E/AndroidRuntime(28591): java.lang.RuntimeException: Unable to instantiate activity
ComponentInfo{com.foo.app/com.foo.app.LoginActivity}:
java.lang.ClassNotFoundException: Didn't find class
"com.foo.app.LoginActivity" on path: DexPathList[[zip file
"/data/app/com.foo.app-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.foo.app-2,
/vendor/lib, /system/lib]]
why this happend? and how to solve this?
this only happend if i navigate to activity with google play service imported
manifest :
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="com.foo.app.SplashActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.foo.app.LoginActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.foo.app.Login" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
LoginActivity.java
package com.foo.app;
import java.io.InputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;
public class LoginActivity extends Activity implements OnClickListener, ConnectionCallbacks, OnConnectionFailedListener {
private static final int RC_SIGN_IN = 0;
// Logcat tag
private static final String TAG = "MainActivity";
// Profile pic image size in pixels
private static final int PROFILE_PIC_SIZE = 400;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
/**
* A flag indicating that a PendingIntent is in progress and prevents us
* from starting further intents.
*/
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout llProfileLayout;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
txtName = (TextView) findViewById(R.id.txtName);
txtEmail = (TextView) findViewById(R.id.txtEmail);
llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
// Button click listeners
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
#Override
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get user's information
getProfileInformation();
// Update the UI after signin
updateUI(true);
}
/**
* Updating the UI, showing/hiding buttons and profile layout
* */
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
}
}
/**
* Fetching user's information name, email, profile pic
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(email);
// by default the profile url gives 50x50 px image only
// we can replace the value with whatever dimension we want by
// replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0,
personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* Button on click listener
* */
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign_in:
// Signin button clicked
signInWithGplus();
break;
case R.id.btn_sign_out:
// Signout button clicked
signOutFromGplus();
break;
case R.id.btn_revoke_access:
// Revoke access button clicked
revokeGplusAccess();
break;
}
}
/**
* Sign-in into google
* */
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Sign-out from google
* */
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
/**
* Revoking access from google
* */
private void revokeGplusAccess() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status arg0) {
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
/**
* 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... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
<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="16dp"
tools:context=".LoginActivity" >
<LinearLayout
android:id="#+id/llProfile"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal"
android:weightSum="3"
android:visibility="gone">
<ImageView
android:id="#+id/imgProfilePic"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:layout_weight="2" >
<TextView
android:id="#+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="20dp" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18dp" />
</LinearLayout>
</LinearLayout>
<com.google.android.gms.common.SignInButton
android:id="#+id/btn_sign_in"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"/>
<Button
android:id="#+id/btn_sign_out"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_logout_from_google"
android:visibility="gone"
android:layout_marginBottom="10dp"/>
<Button
android:id="#+id/btn_revoke_access"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_revoke_access"
android:visibility="gone" />
</LinearLayout>
and this is how i navigate
startActivity(new Intent("com.foo.app.Login"));
finish();
my error :
08-29 13:31:55.668: E/AndroidRuntime(9232): FATAL EXCEPTION: main
08-29 13:31:55.668: E/AndroidRuntime(9232):
java.lang.RuntimeException: Unable to instantiate activity
ComponentInfo{com.foo.app/com.foo.app.LoginActivity}:
java.lang.ClassNotFoundException: Didn't find class
"com.foo.app.LoginActivity" on path: DexPathList[[zip file
"/data/app/com.foo.app-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.foo.app-1,
/vendor/lib, /system/lib]] 08-29 13:31:55.668: E/AndroidRuntime(9232):
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140)
08-29 13:31:55.668: E/AndroidRuntime(9232): at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2264)
08-29 13:31:55.668: E/AndroidRuntime(9232): at
android.app.ActivityThread.access$600(ActivityThread.java:144) 08-29
13:31:55.668: E/AndroidRuntime(9232): at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1259)
08-29 13:31:55.668: E/AndroidRuntime(9232): at
android.os.Handler.dispatchMessage(Handler.java:99) 08-29
13:31:55.668: E/AndroidRuntime(9232): at
android.os.Looper.loop(Looper.java:137) 08-29 13:31:55.668:
E/AndroidRuntime(9232): at
android.app.ActivityThread.main(ActivityThread.java:5152) 08-29
13:31:55.668: E/AndroidRuntime(9232): at
java.lang.reflect.Method.invokeNative(Native Method) 08-29
13:31:55.668: E/AndroidRuntime(9232): at
java.lang.reflect.Method.invoke(Method.java:525) 08-29 13:31:55.668:
E/AndroidRuntime(9232): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:744)
08-29 13:31:55.668: E/AndroidRuntime(9232): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 08-29
13:31:55.668: E/AndroidRuntime(9232): at
dalvik.system.NativeStart.main(Native Method) 08-29 13:31:55.668:
E/AndroidRuntime(9232): Caused by: java.lang.ClassNotFoundException:
Didn't find class "com.foo.app.LoginActivity" on path:
DexPathList[[zip file
"/data/app/com.foo.app-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.foo.app-1,
/vendor/lib, /system/lib]] 08-29 13:31:55.668: E/AndroidRuntime(9232):
at
dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)
08-29 13:31:55.668: E/AndroidRuntime(9232): at
java.lang.ClassLoader.loadClass(ClassLoader.java:501) 08-29
13:31:55.668: E/AndroidRuntime(9232): at
java.lang.ClassLoader.loadClass(ClassLoader.java:461) 08-29
13:31:55.668: E/AndroidRuntime(9232): at
android.app.Instrumentation.newActivity(Instrumentation.java:1061)
08-29 13:31:55.668: E/AndroidRuntime(9232): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2131)
08-29 13:31:55.668: E/AndroidRuntime(9232): ... 11 more
startActivity(new Intent(calleractivty.this, LoginActivity.class));
and in the manifest
<activity android:name=".SplashActivity" ...
if you look and the stack
Unable to instantiate activity
ComponentInfo{com.foo.app/com.foo.app.LoginActivity}: it tries to reach wrong path
then it should work.

Android Emulator: This app won't run without Google Play services

Since Android 4.2.2 it's possible to run Google Services on the Android Emulator. I'm currently making an Android app and made a test project to see if I can get Google+ sign-in and sign-out to work.
I've followed the following tutorial:
http://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/
With extra info used from the following tutorials/sites:
https://developers.google.com/+/mobile/android/getting-started
https://developers.google.com/+/mobile/android/sign-in
http://developer.android.com/google/play-services/setup.html#Setup
This generated the following code:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testproject_gmaillogin"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name="com.example.testproject_gmaillogin.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TestProject_GmailLogin</string>
<string name="action_settings">Settings</string>
<string name="profile_pic_description">Google Profile Picture</string>
<string name="btn_logout_from_google">Logout from Google</string>
<string name="btn_revoke_access">Revoke Access</string>
</resources>
activity_main.xml:
<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="16dp"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/profile_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal"
android:weightSum="3"
android:visibility="gone">
<ImageView
android:id="#+id/img_profile_pic"
android:contentDescription="#string/profile_pic_description"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:layout_weight="2" >
<TextView
android:id="#+id/txt_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="20sp" />
<TextView
android:id="#+id/txt_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
<com.google.android.gms.common.SignInButton
android:id="#+id/btn_sign_in"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"/>
<Button
android:id="#+id/btn_sign_out"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_logout_from_google"
android:visibility="gone"
android:layout_marginBottom="10dp"/>
<Button
android:id="#+id/btn_revoke_access"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_revoke_access"
android:visibility="gone" />
</LinearLayout>
MainActivity.java:
package com.example.testproject_gmaillogin;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;
import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, OnClickListener
{
// Logcat tag
private static final String TAG = "MainActivity";
// Profile pix image size in pixels
private static final int PROFILE_PIC_SIZE = 400;
// Request code used to invoke sign in user interactions
private static final int RC_SIGN_IN = 0;
// Client used to interact with Google APIs
private GoogleApiClient mGoogleApiClient;
// A flag indicating that a PendingIntent is in progress and prevents
// us from starting further intents
private boolean mIntentInProgress;
// Track whether the sign-in button has been clicked so that we know to resolve
// all issues preventing sign-in without waiting
private boolean mSignInClicked;
// Store the connection result from onConnectionFailed callbacks so that we can
// resolve them when the user clicks sign-in
private ConnectionResult mConnectionResult;
// The used UI-elements
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout profileLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the UI-elements
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
imgProfilePic = (ImageView) findViewById(R.id.img_profile_pic);
txtName = (TextView) findViewById(R.id.txt_name);
txtEmail = (TextView) findViewById(R.id.txt_email);
profileLayout = (LinearLayout) findViewById(R.id.profile_layout);
// Set the Button onClick-listeners
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build();
}
#Override
protected void onStart(){
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop(){
super.onStop();
if(mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
#Override
public void onClick(View view){
switch(view.getId()){
case R.id.btn_sign_in:
signInWithGPlus();
break;
case R.id.btn_sign_out:
signOutFromGPlus();
break;
case R.id.btn_revoke_access:
revokeGPlusAccess();
break;
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if(!result.hasResolution()){
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
return;
}
if(!mIntentInProgress){
// Store the ConnectionResult so that we can use it later when the user clicks 'sign-in'
mConnectionResult = result;
if(mSignInClicked)
// The user has already clicked 'sign-in' so we attempt to resolve all
// errors until the user is signed in, or they cancel
resolveSignInErrors();
}
}
#Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent){
if(requestCode == RC_SIGN_IN && responseCode == RESULT_OK)
SignInClicked = true;
mIntentInProgress = false;
if(!mGoogleApiClient.isConnecting())
mGoogleApiClient.connect();
}
}
#Override
public void onConnected(Bundle connectionHint) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get all the user's information
getProfileInformation();
// Update the UI after sign-in
updateUI(true);
}
#Override
public void onConnectionSuspended(int cause){
mGoogleApiClient.connect();
updateUI(false);
}
// Updating the UI, showing/hiding buttons and profile layout
private void updateUI(boolean isSignedIn){
if(isSignedIn){
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
profileLayout.setVisibility(View.VISIBLE);
}
else{
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
profileLayout.setVisibility(View.GONE);
}
}
// Sign-in into Google
private void signInWithGPlus(){
if(!mGoogleApiClient.isConnecting()){
mSignInClicked = true;
resolveSignInErrors();
}
}
// Method to resolve any sign-in errors
private void resolveSignInErrors(){
if(mConnectionResult.hasResolution()){
try{
mIntentInProgress = true;
//Toast.makeText(this, "Resolving Sign-in Errors", Toast.LENGTH_SHORT).show();
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
}
catch(SendIntentException e){
// The intent was cancelled before it was sent. Return to the default
// state and attempt to connect to get an updated ConnectionResult
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
// Fetching the user's infromation name, email, profile pic
private void getProfileInformation(){
try{
if(Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null){
Person currentPerson = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String personEmail = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", "
+ "plusProfile: " + personGooglePlusProfile + ", "
+ "email: " + personEmail + ", "
+ "image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(personEmail);
// by default the profile url gives 50x50 px image,
// but we can replace the value with whatever dimension we
// want by replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0, personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
}
else{
Toast.makeText(getApplicationContext(), "Person information is null", Toast.LENGTH_LONG).show();
}
}
catch(Exception ex){
ex.printStackTrace();
}
}
// Sign-out from Google
private void signOutFromGPlus(){
if(mGoogleApiClient.isConnected()){
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
// Revoking access from Google
private void revokeGPlusAccess(){
if(mGoogleApiClient.isConnected()){
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>(){
#Override
public void onResult(Status s){
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings)
return true;
return super.onOptionsItemSelected(item);
}
}
LoadProfileImage.java:
package com.example.testproject_gmaillogin;
import java.io.InputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
/**
* Background async task to load user profile picture from url
**/
public class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
private ImageView bmImage;
public LoadProfileImage(ImageView bmImage){
this.bmImage = bmImage;
}
#Override
protected Bitmap doInBackground(String... urls){
String urlDisplay = urls[0];
Bitmap mIcon11 = null;
try{
InputStream in = new java.net.URL(urlDisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
}
catch(Exception ex){
Log.e("Error", ex.getMessage());
ex.printStackTrace();
}
return mIcon11;
}
#Override
protected void onPostExecute(Bitmap result){
bmImage.setImageBitmap(result);
}
}
The other steps I did were:
At https://console.developers.google.com/project I've created a project with:
Google+ API on:
And a Client ID created with the correct SHA1 and exact same namespace as the project:
At Eclipse:
I've installed the google-play-services library:
And added it to the project:
I've also created an Emulator with version 4.4.2:
But when I run the app I get the following error, and this error keeps popping up when I click on the button:
Anyone has any idea where it goes wrong? Thanks in advance for the responses.
Ok, after trying some things it turned out I had one last option not correctly checked, which wasn't mentioned anywhere in the tutorial(s)..
Instead of Android 4.4.2 as Project Build Target & Emulator Target, I've selected Google APIs 4.4.2. Now I don't get the error of Google Play services anymore.
I do get a NullPointerException though, but at least I can continue.. ;)
EDIT: Fixed the NullPointerException and modified the code in my original post. Everything works as it should now and I hope this post helps other people with the same (or other) errors using google play services sign-in using an Android Emulator.
Try using the Goole APIs API level 19 as emulator target instead of normal API level 19.

layout and view Formatting in android

i have created an application which uses the google plus sign in !! so when i sign in with google plus, it displays the fetched profile name , email id and the profile picture !!
but my problem is that the layout or you can say formatting is not working out !!
i want the profile picture besides the email id and the profile name !!
profile picture goes way down to the end of the page and i have to use a scroll view to get it displayed by scrolling other wise it wont show up !! please help !! i cant attach screenshots as it needs 10 reputations !!
activity_login.xml
<ScrollView 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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/llProfile"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal"
android:weightSum="3"
android:visibility="gone">
<ImageView
android:id="#+id/imgProfilePic"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:contentDescription="#string/profile_pic"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:layout_weight="2" >
<TextView
android:id="#+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="20sp" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
<com.google.android.gms.common.SignInButton
android:id="#+id/btn_sign_in"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"/>
<Button
android:id="#+id/btn_sign_out"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_logout_from_google"
android:visibility="gone"
android:layout_marginBottom="10dp"/>
<Button
android:id="#+id/btn_revoke_access"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/btn_revoke_access"
android:visibility="gone" />
</LinearLayout>
</ScrollView>
LoginActicity.java
package com.krrysis.dogbreedinfo;
import java.io.InputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;
public class LoginActivity extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener {
private static final int RC_SIGN_IN = 0;
// Logcat tag
private static final String TAG = "MainActivity";
// Profile pic image size in pixels
private static final int PROFILE_PIC_SIZE = 400;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
/**
* A flag indicating that a PendingIntent is in progress and prevents us
* from starting further intents.
*/
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout llProfileLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
txtName = (TextView) findViewById(R.id.txtName);
txtEmail = (TextView) findViewById(R.id.txtEmail);
llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
// Button click listeners
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
#Override
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get user's information
getProfileInformation();
// Update the UI after signin
updateUI(true);
}
/**
* Updating the UI, showing/hiding buttons and profile layout
* */
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
}
}
/**
* Fetching user's information name, email, profile pic
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(email);
// by default the profile url gives 50x50 px image only
// we can replace the value with whatever dimension we want by
// replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0,
personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* Button on click listener
* */
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign_in:
// Signin button clicked
signInWithGplus();
break;
case R.id.btn_sign_out:
// Signout button clicked
signOutFromGplus();
break;
case R.id.btn_revoke_access:
// Revoke access button clicked
revokeGplusAccess();
break;
}
}
/**
* Sign-in into google
* */
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Sign-out from google
* */
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
/**
* Revoking access from google
* */
private void revokeGplusAccess() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status arg0) {
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
/**
* 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... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
sign in button
Permissions
Fetched Profile
SEE ? , i have to scroll down to see this buttons
instead i want the formatting to be this way particularly for the small screen sized devices having low resolutions cus this have to scroll a way down
Try this
<LinearLayout
android:id="#+id/llProfile"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal"
android:visibility="visible" >
<ImageView
android:id="#+id/imgProfilePic"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:contentDescription="#string/profile_pic"
android:padding="8dip"
android:src="#drawable/ic_launcher" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical" >
<TextView
android:id="#+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="20sp" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>

Categories

Resources