2014-05-17 3 views
0

Google 안드로이드 응용 프로그램에 Google 로그인 버튼이 있습니다.조각에있는 Android 로그인 버튼

Google 검색 및 빠른 시작 자습서를 찾았습니다. 다음 코드를 작성했습니다.

<meta-data android:name="com.google.android.gms.version" 
    android:value="@integer/google_play_services_version" /> 

내 조각 XML (fragment_main_menu.xml) :

package com.tuxin.myalcoholist.myalcoholist.myalcoholist; 

import android.app.PendingIntent; 
import android.content.IntentSender; 
import android.support.v7.app.ActionBarActivity; 
import android.support.v7.app.ActionBar; 
import android.support.v4.app.Fragment; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.os.Build; 
import android.widget.Toast; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.SignInButton; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.plus.Plus; 
import com.google.android.gms.plus.model.people.Person; 


public class MainMenuActivity extends ActionBarActivity { 



@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main_menu); 
    if (savedInstanceState == null) { 
     getSupportFragmentManager().beginTransaction() 
       .add(R.id.container, new PlaceholderFragment()) 
       .commit(); 
    } 
} 


@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, 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); 
} 

public void addCocktailClickHandler(View v) { 
} 




/** 
* A placeholder fragment containing a simple view. 
*/ 
public class PlaceholderFragment extends Fragment implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { 

    private SignInButton mSignInButton; 
    private GoogleApiClient mGoogleApiClient; 
    private int mSignInProgress; 
    private PendingIntent mSignInIntent; 
    private int mSignInError; 

    private static final int STATE_DEFAULT = 0; 
    private static final int STATE_SIGN_IN = 1; 
    private static final int STATE_IN_PROGRESS = 2; 
    private static final int RC_SIGN_IN = 0; 


    private static final String SAVED_PROGRESS = "sign_in_progress"; 

    public PlaceholderFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_main_menu, container, false); 
     mSignInButton = (SignInButton) rootView.findViewById(R.id.sign_in_button); 
     mSignInButton.setOnClickListener(this); 
     mGoogleApiClient = buildGoogleApiClient(); 

     return rootView; 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     mGoogleApiClient.connect();; 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     if (mGoogleApiClient.isConnected()) { 
      mGoogleApiClient.disconnect();; 
     } 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putInt(SAVED_PROGRESS, mSignInProgress); 
    } 

    @Override 
    public void onClick(View v) { 
     if (!mGoogleApiClient.isConnecting()) { 
      // We only process button clicks when GoogleApiClient is not transitioning 
      // between connected and not connected. 
      switch (v.getId()) { 
       case R.id.sign_in_button: 
        Toast.makeText(getActivity().getApplicationContext(),"connecting",Toast.LENGTH_LONG).show(); 
        resolveSignInError(); 
        break; 
      } 
     } 
    } 

    private GoogleApiClient buildGoogleApiClient() { 
     // When we build the GoogleApiClient we specify where connected and 
     // connection failed callbacks should be returned, which Google APIs our 
     // app uses and which OAuth 2.0 scopes our app requests. 
     return new GoogleApiClient.Builder(getActivity().getApplicationContext()) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(Plus.API, null) 
       .addScope(Plus.SCOPE_PLUS_LOGIN) 
       .build(); 
    } 


    private void resolveSignInError() { 
     if (mSignInIntent != null) { 
      // We have an intent which will allow our user to sign in or 
      // resolve an error. For example if the user needs to 
      // select an account to sign in with, or if they need to consent 
      // to the permissions your app is requesting. 

      try { 
       // Send the pending intent that we stored on the most recent 
       // OnConnectionFailed callback. This will allow the user to 
       // resolve the error currently preventing our connection to 
       // Google Play services. 
       mSignInProgress = STATE_IN_PROGRESS; 
       startIntentSenderForResult(mSignInIntent.getIntentSender(), 
         RC_SIGN_IN, null, 0, 0, 0); 
      } catch (IntentSender.SendIntentException e) { 
       Toast.makeText(getApplicationContext(),"Sign in intent could not be sent: " 
         + e.getLocalizedMessage(),Toast.LENGTH_LONG).show(); 
       // The intent was canceled before it was sent. Attempt to connect to 
       // get an updated ConnectionResult. 
       mSignInProgress = STATE_SIGN_IN; 
       mGoogleApiClient.connect(); 
      } 
     } else { 
      // Google Play services wasn't able to provide an intent for some 
      // error types, so we show the default Google Play services error 
      // dialog which may still start an intent on our behalf if the 
      // user can resolve the issue. 
      Toast.makeText(getApplicationContext(),"play services error",Toast.LENGTH_LONG).show(); 
     } 
    } 


    @Override 
    public void onConnected(Bundle bundle) { 
     // Retrieve some profile information to personalize our app for the user. 
     Person currentUser = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient); 
     Toast.makeText(getApplicationContext(),currentUser.getDisplayName(),Toast.LENGTH_LONG).show(); 
     mSignInProgress = STATE_DEFAULT; 

    } 

    @Override 
    public void onConnectionSuspended(int i) { 

    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Toast.makeText(getApplicationContext(),"onConnectionFailed: ConnectionResult.getErrorCode() = " 
       + connectionResult.getErrorCode(),Toast.LENGTH_LONG).show(); 

     if (mSignInProgress != STATE_IN_PROGRESS) { 
      // We do not have an intent in progress so we should store the latest 
      // error resolution intent for use when the sign in button is clicked. 
      mSignInIntent = connectionResult.getResolution(); 
      mSignInError = connectionResult.getErrorCode(); 

      if (mSignInProgress == STATE_SIGN_IN) { 
       // STATE_SIGN_IN indicates the user already clicked the sign in button 
       // so we should continue processing errors until the user is signed in 
       // or they click cancel. 
       resolveSignInError(); 
      } 
     } 

     // In this sample we consider the user signed out whenever they do not have 
     // a connection to Google Play services. 
     onSignedOut(); 
    } 

    private void onSignedOut() { 
     Toast.makeText(getApplicationContext(),"signed out",Toast.LENGTH_LONG).show(); 
    } 


    } 
} 
:

