Android twitter登录集成

集成的方式有两种,主要在于获取用户信息的方式不同。

一、准备工作

1.在项目级build.gradle文件中配置fabric

buildscript {

    repositories {
        google()
        jcenter()
        mavenCentral()
        maven {
            url 'https://maven.fabric.io/public'
        }
    }

    dependencies {
     ...
        classpath 'io.fabric.tools:gradle:1.+'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven {
            url 'https://jitpack.io'
        }
       ...
    }
}
  1. 在app级build.gradle文件中配置
apply plugin: 'io.fabric'
...
repositories {
    mavenCentral()
    maven {
        url 'https://maven.fabric.io/public'
    }
}
...
    implementation('com.twitter.sdk.android:twitter-core:3.1.1@aar') {
        transitive = true
    }
    implementation('com.twitter.sdk.android:tweet-composer:3.1.1@aar') {
        transitive = true
    }
    implementation('com.twitter.sdk.android:tweet-ui:3.1.1@aar') {
        transitive = true
    }
   implementation('com.crashlytics.sdk.android:crashlytics:2.9.4@aar') {
        transitive = true
    }
...
apply plugin: 'com.google.gms.google-services'
  1. 在清单文件中配置fabric key,
  
  1. 在twitter平台注册自己的app,获取twitter 的key和secret


    Android twitter登录集成_第1张图片

二、授权访问用户信息

在我们要调用的位置,初始化twitter配置信息

TwitterConfig config = new TwitterConfig.Builder(this)                         
        .logger(new DefaultLogger(Log.DEBUG))                                  
        .twitterAuthConfig(new TwitterAuthConfig(TWITTER_KEY, TWITTER_SECRET)) 
        .debug(BuildConfig.DEBUG)                                              
        .build();                                                              
Twitter.initialize(config);                                                    

一种是不用twitter的btn控件按钮,访问用户信息用url

 private void twitterLogin() {
        loginTwitter(LoginActivity.this, new LoginCallback() {
            @Override
            public void onSuccess(User user, String email, String twitterSecret, String twitterToken) {
                String imageProfileUrl = user.profileImageUrl;
                String userName = user.name;

                String profileUrl = imageProfileUrl.replace("_normal", "");
            
                LogTracer.INSTANCE.print(TAG, "loginTwitter onSuccess");
            }

            @Override
            public void onFailure(Exception e) {
                LogTracer.INSTANCE.print(TAG, "twitter login failed:" + e.getMessage());
                ToastUtils.INSTANCE.showLongToast(LoginActivity.this, R.string.toast_common_failed);
            }
        });
    }

    private TwitterAuthClient mTwitterAuthClient;

    public interface LoginCallback {
        void onSuccess(User user, String email, String twitterSecret, String twitterToken);

        void onFailure(Exception e);
    }

    public void loginTwitter(Activity activity, final LoginCallback callback) {
        if (mTwitterAuthClient == null) {
            mTwitterAuthClient = new TwitterAuthClient();
        }
        mTwitterAuthClient.authorize(activity, new Callback() {
            @Override
            public void success(Result result) {
                String name = result.data.getUserName();
                long userId = result.data.getUserId();
                LogTracer.INSTANCE.print(TAG, "loginTwitter name =" + name + ", userId=" + userId);
                getTwitterUserEmail(userId, callback);
            }

            @Override
            public void failure(TwitterException e) {
                LogTracer.INSTANCE.print(TAG, "loginTwitter failure e=" + e.getMessage());
                callback.onFailure(e);
            }
        });
    }

    private void getTwitterUserEmail(final long userId, final LoginCallback callback) {
        final TwitterSession activeSession = TwitterCore.getInstance().getSessionManager().getActiveSession();
        mTwitterAuthClient.requestEmail(activeSession, new Callback() {

            @Override
            public void success(Result result) {
                String email = result.data;
                LogTracer.INSTANCE.print(TAG, "getTwitterUserEmail email::" + email);
                getTwitterUserInfo(userId, email, callback);
            }

            @Override
            public void failure(TwitterException e) {
                getTwitterUserInfo(userId, "", callback);
                LogTracer.INSTANCE.print(TAG, "getTwitterUserEmail failure::" + e.getMessage());
            }
        });

    }

    private void getTwitterUserInfo(final long userId, final String email, final LoginCallback callback) {
        final TwitterSession activeSession = TwitterCore.getInstance().getSessionManager().getActiveSession();
        final String twitterSecret = activeSession.getAuthToken().secret;
        final String twitterToken = activeSession.getAuthToken().token;
        MyTwitterApiClient client = new MyTwitterApiClient(activeSession);
        client.getCustomService().show(userId).enqueue(new Callback() {
            @Override
            public void success(Result result) {
                User data = result.data;
                callback.onSuccess(data, email, twitterSecret, twitterToken);
            }

            @Override
            public void failure(TwitterException e) {
                e.printStackTrace();
                callback.onFailure(e);
            }
        });
    }

    static class MyTwitterApiClient extends TwitterApiClient {
        public MyTwitterApiClient(TwitterSession session) {
            super(session);
        }

        /**
         * Provide CustomService with defined endpoints
         */
        public CustomService getCustomService() {
            return getService(CustomService.class);
        }

        // example users/show service endpoint
        interface CustomService {
            @GET("/1.1/users/show.json")
            Call show(@Query("user_id") long id);
        }
    }

另一种是用twitter loginBtn控件
xml中添加下面代码:


            

在页面使用下面的方式:
初始化控件

 mTwitterLoginButton = findViewById(R.id.twitter_button);
        twitterLogin();

