首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Android 整合新浪微博 SDK 分享功能完整實作指南

     編輯:Java 相關知識

前言

新浪微博開放平台提供 Android SDK 支援 App 唤起微博客戶端進行授權與分享。本文整合官方最新流程,涵蓋 SSO 授權、Token 持久化、多媒體分享 (文字/圖片/網頁)、回調處理 等完整實作,並針對常見坑點給出解法。

一、前置準備

  1. 註冊應用:微博開放平台建立應用,獲取 App Key、App Secret、設定 Redirect URL (如 https://api.weibo.com/oauth2/default.html)。
  2. 配置簽名:在開放平台填入 App 簽名雜湊值 (SHA1),否則 SSO 會失敗導向網頁授權。
  3. 依賴導入 (Maven/Gradle):
    // build.gradle
    implementation 'com.sina.weibo.sdk:core:4.4.0' // 請用最新版
    implementation 'com.sina.weibo.sdk:share:4.4.0'
    
  4. AndroidManifest 權限與組件:
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    <activity
        android:name="com.sina.weibo.sdk.web.WeiboSdkWebActivity"
        android:configChanges="keyboardHidden|orientation"
        android:exported="false"
        android:windowSoftInputMode="adjustResize" />
    <!-- 回調 Activity,需在包名下建立 wb_sdk_Activity -->
    <activity
        android:name=".wb_sdk_Activity"
        android:exported="true"
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="wb{AppKey}" /> <!-- 如 wb123456789 -->
        </intent-filter>
    </activity>
    

二、核心實作類別

1. 常數與 Token 持久化

public class WeiboConstants {
    public static final String APP_KEY = "YOUR_APP_KEY";
    public static final String REDIRECT_URL = "https://api.weibo.com/oauth2/default.html";
    public static final String SCOPE = "email,direct_messages_read,direct_messages_write,"
            + "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
            + "follow_app_official_microblog,invitation_write";
}

public class AccessTokenKeeper {
    private static final String PREF = "weibo_token_pref";
    private static final String KEY_TOKEN = "access_token";
    private static final String KEY_EXPIRES = "expires_in";
    private static final String KEY_UID = "uid";

    public static void write(Context ctx, Oauth2AccessToken token) {
        if (token == null) return;
        ctx.getSharedPreferences(PREF, Context.MODE_PRIVATE).edit()
                .putString(KEY_TOKEN, token.getToken())
                .putLong(KEY_EXPIRES, token.getExpiresTime())
                .putString(KEY_UID, token.getUid())
                .apply();
    }

    public static Oauth2AccessToken read(Context ctx) {
        SharedPreferences sp = ctx.getSharedPreferences(PREF, Context.MODE_PRIVATE);
        String token = sp.getString(KEY_TOKEN, "");
        long expires = sp.getLong(KEY_EXPIRES, 0);
        String uid = sp.getString(KEY_UID, "");
        if (token.isEmpty() || expires == 0) return null;
        Oauth2AccessToken t = new Oauth2AccessToken(token, expires);
        t.setUid(uid);
        return t;
    }

    public static void clear(Context ctx) {
        ctx.getSharedPreferences(PREF, Context.MODE_PRIVATE).edit().clear().apply();
    }
}

2. 主 Activity 整合授權與分享

public class ShareActivity extends AppCompatActivity 
        implements IWeiboHandler.Response {

    private IWeiboShareAPI shareAPI;
    private SsoHandler ssoHandler;
    private Oauth2AccessToken accessToken;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_share);

        // 1. 初始化 SDK
        shareAPI = WeiboShareSDK.createWeiboAPI(this, WeiboConstants.APP_KEY);
        shareAPI.registerApp(); // 註冊到微博客戶端

        // 2. 恢復 Token
        accessToken = AccessTokenKeeper.read(this);

        // 3. 處理從微博客戶端回傳的響應 (onNewIntent)
        if (savedInstanceState != null) {
            shareAPI.handleWeiboResponse(getIntent(), this);
        }

        findViewById(R.id.btn_share).setOnClickListener(v -> checkEnvAndShare());
    }

    /** 檢查環境並啟動分享流程 */
    private void checkEnvAndShare() {
        // 檢查微博客戶端是否安裝且支援 API
        if (!shareAPI.isWeiboAppSupportAPI()) {
            Toast.makeText(this, "請安裝微博客戶端", Toast.LENGTH_SHORT).show();
            // 可引導至應用市場
            return;
        }

        // Token 有效直接分享,否則先授權
        if (accessToken != null && accessToken.isSessionValid()) {
            sendMultiMessage();
        } else {
            ssoHandler = new SsoHandler(this, new AuthInfo(this, WeiboConstants.APP_KEY, WeiboConstants.REDIRECT_URL, WeiboConstants.SCOPE));
            ssoHandler.authorize(new AuthListener());
        }
    }

    /** SSO 授權回調 */
    private class AuthListener implements WeiboAuthListener {
        @Override public void onComplete(Bundle values) {
            accessToken = Oauth2AccessToken.parseAccessToken(values);
            if (accessToken.isSessionValid()) {
                AccessTokenKeeper.write(ShareActivity.this, accessToken);
                sendMultiMessage(); // 授權成功後直接分享
            } else {
                Toast.makeText(ShareActivity.this, "授權失敗", Toast.LENGTH_SHORT).show();
            }
        }
        @Override public void onCancel() { Toast.makeText(ShareActivity.this, "取消授權", Toast.LENGTH_SHORT).show(); }
        @Override public void onWeiboException(WeiboException e) { Toast.makeText(ShareActivity.this, "錯誤: " + e.getMessage(), Toast.LENGTH_SHORT).show(); }
    }

    /** 發送多媒體分享 (文字 + 網頁卡片 + 縮圖) */
    private void sendMultiMessage() {
        WeiboMultiMessage msg = new WeiboMultiMessage();
        msg.textObject = getTextObj();
        msg.mediaObject = getWebpageObj();

        SendMultiMessageToWeiboRequest req = new SendMultiMessageToWeiboRequest();
        req.transaction = String.valueOf(System.currentTimeMillis());
        req.multiMessage = msg;

        shareAPI.sendRequest(req); // 唤起微博分享介面
    }

    private TextObject getTextObj() {
        TextObject obj = new TextObject();
        obj.text = getString(R.string.share_content) + " #我的App#";
        return obj;
    }

    private WebpageObject getWebpageObj() {
        WebpageObject obj = new WebpageObject();
        obj.actionUrl = getString(R.string.share_url); // 落地頁
        obj.identify = Utility.generateGUID();
        obj.title = getString(R.string.share_title);
        obj.description = getString(R.string.share_content);
        // 縮圖:建議 < 32KB,尺寸 120x120 以上
        Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground);
        obj.setThumbImage(bmp);
        return obj;
    }

    /** === 必須重寫的生命週期回調 === */
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        shareAPI.handleWeiboResponse(intent, this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (ssoHandler != null) ssoHandler.authorizeCallBack(requestCode, resultCode, data);
    }

    /** === 分享結果回調 === */
    @Override
    public void onResponse(BaseResponse baseResp) {
        String tip;
        switch (baseResp.errCode) {
            case WBConstants.ErrorCode.ERR_OK: tip = "分享成功"; break;
            case WBConstants.ErrorCode.ERR_CANCEL: tip = "取消分享"; break;
            default: tip = "分享失敗: " + baseResp.errMsg; break;
        }
        Toast.makeText(this, tip, Toast.LENGTH_LONG).show();
    }
}

