Android 用官方SDK實現第三方(qq、微信、微博等)分享和登入
上一篇講了android第三方登入,這一篇大概說一下分享。需要注意幾點:
1.登入和分享功能都必須是簽名之後的apk,才能用
2.再吐槽一下,微信SDK做的真他媽的變態,和登入一樣,必須是例如我的apk,包名(也就是AndroidManifest.xml中的包名)是com.kingdowin.gosu,你專案中必須有一個包名是com.kingdowin.gosu.wxapi,下面有一個類是WXEntryActivity.java,裡面寫登入或分享以及獲得返回響應結果(public void onResp(BaseResp resp) {})微信程式碼,我不得不把自己的MainActivity改為WXEntryActivity。
3.微信分享如果文字能分享而圖片不能,那是可能是因為你分享的圖片太大了,SDK協議中對縮圖的大小作了限制,大小不能超過32K(最好不要超過20k,因為在測試中有時27k就不能分享)。另外限制的還有title、description等引數的長度。另外Bitmap的compress方法不支援PNG,只支援JPG。
4.qq分享如果包含圖片似乎只支援手機裡的本地圖片而不支援二進位制
5、如果我們把WXEntryActivity設為
android:theme="@android:style/Theme.Translucent
作為透明的分享選單,那麼我們在Manifest中設定singleInstance,這樣從微信分享返回時才不會重複建立WXEntryActivity,並且呼叫onNewIntent()。
網上有許多說設為singleTop,這樣不對,因為微信肯定是在一個新的Task,我們可以getTaskId()來測試是不是taskId一樣。重新啟動
WXEntryActivity時,它也被放在那個新的Task,而singleTop只針對同一個task中,所以還會重新建立WXEntryActivity,這樣一來介面上就會產生許多個
WXEntryActivity,而這並不是我們想要的
<activity android:name="com.yongche.wxapi.WXEntryActivity" android:exported="true" android:launchMode="singleInstance" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar" >
6、問題:AndroidStudio做分享會報錯:
Error:Execution failed for task ':app:transformClassesWithMultidexlistForYongcheDebug'.
> java.io.IOException: Can't read [/Users/gaolei/Work/CompanyProject/android-weidao-driver/DriverZhuanche/app/build/intermediates/transforms/jarMerging/yongche/debug/jars/1/1f/combined.jar] (Can't process class [com/tencent/wxop/stat/al.class] (Unknown verification type [95] in stack map frame))
解決辦法:去微信開放平臺,下載最新的libammsdk.jar,就OK ^~^
效果圖:
WXEntryActivity.java主要程式碼
public class WXEntryActivity extends Activity implements OnClickListener,
IWXAPIEventHandler {
private Button share, qq_login, qq_logout, weibo_login, weixin_login;
private IWXAPI api;
private QQLogin qqLogin;
private WeiBoLogin weiboLogin;
private TextView share_cancel;
private RelativeLayout share_full_layout, share_item_layout;
private GridView share_gridview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
share = (Button) findViewById(R.id.share);
qq_login = (Button) findViewById(R.id.qq_login);
qq_logout = (Button) findViewById(R.id.qq_logout);
weibo_login = (Button) findViewById(R.id.weibo_login);
weixin_login = (Button) findViewById(R.id.weixin_login);
share.setOnClickListener(this);
qq_login.setOnClickListener(this);
qq_logout.setOnClickListener(this);
weibo_login.setOnClickListener(this);
weixin_login.setOnClickListener(this);
share_cancel = (TextView) findViewById(R.id.share_cancel);
share_full_layout = (RelativeLayout) findViewById(R.id.share_full_layout);
share_full_layout.setOnClickListener(this);
share_cancel.setOnClickListener(this);
share_item_layout = (RelativeLayout) findViewById(R.id.share_item_layout);
share_gridview = (GridView) findViewById(R.id.share_gridview);
qqLogin = new QQLogin(this);
weiboLogin = new WeiBoLogin(this);
api = WXAPIFactory.createWXAPI(this, Constant.WEIXIN_APP_ID, false);
api.handleIntent(getIntent(), this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.share:
showShareLayout();
break;
case R.id.qq_login:
if (!QQLogin.mTencent.isSessionValid()) {
QQLogin.mTencent.login(this, "all", qqLogin);
}
break;
case R.id.qq_logout:
if (QQLogin.mTencent.isSessionValid()) {
QQLogin.mTencent.logout(this);
}
break;
case R.id.weixin_login:
api.registerApp(Constant.WEIXIN_APP_ID);
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wechat_sdk_demo";
api.sendReq(req);
break;
case R.id.weibo_login:
WeiBoLogin.mSsoHandler.authorizeWeb(weiboLogin);
break;
case R.id.share_cancel:
hideShareLayout();
break;
case R.id.share_full_layout:
hideShareLayout();
break;
}
}
private void showShareLayout() {
new ThirdUtil(this, share_full_layout, share_item_layout,
"MineFragment", getString(R.string.app_share_content),
getString(R.string.company_website))
.showShareLayout(share_gridview);
}
private void hideShareLayout() {
new ThirdUtil(this, share_full_layout, share_item_layout,
"", "", "").hideShareLayout();
}
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
switch (req.getType()) {
case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
break;
case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
break;
default:
break;
}
}
@Override
public void onResp(BaseResp resp) {
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
if (MyApplication.loginShare.equals("login")) {
CommonUtils.getUtilInstance().showToast(this, getString(R.string.auth_success));
String code = ((SendAuth.Resp) resp).code;
new WeiXinLogin(WXEntryActivity.this).getWeiXinInfo(code);
Log.d("gaolei", "onResp----------login-----------");
} else {
CommonUtils.getUtilInstance().showToast(this,
getString(R.string.share_success));
Log.d("gaolei", "onResp----------share-----------");
}
break;
case BaseResp.ErrCode.ERR_SENT_FAILED:
if (MyApplication.loginShare.equals("login")) {
CommonUtils.getUtilInstance().showToast(this,
getString(R.string.auth_failure));
} else {
CommonUtils.getUtilInstance().showToast(this,
getString(R.string.share_failure));
}
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
if (MyApplication.loginShare.equals("login")) {
CommonUtils.getUtilInstance().showToast(this,
getString(R.string.auth_failure));
} else {
CommonUtils.getUtilInstance().showToast(this,
getString(R.string.share_failure));
}
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
if (MyApplication.loginShare.equals("login")) {
CommonUtils.getUtilInstance().showToast(this,
getString(R.string.auth_cancel));
} else {
CommonUtils.getUtilInstance().showToast(this,
getString(R.string.share_cancel));
}
break;
default:
break;
}
}
}
微信分享程式碼:
public class WeiXinShare{
private Context context;
private IWXAPI api;
private static final int THUMB_SIZE = 150;
public WeiXinShare(Context context){
this.context=context;
api = WXAPIFactory.createWXAPI(context, Constant.WEIXIN_APP_ID);
api.registerApp(Constant.WEIXIN_APP_ID);
}
//只分享文字,flag(0:分享到微信好友,1:分享到微信朋友圈)
public void shareText(int flag){
WXTextObject textObj = new WXTextObject();
textObj.text = context.getString(R.string.app_share_content);
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = textObj;
msg.description =context.getString(R.string.app_share_content);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("text");
req.message = msg;
req.scene =flag;
api.sendReq(req);
boolean bool=api.sendReq(req);
Log.d("gaolei","weixin------"+bool);
}
//只分享圖片,flag(0:分享到微信好友,1:分享到微信朋友圈)
public void shareImg(int flag){
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.app_icon);
WXImageObject imgObj = new WXImageObject(bmp);
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = imgObj;
Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true);
bmp.recycle();
msg.thumbData = ThirdUtil.bmpToByteArray(thumbBmp, true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction =buildTransaction("img");
req.message = msg;
req.scene =flag;
api.sendReq(req);
boolean bool=api.sendReq(req);
Log.d("gaolei","weixin------"+bool);
}
private String buildTransaction(final String type) {
return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}
//分享圖片給好友
public void shareWebToFriend(String shareContext,String url){
WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl = url;
WXMediaMessage msg = new WXMediaMessage(webpage);
msg.title =context.getString(R.string.app_gosu);
msg.description =shareContext;
Bitmap thumb = BitmapFactory.decodeResource(context.getResources(), R.drawable.app_icon);
msg.thumbData = ThirdUtil.bmpToByteArray(thumb, true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("webpage");
req.message = msg;
req.scene = 0;
api.sendReq(req);
boolean bool=api.sendReq(req);
Log.d("gaolei","weixin------"+bool);
}
//分享圖文到朋友圈
public void shareWebToZone(String shareContext,String url){
WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl =url ;
WXMediaMessage msg = new WXMediaMessage(webpage);
msg.title =shareContext;
Bitmap thumb = BitmapFactory.decodeResource(context.getResources(), R.drawable.app_icon);
msg.thumbData = ThirdUtil.bmpToByteArray(thumb, true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("webpage");
req.message = msg;
req.scene = 1;
api.sendReq(req);
}
}
qq分享程式碼:
<span style="font-size:14px;"><span style="font-size:14px;">public class QShare {
private Context context;
public static Tencent mTencent;
private String fileUrl;
private int mExtarFlag = 0x00;
public QShare(Context context) {
this.context = context;
if (mTencent == null) {
mTencent = Tencent.createInstance(Constant.QQ_APP_ID, context);
}
fileUrl=MyApplication.photo_path+"app_icon.png";
}
public void shareToQ(String shareContent,String url) {
final Bundle params = new Bundle();
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE,QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
params.putString(QQShare.SHARE_TO_QQ_TITLE, context.getString(R.string.app_gosu));
params.putString(QQShare.SHARE_TO_QQ_SUMMARY,shareContent);
params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, fileUrl);
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL,url);
mTencent.shareToQQ((Activity) context, params, qqShareListener);
}
public void shareToQZone(String shareContent,String url) {
final Bundle params = new Bundle();
params.putString(QQShare.SHARE_TO_QQ_TITLE, context.getString(R.string.app_gosu));
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, shareContent);
params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, fileUrl);
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL,url);
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, mExtarFlag|= QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
mTencent.shareToQQ((Activity) context, params, qqShareListener);
}
IUiListener qqShareListener = new IUiListener() {
@Override
public void onCancel() {
Toast.makeText(context,
context.getString(R.string.share_cancel),Toast.LENGTH_LONG);
}
@Override
public void onComplete(Object response) {
// TODO Auto-generated method stub
Toast.makeText(context,
context.getString(R.string.share_success),Toast.LENGTH_LONG);
}
@Override
public void onError(UiError e) {
// TODO Auto-generated method stub
Toast.makeText(context,
context.getString(R.string.share_failure),Toast.LENGTH_LONG);
}
};
}</span></span>
微博分享程式碼:
<span style="font-size:14px;"><span style="font-size:14px;">public class WeiBoShare implements IWeiboHandler.Response {
private IWeiboShareAPI mWeiboShareAPI;
private Context context;
public WeiBoShare(Context context) {
this.context = context;
mWeiboShareAPI = WeiboShareSDK.createWeiboAPI(context,
Constant.WEIBO_APP_KEY);
mWeiboShareAPI.registerApp();
}
public void share(String shareContent) {
WeiboMultiMessage weiboMessage = new WeiboMultiMessage();
TextObject textObject = new TextObject();
textObject.text = shareContent;
weiboMessage.textObject = textObject;
weiboMessage.imageObject = getImageObj();
// weiboMessage.mediaObject = getWebpageObj();
SendMultiMessageToWeiboRequest request = new SendMultiMessageToWeiboRequest();
request.transaction = String.valueOf(System.currentTimeMillis());
request.multiMessage = weiboMessage;
AuthInfo authInfo = new AuthInfo(context, Constant.WEIBO_APP_KEY,
Constant.REDIRECT_URL, Constant.SCOPE);
Oauth2AccessToken accessToken = AccessTokenKeeper
.readAccessToken(context);
Log.d("gaolei", "authInfo--------------" + authInfo);
Log.d("gaolei", "accessToken--------------" + accessToken);
String token = "";
if (accessToken != null) {
token = accessToken.getToken();
}
mWeiboShareAPI.sendRequest((Activity) context, request, authInfo,
token, new WeiboAuthListener() {
@Override
public void onWeiboException(WeiboException e) {
Log.d("gaolei",
"onWeiboException--------------"
+ e.getMessage());
}
@Override
public void onComplete(Bundle bundle) {
// TODO Auto-generated method stub
Oauth2AccessToken newToken = Oauth2AccessToken
.parseAccessToken(bundle);
AccessTokenKeeper.writeAccessToken(context, newToken);
Toast.makeText(
context,
"onAuthorizeComplete token = "
+ newToken.getToken(), 0).show();
}
@Override
public void onCancel() {
}
});
}
// private TextObject getTextObj() {
// TextObject textObject = new TextObject();
// textObject.text = context.getString(R.string.app_share_content);
// return textObject;
// }
private ImageObject getImageObj() {
ImageObject imageObject = new ImageObject();
BitmapDrawable bitmapDrawable = (BitmapDrawable) context.getResources()
.getDrawable(R.drawable.app_icon);
imageObject.setImageObject(bitmapDrawable.getBitmap());
return imageObject;
}
private WebpageObject getWebpageObj() {
WebpageObject mediaObject = new WebpageObject();
mediaObject.identify = Utility.generateGUID();
mediaObject.title = context.getString(R.string.share_gosu);
mediaObject.description = context.getString(R.string.app_share_content);
mediaObject.setThumbImage(BitmapFactory.decodeResource(
context.getResources(), R.drawable.app_icon));
mediaObject.actionUrl = "http://www.kingdowin.com/";
mediaObject.defaultText = context.getString(R.string.share_gosu);
return mediaObject;
}
<a target=_blank href="http://download.csdn.net/detail/gaolei1201/9519509">
@Override</a>
public void onResponse(BaseResponse baseResp) {
// TODO Auto-generated method stub
switch (baseResp.errCode) {
case WBConstants.ErrorCode.ERR_OK:
Toast.makeText(context,
context.getString(R.string.share_success),Toast.LENGTH_LONG);
break;
case WBConstants.ErrorCode.ERR_CANCEL:
Toast.makeText(context,
context.getString(R.string.share_cancel),Toast.LENGTH_LONG);
break;
case WBConstants.ErrorCode.ERR_FAIL:
Toast.makeText(context,
context.getString(R.string.share_failure),Toast.LENGTH_LONG);
break;
}
}
}
</span></span>