回调监听

    
    private void twitterLogin() {
        mTwitterLoginButton.setCallback(new Callback() {

            @Override
            public void success(Result result) {
                LogTracer.INSTANCE.print(TAG, "twitter login success");
                TwitterSession session = result.data;
                final String twitterID = session.getAuthToken().secret;
                final String twitterToken = session.getAuthToken().token;
                getTwitterUserPhoto(twitterID, twitterToken);
            }

            @Override
            public void failure(TwitterException e) {
                LogTracer.INSTANCE.print(TAG, "twitter login failed:" + e.getMessage());
                ToastUtils.INSTANCE.showLongToast(LoginActivity.this, R.string.toast_common_failed);
            }
        });

    }

    private void getTwitterUserPhoto(final String twitterID,final String twitterToken) {
        final TwitterApiClient twitterApiClient = TwitterCore.getInstance().getApiClient();
        Call call = twitterApiClient.getAccountService().verifyCredentials(true, false, true);
        call.enqueue(new Callback() {
            @Override
            public void success(Result result) {
                User user = result.data;
                String imageProfileUrl = user.profileImageUrl;
                String email = user.email;
                String userName = user.name;

                String profileUrl = imageProfileUrl.replace("_normal", "");
                
            }

            @Override
            public void failure(TwitterException e) {
                LogTracer.INSTANCE.print(TAG, "twitter getTwitterUserPhoto failed:" + e.getMessage());
                ToastUtils.INSTANCE.showLongToast(LoginActivity.this, R.string.toast_common_failed);
            }
        });
    }

在onActivityResult方法中添加此代码

 mTwitterLoginButton.onActivityResult(requestCode, resultCode, data);

三、twitter挖坑填坑系列

  1. 当登录按钮成功回调,但是下一步请求用户头像出问题401时,参考这位博主的帖子https://blog.csdn.net/xu20082100226/article/details/79315830,救命了。
  2. 当手机端没有安装twitter客户端时,
    预期:显示Twitter登录网页以输入用户名和密码,然后继续。
    实际:未显示任何页面。
    在Android app中点击twitter登录按钮,返回错误信息为
08-06 13:56:09.317 6499-6499/? E/Twitter: Invalid json: Callback URL not approved for this client application. Approved callback URLs can be adjusted in your application settings
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
        at com.twitter.sdk.android.core.models.SafeListAdapter$1.read(SafeListAdapter.java:45)
        at com.twitter.sdk.android.core.models.SafeMapAdapter$1.read(SafeMapAdapter.java:45)
        at com.google.gson.Gson.fromJson(Gson.java:888)
        at com.google.gson.Gson.fromJson(Gson.java:853)
        at com.google.gson.Gson.fromJson(Gson.java:802)
        at com.google.gson.Gson.fromJson(Gson.java:774)
        at com.twitter.sdk.android.core.TwitterApiException.parseApiError(TwitterApiException.java:110)
        at com.twitter.sdk.android.core.TwitterApiException.readApiError(TwitterApiException.java:95)
        at com.twitter.sdk.android.core.TwitterApiException.(TwitterApiException.java:43)
        at com.twitter.sdk.android.core.Callback.onResponse(Callback.java:42)
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
        at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213)
        at com.twitter.sdk.android.core.models.SafeListAdapter$1.read(SafeListAdapter.java:45) 
        at com.twitter.sdk.android.core.models.SafeMapAdapter$1.read(SafeMapAdapter.java:45) 
        at com.google.gson.Gson.fromJson(Gson.java:888) 
        at com.google.gson.Gson.fromJson(Gson.java:853) 
        at com.google.gson.Gson.fromJson(Gson.java:802) 
        at com.google.gson.Gson.fromJson(Gson.java:774) 
        at com.twitter.sdk.android.core.TwitterApiException.parseApiError(TwitterApiException.java:110) 
        at com.twitter.sdk.android.core.TwitterApiException.readApiError(TwitterApiException.java:95) 
        at com.twitter.sdk.android.core.TwitterApiException.(TwitterApiException.java:43) 
        at com.twitter.sdk.android.core.Callback.onResponse(Callback.java:42) 
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68) 
        at android.os.Handler.handleCallback(Handler.java:739) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
    Failed to get request token
    com.twitter.sdk.android.core.TwitterApiException: HTTP request failed, Status: 403
        at com.twitter.sdk.android.core.Callback.onResponse(Callback.java:42)
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
08-06 13:56:09.347 6499-6499/? D/Twitter: onActivityResult called with 140 1
08-06 13:56:09.348 6499-6499/? E/Twitter: Authorization completed with an error
    com.twitter.sdk.android.core.TwitterAuthException: Failed to get request token
        at com.twitter.sdk.android.core.identity.OAuthController$1.failure(OAuthController.java:94)
        at com.twitter.sdk.android.core.internal.oauth.OAuth1aService$1.failure(OAuth1aService.java:191)
        at com.twitter.sdk.android.core.Callback.onResponse(Callback.java:42)
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

在Android设备上,我们收到此错误“无法获取请求令牌”。我们发现请求https://api.twitter.com/oauth/request_token收到403错误。
我们的iOS应用程序也是如此,错误日志“未批准此客户端应用程序的回调URL。可以在您的应用程序设置中调整已批准的回调URL”。
这是因为twitter api 的这种变化。

要解决此问题,您可以在https://apps.twitter.com上的应用控制台中指定以下回调网址
网址方案
适用于Android的TwitterKit twittersdk:// OAuth1aService.java#L59
适用于iOS的TwitterKit twitterkit-YOUR_CONSUMER_KEY:// TWTRLoginURLParser.m#L39
Android twitter登录集成_第2张图片
000000000.png

你可能感兴趣的:(Android twitter登录集成)