在Android开发中实现GoogleApiClient Builder时出现错误

34

我正在按照Google的文档将Google+登录功能集成到应用程序中。

https://developers.google.com/+/mobile/android/getting-started

我按照指南的每个步骤进行了操作,但在GoogleApiClient.Builder生成的错误中卡住了,在彻底搜索后仍然没有结果。请帮我解决这个问题。谢谢。

错误代码:

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).addApi(Plus.API, null)
            .addScope(Plus.SCOPE_PLUS_LOGIN).build();

错误信息:

   The method addConnectionCallbacks(GoogleApiClient.ConnectionCallbacks) in the type 
   GoogleApiClient.Builder is not applicable for the arguments (MainActivity)

完整的 MainActivity.java 代码如下:

    package mad.project.mightysatta;

    import android.content.Intent;
    import android.content.IntentSender.SendIntentException;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v7.app.ActionBarActivity;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;

    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
    import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.plus.Plus;

    public class MainActivity extends ActionBarActivity implements
    ConnectionCallbacks, OnConnectionFailedListener {

/* 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;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).addApi(Plus.API, null)
            .addScope(Plus.SCOPE_PLUS_LOGIN).build();

    setContentView(R.layout.activity_main);

    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);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_activity_actions, menu);
    return super.onCreateOptionsMenu(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);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container,
                false);
        return rootView;
    }
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    // TODO Auto-generated method stub

    if (!mIntentInProgress && result.hasResolution()) {
        try {
            mIntentInProgress = true;
            result.startResolutionForResult(this, // your activity
                    RC_SIGN_IN);
        } catch (SendIntentException e) {
            // The intent was canceled before it was sent. Return to the
            // default
            // state and attempt to connect to get an updated
            // ConnectionResult.
            mIntentInProgress = false;
            mGoogleApiClient.connect();
        }
    }

}

@Override
public void onConnected(Bundle connectionHint) {
    // TODO Auto-generated method stub

}

@Override
public void onDisconnected() {
    // TODO Auto-generated method stub

}

protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

protected void onStop() {
    super.onStop();

    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }
}

protected void onActivityResult(int requestCode, int responseCode,
        Intent intent) {
    if (requestCode == RC_SIGN_IN) {
        mIntentInProgress = false;

        if (!mGoogleApiClient.isConnecting()) {
            mGoogleApiClient.connect();
        }
    }
}

public void onConnectionSuspended(int cause) {
    mGoogleApiClient.connect();
}

    }

如果我在这段代码中注释掉 .addConnectionCallbacks 和 .addOnConnectionFailedListener ,那么错误就消失了。这个错误似乎与它们的参数有关。

    mGoogleApiClient = new GoogleApiClient.Builder(this)
        //  .addConnectionCallbacks(this)
        //  .addOnConnectionFailedListener(this)
            .addApi(Plus.API, null)
            .addScope(Plus.SCOPE_PLUS_LOGIN).build();

替换实现后更新了主活动

    GooglePlayServicesClient.ConnectionCallbacks,
    GooglePlayServicesClient.OnConnectionFailedListener

MainActivity.java(已更新)

    package mad.project.mightysatta;

    import android.content.Intent;
    import android.content.IntentSender.SendIntentException;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v7.app.ActionBarActivity;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;

    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GooglePlayServicesClient;
    import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
    import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.plus.Plus;

    public class MainActivity extends ActionBarActivity implements
    GooglePlayServicesClient.ConnectionCallbacks,
    GooglePlayServicesClient.OnConnectionFailedListener {

/* 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;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API, null)
            .addScope(Plus.SCOPE_PLUS_LOGIN).build();

    setContentView(R.layout.activity_main);

    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);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_activity_actions, menu);
    return super.onCreateOptionsMenu(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);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container,
                false);
        return rootView;
    }
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    // TODO Auto-generated method stub

    if (!mIntentInProgress && result.hasResolution()) {
        try {
            mIntentInProgress = true;
            result.startResolutionForResult(this, // your activity
                    RC_SIGN_IN);
        } catch (SendIntentException e) {
            // The intent was canceled before it was sent. Return to
            // default
            // state and attempt to connect to get an updated
            // ConnectionResult.
            mIntentInProgress = false;
            mGoogleApiClient.connect();
        }
    }

}

@Override
public void onConnected(Bundle connectionHint) {
    // TODO Auto-generated method stub

}

@Override
public void onDisconnected() {
    // TODO Auto-generated method stub

}

protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

protected void onStop() {
    super.onStop();

    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }
}

protected void onActivityResult(int requestCode, int responseCode,
        Intent intent) {
    if (requestCode == RC_SIGN_IN) {
        mIntentInProgress = false;

        if (!mGoogleApiClient.isConnecting()) {
            mGoogleApiClient.connect();
        }
    }
}

public void onConnectionSuspended(int cause) {
    mGoogleApiClient.connect();
}

    }

Taha,我遇到了同样的问题,并想出了你上面提到的解决方案。你在使用Android Studio吗?如果是的话,你能成功进行G+登录吗? - Gerard
我曾经使用ADT-Bundle,它确实可以登录。我认为需要在应用程序的设备上安装并登录G+应用程序。 - Taha Rushain
5个回答

72

我在他们的文档中看到了明确指示您包含此导入:

import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;

然而,抛出的错误期望的类与GooglePlayServicesClient.ConnectionCallbacks不同,它要求使用GoogleApiClient.ConnectionCallbacks。尝试更改您的实现以使用更合格的类名。这似乎是唯一可能使代码出错的事情,如果没有显式的限定类名,它将默认为直接导入的类名。

当你不得不质疑手册时,总是更加困难。

编辑:我的意思是像这样进行更改:

public class MainActivity 
    extends ActionBarActivity 
    implements GoogleApiClient.ConnectionCallbacks,
               GoogleApiClient.OnConnectionFailedListener {

6
这是正确的。已提交文档错误报告。谢谢。 - Hounshell
16
谢谢这个修复。你会认为谷歌会测试他们自己的代码。每一步实现谷歌播放服务都需要进行堆栈溢出研究以修复奇怪的错误。我希望有一天能够完全实现它。 - Androidcoder
1
迈克尔,我很高兴不是只有我被文档绊倒了。他们的样例几乎都需要大量修改才能运行。 - Gerard
1
@ Gerard 很高兴能帮忙。这绝对是一项具有挑战性的任务。 - user1932079
3
最新情况是,我也遇到了这个问题。仍未修复-已提交另一个文档错误。 - JasCav
显示剩余7条评论

16

我也遇到了同样的问题,我通过以下方法解决了它。

导入正确的ConnectionCallbacks。

这是我的代码:

import android.content.Context;
import android.os.Bundle;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.drive.Drive;

public class GplusLogin implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {
GoogleApiClient mGoogleApiClient;
GplusLogin(Context context){

    mGoogleApiClient = new GoogleApiClient.Builder(context)
            .addApi(Drive.API)
            .addScope(Drive.SCOPE_FILE)
            .addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) context)
            .addOnConnectionFailedListener(this)
            .build();
}

@Override
public void onConnected(Bundle bundle) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

@Override
public void onConnectionSuspended(int i) {

}
}

1
谢谢,我有同样的问题。我只导入了一个(正确的)ConnectionCallbacks,但它在 .addConnectionCallbacks 处崩溃,直到我将上下文显式转换为 (GoogleApiClient.ConnectionCallbacks)。我是在 Service 中使用它而不是 ACtivity,但它们都扩展了 Context,所以不确定为什么会有影响。 - Mick O'Hea

2

点击Alt+Enter,强制Android Studio实现:

GoogleApiClient.ConnectionCallbacks,

GoogleApiClient.OnConnectionFailedListener


2
原文大意:结果发现他们(谷歌)自己并没有遵循指南。使用他们实际在教程顶部提到的Google Drive Android Quickstart作为参考,但他们将其误导性地命名为“Android Quickstart”,尽管它是针对Google Drive特定的。 指南顶部的注释: The note at the top of the guide

0
   implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,OnMapReadyCallback

返回Activity


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接