三、關鍵坑點與解法

問題原因解法
SSO 授權跳轉網頁而非客戶端簽名雜湊未在開放平台配置、或包名不符用 PackageManager.getPackageInfo(..., GET_SIGNATURES) 列印 SHA1 填入後台
分享後回調不觸發 onResponse缺少 wb_sdk_Activity 或 onNewIntent 未轉交嚴格依照 Manifest 範本建立回調 Activity,並在主 Activity 重寫 onNewIntent
縮圖不顯示/壓扁圖片過大、格式不支援、未壓縮壓縮至 32KB 以下、正方形、使用 Bitmap.compress()
Token 過期未自動刷新SDK 無自動刷新機制檢測 isSessionValid() 失敗時重新 ssoHandler.authorize()
Android 11+ 封裝可見性需在 Manifest <queries> 聲明微博包名<queries><package android:name="com.sina.weibo" /></queries>

四、總結

微博分享核心流程:初始化 SDK → 環境檢查 → Token 有效性判斷 → SSO 授權 (含回調處理) → 構建 MultiMessage → sendRequest → 處理 onResponse。做好 簽名配置、回調 Activity、Token 持久化、錯誤碼對應 四大基石,即可穩定上線。建議封裝為 WeiboShareManager 單例,供全專案複用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved