前段时间公司需要,逐步了新浪微博、腾讯qq、微信等授权登录验证的问题。如果要一个个申请,看文档写代码也是很多流程的。干脆用友盟社会化Android组件之第三方登录。友盟是集成了这些平台,还有其他主流的平台的。我在这里主要讲一下友盟里面微博登录。先看看友盟是怎么介绍自已的。
一、友盟社会化分享介绍
友盟社会化分享组件,帮助移动应用快速具备微信分享,微博分享、登录、评论、喜欢等社会化组件功能,助力产品推广,并提供实时、全面的社会化数据统计分析服务,是国内最大的社会化分享SDK。
支持各大社交平台
精选国内外23个主流社交平台,支持图片、文字、图文、音乐、视频等多种内容的分享。
国内平台:微信、朋友圈、QQ、Qzone、新浪微博、腾讯微博、人人、豆瓣、有道云笔记、来往、易信、短信、邮件
国外平台:Facebook、Twitter、Instagram、Google+、Line、Whatsapp、Tumblr、Pinterest、Evernote、Pocket、LIinkedIn、Flickr、Kakao Talk。
从这上面可以看出,支持平台太多啦,自已有选择开发就行。搞几个申请、注册、身份认证、应用审核。。。你都会抓狂的。。
二、友盟开发
友盟的注册很简单,有个邮箱就能注册,注册完不用身份认证那么麻烦。不用审核等。
2、友盟官方第三方文档支持:
http://dev.umeng.com/social/android/operation
http://dev.umeng.com/social/android/login-page
三、友盟平台里面新浪微博操作
这个开放平台的注册,一定要有开通微博账号的账户。用个人或者企业级的。
开通之后,先进行邮箱验证:选择个人或者企业。需要一系列的资料。
身份验证:个人和企业认证有区别。也是一系列的资料。
搞定这些了,创建移动应用了。需要的资料很多,我在这里列出几个重点的:
应用的包名:
应用的签名:
android应用的下载地址:(一定是应用商店上线后的地址:例如,百度、91、安卓等,我是有百度开发者平台上线应用的)
应用介绍:
应用图标:三个(分别是16*16、80*80、120*120 单位px)
应用介绍图片:三张以上(300*450 单位px)
ps:有这些资料就差不多了,图片尺寸以及应用下载地址严格按照要求。个人开发一般人还真弄不了那么多。
提交需要审核,最好在应用展示图片中有用到分享到微博的例子,容易通过。审核时间一天以内。
2、App Key以及App Secret配置到友盟平台
这上面搞定了之后,把上面申请到的App Key以及App Secret配置到友盟平台。如下图:
新浪微博的配置不用在代码中配置,只需要在友盟的后台。微信,qq需要在代码中配置。
3、新浪微博第三方登录代码的流程
这个流程在友盟文档中也有很详细,我就不写友盟那里文档的东西了。写了就有重复。就看看我的代码吧。不过我代码中还有qq,微信都在了。将就着看,感觉都还好理解。我只贴授权登录的了,分享、评论那些我删了。
-
<span style="font-size:18px;">package com.southgnss.umeng;
-
-
import java.io.File;
-
import java.util.Date;
-
import java.util.Map;
-
-
import android.app.Activity;
-
import android.content.Intent;
-
import android.graphics.BitmapFactory;
-
import android.os.Bundle;
-
import android.text.TextUtils;
-
import android.view.View;
-
import android.view.View.OnClickListener;
-
import android.widget.Button;
-
import android.widget.Toast;
-
-
import com.southgnss.umeng.commons.Constants;
-
import com.umeng.analytics.MobclickAgent;
-
import com.umeng.socialize.bean.SHARE_MEDIA;
-
import com.umeng.socialize.bean.SocializeEntity;
-
import com.umeng.socialize.bean.StatusCode;
-
import com.umeng.socialize.controller.UMServiceFactory;
-
import com.umeng.socialize.controller.UMSocialService;
-
import com.umeng.socialize.controller.listener.SocializeListeners.SocializeClientListener;
-
import com.umeng.socialize.controller.listener.SocializeListeners.UMAuthListener;
-
import com.umeng.socialize.controller.listener.SocializeListeners.UMDataListener;
-
import com.umeng.socialize.exception.SocializeException;
-
import com.umeng.socialize.sso.QZoneSsoHandler;
-
import com.umeng.socialize.sso.SinaSsoHandler;
-
import com.umeng.socialize.sso.UMQQSsoHandler;
-
import com.umeng.socialize.sso.UMSsoHandler;
-
import com.umeng.socialize.utils.Log;
-
import com.umeng.socialize.weixin.controller.UMWXHandler;
-
-
/**
-
* @description 实现友盟第三方登录注销、获取用户信息
-
*/
-
public class LoginActivity extends Activity implements OnClickListener {
-
// 整个平台的Controller,负责管理整个SDK的配置、操作等处理
-
private UMSocialService mController = UMServiceFactory
-
.getUMSocialService(Constants.DESCRIPTOR);
-
-
private Button sinaLoginButton;
-
private Button sinaLogoutButton;
-
private Button qqLoginButton;
-
private Button qqLogoutButton;
-
private Button wechatLoginButton;
-
private Button wechatLogoutButton;
-
private Button shareButton;
-
-
@SuppressWarnings("deprecation")
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
-
sinaLoginButton = (Button) this.findViewById(R.id.btn_sina_login);
-
sinaLogoutButton = (Button) this.findViewById(R.id.btn_sina_logout);
-
qqLoginButton = (Button) this.findViewById(R.id.btn_qq_login);
-
qqLogoutButton = (Button) this.findViewById(R.id.btn_qq_logout);
-
shareButton = (Button) this.findViewById(R.id.btn_share);
-
wechatLoginButton = (Button) this.findViewById(R.id.btn_wechat_login);
-
wechatLogoutButton = (Button) this.findViewById(R.id.btn_wechat_logout);
-
-
sinaLoginButton.setOnClickListener(this);
-
sinaLogoutButton.setOnClickListener(this);
-
qqLoginButton.setOnClickListener(this);
-
qqLogoutButton.setOnClickListener(this);
-
shareButton.setOnClickListener(this);
-
wechatLoginButton.setOnClickListener(this);
-
wechatLogoutButton.setOnClickListener(this);
-
-
// 配置需要分享的相关平台
-
configPlatforms();
-
-
MobclickAgent.updateOnlineConfig(this);
-
}
-
-
@Override
-
protected void onResume() {
-
super.onResume();
-
MobclickAgent.onResume(this);
-
}
-
-
@Override
-
protected void onPause() {
-
super.onPause();
-
MobclickAgent.onPause(this);
-
}
-
-
/**
-
* 配置分享平台参数
-
*/
-
private void configPlatforms() {
-
// 添加新浪sso授权
-
mController.getConfig().setSsoHandler(new SinaSsoHandler());
-
-
// 添加QQ、QZone平台
-
addQQQZonePlatform();
-
-
// 添加微信、微信朋友圈平台
-
addWXPlatform();
-
-
}
-
-
-
/**
-
* 添加所有的平台</br>
-
*/
-
private void addCustomPlatforms() {
-
// 添加微信平台
-
addWXPlatform();
-
// 添加QQ平台
-
addQQQZonePlatform();
-
-
mController.getConfig().setPlatforms(SHARE_MEDIA.WEIXIN,
-
SHARE_MEDIA.WEIXIN_CIRCLE, SHARE_MEDIA.QQ, SHARE_MEDIA.QZONE,
-
SHARE_MEDIA.SINA, SHARE_MEDIA.TENCENT);
-
mController.openShare(LoginActivity.this, false);
-
}
-
-
/**
-
* @功能描述 : 添加微信平台分享
-
* @return
-
*/
-
private void addWXPlatform() {
-
// 注意:在微信授权的时候,必须传递appSecret
-
// wx967daebe835fbeac是你在微信开发平台注册应用的AppID, 这里需要替换成你注册的AppID
-
String appId = "wxc8f10d692edf9f5f";
-
String appSecret = "d4624c36b6795d1d99dcf0547af5443d";
-
// 添加微信平台
-
UMWXHandler wxHandler = new UMWXHandler(LoginActivity.this, appId,
-
appSecret);
-
wxHandler.addToSocialSDK();
-
-
// 支持微信朋友圈
-
// UMWXHandler wxCircleHandler = new UMWXHandler(LoginActivity.this,
-
// appId, appSecret);
-
// wxCircleHandler.setToCircle(true);
-
// wxCircleHandler.addToSocialSDK();
-
}
-
-
/**
-
* @功能描述 : 添加QQ平台支持 QQ分享的内容, 包含四种类型, 即单纯的文字、图片、音乐、视频. 参数说明 : title, summary,
-
* image url中必须至少设置一个, targetUrl必须设置,网页地址必须以"http://"开头 . title :
-
* 要分享标题 summary : 要分享的文字概述 image url : 图片地址 [以上三个参数至少填写一个] targetUrl
-
* : 用户点击该分享时跳转到的目标地址 [必填] ( 若不填写则默认设置为友盟主页 )
-
* @return
-
*/
-
private void addQQQZonePlatform() {
-
String appId = "100424468";
-
String appKey = "c7394704798a158208a74ab60104f0ba";
-
// 添加QQ支持, 并且设置QQ分享内容的target url
-
UMQQSsoHandler qqSsoHandler = new UMQQSsoHandler(LoginActivity.this,
-
appId, appKey);
-
// qqSsoHandler.setTargetUrl("http://www.umeng.com");
-
// qqSsoHandler.addToSocialSDK();
-
-
// 添加QZone平台
-
QZoneSsoHandler qZoneSsoHandler = new QZoneSsoHandler(
-
LoginActivity.this, appId, appKey);
-
// qZoneSsoHandler.addToSocialSDK();
-
}
-
-
-
@Override
-
public void onClick(View v) {
-
int nid = v.getId();
-
if (nid == R.id.btn_sina_login) {
-
login(SHARE_MEDIA.SINA);
-
return;
-
}else if (nid == R.id.btn_qq_login) {
-
login(SHARE_MEDIA.QQ);
-
return;
-
}else if (nid == R.id.btn_wechat_login) {
-
login(SHARE_MEDIA.WEIXIN);
-
return;
-
}else if (nid == R.id.btn_sina_logout) {
-
logout(SHARE_MEDIA.SINA);
-
return;
-
}else if (nid == R.id.btn_qq_logout) {
-
logout(SHARE_MEDIA.QQ);
-
return;
-
}else if (nid == R.id.btn_wechat_logout) {
-
logout(SHARE_MEDIA.WEIXIN);
-
return;
-
}
-
}
-
-
/**
-
* 授权。如果授权成功,则获取用户信息
-
*
-
* @param platform
-
*/
-
private void login(final SHARE_MEDIA platform) {
-
mController.doOauthVerify(LoginActivity.this, platform,
-
new UMAuthListener() {
-
-
@Override
-
public void onStart(SHARE_MEDIA platform) {
-
Toast.makeText(LoginActivity.this, "授权开始",
-
Toast.LENGTH_SHORT).show();
-
}
-
-
@Override
-
public void onError(SocializeException e,
-
SHARE_MEDIA platform) {
-
Toast.makeText(LoginActivity.this, "授权失败",
-
Toast.LENGTH_SHORT).show();
-
}
-
-
@Override
-
public void onComplete(Bundle value, SHARE_MEDIA platform) {
-
Toast.makeText(LoginActivity.this, "授权完成",
-
Toast.LENGTH_LONG).show();
-
// 获取uid
-
String uid = value.getString("uid");
-
if (!TextUtils.isEmpty(uid)) {
-
// uid不为空,获取用户信息
-
getUserInfo(platform);
-
} else {
-
Toast.makeText(LoginActivity.this, "授权失败...",
-
Toast.LENGTH_LONG).show();
-
}
-
}
-
-
@Override
-
public void onCancel(SHARE_MEDIA platform) {
-
Toast.makeText(LoginActivity.this, "授权取消",
-
Toast.LENGTH_SHORT).show();
-
}
-
});
-
}
-
-
/**
-
* 获取用户信息
-
*
-
* @param platform
-
*/
-
private void getUserInfo(SHARE_MEDIA platform) {
-
mController.getPlatformInfo(LoginActivity.this, platform,
-
new UMDataListener() {
-
-
@Override
-
public void onStart() {
-
-
}
-
-
@Override
-
public void onComplete(int status, Map<String, Object> info) {
-
// String showText = "";
-
// if (status == StatusCode.ST_CODE_SUCCESSED) {
-
// showText = "用户名:" +
-
// info.get("screen_name").toString();
-
// Log.d("#########", "##########" + info.toString());
-
// } else {
-
// showText = "获取用户信息失败";
-
// }
-
-
if (info != null) {
-
Toast.makeText(LoginActivity.this, info.toString(),Toast.LENGTH_SHORT).show();
-
}
-
}
-
});
-
}
-
-
/**
-
* 注销本次登陆
-
* @param platform
-
*/
-
private void logout(final SHARE_MEDIA platform) {
-
mController.deleteOauth(LoginActivity.this, platform, new SocializeClientListener() {
-
-
@Override
-
public void onStart() {
-
-
}
-
-
@Override
-
public void onComplete(int status, SocializeEntity entity) {
-
String showText = "解除" + platform.toString() + "平台授权成功";
-
if (status != StatusCode.ST_CODE_SUCCESSED) {
-
showText = "解除" + platform.toString() + "平台授权失败[" + status + "]";
-
}
-
Toast.makeText(LoginActivity.this, showText, Toast.LENGTH_SHORT).show();
-
}
-
});
-
}
-
-
-
// 如果有使用任一平台的SSO授权, 则必须在对应的activity中实现onActivityResult方法, 并添加如下代码
-
@Override
-
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-
super.onActivityResult(requestCode, resultCode, data);
-
// 根据requestCode获取对应的SsoHandler,返回一定是requestCode
-
UMSsoHandler ssoHandler = mController.getConfig().getSsoHandler(requestCode);
-
if (ssoHandler != null) {
-
ssoHandler.authorizeCallBack(requestCode, resultCode, data);
-
}
-
}
-
}
-
</span>
这上面代码我在测试时候,微博是成功的。然后qq那个**不行,我注释掉了配置到平台的代码。微信那个审核最严格,没有App Key以及App Secret是行不通。我的那个还在微信那边审核,开通那个开发者身份资质认证需要300元的。一堆资料填写审核。。。
实现效果如下:
这张是微博授权界面
授权通过返回的数据:
最后一张是,我在友盟官网有选择性下载的一个demo的界面。那个友盟demo我也有源码,现在懂得怎样开发了。
四、开发过程中遇到的问题:
1、编译出现以下错误
[2015-11-27 15:05:23 - Dex Loader] Unable to execute dex: Multiple dex files define Lcom/sina/sso/RemoteSSO;
[2015-11-27 15:05:23 - SouthGnssServer] Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lcom/sina/sso/RemoteSSO;
出现这个是有重复的库,删掉一个就可以了。如下两张图的比较。
一是没有集成到一个SocialSDK_Sina.jar里面,放在外面的包下面com.sina.sso,这个需要额外添加这个包下.aidl文件。包名还是这个com.sina.sso。不能变。
二是有集成SocialSDK_Sina.jar里面。这个不用再外面添加了。如有添加,就会出现编译错误。
2、带签名调试的问题,解决办法如下:(我也是网上找的资料如下,个人觉得写的总结最清晰)
修改Android签名证书keystore的密码、别名alias以及别名密码
之前在测试Eclipse ADT的Custom debug keystore自定义调试证书的时候,发过一篇关于调试证书规格的博文:Eclipse
ADT的Custom debug keystore所需证书规格,提到过自定义调试证书的密码和alias命名以及alias密码都是有规矩的。其实Android应用开发接入各种SDK时会发现,有很多SDK是需要靠package name和keystore的指纹hash来识别的(百度地图SDK、Facebook SDK等等…),这样如果使用默认自动生成的debug keystore的话就会给开发调试工作带来一些麻烦。这时可以通过修改正式的release keystore,生成一份“遵守规矩”的临时自定义调试证书给开发时用,就方便多了,具体方法如下:
1. 首先当然是先复制一份正式证书出来作为要修改为的临时调试证书。
2. 修改keystore密码的命令(keytool为JDK带的命令行工具):
keytool -storepasswd -keystore my.keystore
其中,my.keystore是复制出来的证书文件,执行后会提示输入证书的当前密码,和新密码以及重复新密码确认。这一步需要将密码改为android。
3. 修改keystore的alias:
keytool -changealias -keystore my.keystore -alias my_name -destalias androiddebugkey
这一步中,my_name是证书中当前的alias,-destalias指定的是要修改为的alias,这里按规矩来,改为androiddebugkey!这个命令会先后提示输入keystore的密码和当前alias的密码。
4. 修改alias的密码:
keytool -keypasswd -keystore my.keystore -alias androiddebugkey
这一步执行后会提示输入keystore密码,alias密码,然后提示输入新的alias密码,同样,按规矩来,改为android!
以上几个操作执行后,my.keystore就是符合规矩的debug keystore了,接着在Eclipse的ADT设置中选中这个custom debug keystore即可。
五、参考资料
我的写代码也有参考这个大神的发布的demo:
http://blog.****.net/wwj_748/article/details/41117173
友盟官方第三方文档支持:
http://dev.umeng.com/social/android/operation
http://dev.umeng.com/social/android/login-page
友盟论坛:友盟社会化分享集成问题索引
http://bbs.umeng.com/thread-5908-1-1.html?from=qianming