<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:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
android:paddingBottom="@dimen/activity_vertical_margin" 
tools:context="com.tuxin.myalcoholist.myalcoholist.myalcoholist.MainMenuActivity$PlaceholderFragment"> 

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/add_drink" 
    android:id="@+id/add_drink" 
    android:layout_alignParentTop="true" 
    android:layout_centerHorizontal="true" 
    android:layout_marginTop="36dp" 
    android:onClick="addStringClickHandler" /> 

<com.google.android.gms.common.SignInButton 
    android:id="@+id/sign_in_button" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" /> 
</RelativeLayout> 

내 메인 메뉴의 활동이 다음 코드가 포함의 AndroidManifest.xml에서

나는 다음과 같은 추가

좋은 플레이 서비스를 제공하기 위해 ARM 에뮬레이터 버전 4.4.2가 있어야한다는 것을 이해했습니다. 에뮬레이터에서 작동하므로 내가 그랬어. 이제 Google 로그인 버튼을 클릭하면 메시지가 "연결"되고 그 후에 "서비스 오류 재생"이 표시된다.

그래서 내가 뭘 잘못하고 있니? 나는 무엇을 놓치고 있습니까?

문제에 관한 정보는 크게 감사하겠습니다.

업데이트

이제 Google api x86 이미지를 사용하고 있습니다. 내가 로그인 할 사용자를 선택한 다음 오류 코드 4와 함께 실패하고 "내부 오류가 발생했습니다"토스트 메시지가 표시됩니다.

먼저 애플리케이션에 서명해야합니까? Google Play가 으로 등록한 애플리케이션을 console.developers.google.com에 연결하는 방법을 아직도 이해하지 못했습니다. 나는 어떤 증명서 또는 무엇이든을 사용하지 않았다.

어떤 생각?

내가 빠른 시작 튜토리얼을 기반으로 새 클라이언트 ID를 만든 또 다른 업데이트 나 패키지 com.tuxin.myalcoholist 를 입력하고 난 ~/.android/디버그를 사용하여 키 도구 명령 (에서 SHA1 문자열을 복사 해왔다. 키 스토어

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

나는 여전히 같은 결과를 얻을 수 있습니다.

+0

특정 에뮬레이터 이미지를 사용해야로 태그 사람은 내 대답을 업데이 트했습니다 – sherpya

+0

"API를 구글". console.developers.google.com의 –

답변

1

난 당신이 에뮬레이터에서 구글의 API 플랫폼을 설치하지 않은 생각합니다. 즉, 당신은 기본적으로 서비스를 나타내는 오류가 발생하는 이유가되지이다 사용할 수 있습니다. docs에서

:

은 구글 API를 플랫폼의 호환 버전을 설치합니다. 에뮬레이터에서 앱을 테스트하려면 Android 4.2.2 (API 17) 이상의 버전 디렉토리를 확장하고 Google API를 선택하고 을 설치합니다. 그런 다음 타겟으로 Google API를 사용하여 새로운 AVD를 만듭니다. 업데이트 1

:에 대해서는 당신이 키 도구에서 잘못된 키 값을 복사 한 경우가 발생할 수 있습니다 토스트 메시지 "내부 오류가 발생했습니다."quick start documentation, 특히 5 단계를 따르십시오.

패키지의 패키지 이름과 SHA1을 사용하면 Google에서 콘솔에서 생성 한 앱과 클라이언트 ID를 연결할 수 있습니다. 클라이언트 ID를 만드는 동안 동일한 정보가 표시됩니다.이 정보는 image에서 볼 수 있습니다.

API 요청은 고객의 Android 기기에서 Google로 직접 전송됩니다. Google은 각 요청이 패키지 이름과 일치하는 Android 응용 프로그램과 아래에 나열된 SHA1 서명 인증서 지문 이름에서 비롯된 것인지 확인합니다.

업데이트 2 : 구글 Play 서비스 설치 한 후 , 당신은 구글 API를 대상으로와 새로운 AVD를 작성 했습니까? 그렇지 않다면 아래 그림과 같이하십시오. isGooglePlayServicesAvailable을 사용하여 Google Play 서비스를 사용할 수 있는지 확인할 수 있습니다.

enter image description here

+0

응용 프로그램 이름을 만들었습니까? 내가 말한 응용 프로그램을 알기 위해 클라이언트 ID 또는 클라이언트 암호를 입력 할 필요가 없습니까? – ufk

+0

@ufk 내 이해에 따라 Google은 Android 애플리케이션에서 발생하는 각 요청이 콘솔에 지정된 인증서 SHA1 및 패키지 이름 중 하나와 일치하는지 확인합니다. 이전에 사용했던 드라이브 API에는 매니페스트 파일에 앱 ID를 삽입해야한다는 요구 사항이있었습니다. –

+0

지금까지 도와 주셔서 감사합니다. 나는 현재 상태가 – ufk