写在前面的话
应用要接入QQ登录,分享,需要在QQ的开发者平台上进行提交应用,并且审核通过,应用已经获取到appId。
相关jar包下载地址:http://download.csdn.net/detail/sapce_fish/9570936
也可到官网下载:
http://wiki.open.qq.com/wiki/mobile/SDK%E4%B8%8B%E8%BD%BD
将 open_sdk_r5509.jar,mta-sdk-1.6.2.jar两个jar包引进自己的项目中
第一步:在Manifest中进行如下配置:
<!-- 微信登录相关权限 开始 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 微信登录相关权限 结束 -->
<!-- 腾讯QQ登录相关配置 开始 -->
<activity android:name="com.tencent.tauth.AuthActivity" android:launchMode="singleTask" android:noHistory="true">
<intent-filter tools:ignore="GoogleAppIndexingDeepLinkError">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- <data android:scheme="tencent222222" /> -->
</intent-filter>
</activity>
<activity android:name="com.tencent.connect.common.AssistActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<!-- 腾讯QQ登录相关配置 结束 -->
第二步:初始化Tencent实例,openId,token以及相关回调
初始化Tencent实例
/** * 初始化各社交平台的sdk */
private void initSocial() {
//初始化腾讯QQ相关
if (mTencent == null) {
mTencent = Tencent.createInstance(AppConstants.APP_ID_QQ, mActivity);
}
}
初始化openid和token
/** 初始化openid和token***/
private static void initOpenidAndToken(String token,String expires,String openId) {
if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires)
&& !TextUtils.isEmpty(openId)) {
mTencent.setAccessToken(token, expires);
mTencent.setOpenId(openId);
}
}
Tencent登录回调接口
/***Tencent登录回调接口实现*/
IUiListener qqLoginListener = new IUiListener()
{
@Override
public void onError(UiError e)
{
Log.i("space", "onError"+e.toString());
JsCallbackExecutor.onSocialQQLoginResult(CallbackCode.LOGIN_FAIL,e.toString());
}
@Override
public void onComplete(Object response)
{
if (null == response) {
Log.i("space", "返回为空登录失败 response is null");
JsCallbackExecutor.onSocialQQLoginResult(CallbackCode.LOGIN_FAIL, "response is null");
return;
}
JSONObject jsonResponse = (JSONObject) response;
if (null != jsonResponse && jsonResponse.length() == 0) {
Log.i("space", "返回为空登录失败");
JsCallbackExecutor.onSocialQQLoginResult(CallbackCode.LOGIN_FAIL, "response is null");
return;
}
try {
String token = jsonResponse.optString(Constants.PARAM_ACCESS_TOKEN);
String expires = jsonResponse.optString(Constants.PARAM_EXPIRES_IN);
String openId = jsonResponse.optString(Constants.PARAM_OPEN_ID);
initOpenidAndToken(token, expires, openId);
JsCallbackExecutor.onSocialQQLoginResult(CallbackCode.SUCCESS, response.toString());
} catch(Exception e) {
Log.i("space", "initOpenidAndToken抛出异常");
JsCallbackExecutor.onSocialQQLoginResult(CallbackCode.JSON_EXCEPTION, e.toString());
}
}
@Override
public void onCancel()
{
Log.i("space", "onCancel");
JsCallbackExecutor.onSocialQQLoginResult(CallbackCode.LOGIN_CANCEL, "user cancel login");
}
};
Tencent分享回调
/** 分享回调实现类*/
IUiListener qqShareListener = new IUiListener()
{
@Override
public void onError(UiError e)
{
Log.i("space", "分享异常");
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_ERROR, "share error");
}
@Override
public void onComplete(Object response)
{
if (null == response) {
Log.i("space", "返回为空失败");
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_ERROR, "share error");
return;
}
JSONObject jsonResponse = (JSONObject) response;
if (null != jsonResponse && jsonResponse.length() == 0) {
Log.i("space", "返回为空失败");
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_ERROR, "share error");
return;
}
Log.i("space", "分享成功" + response.toString());
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SUCCESS, response.toString());
}
@Override
public void onCancel()
{
Log.i("space", "取消了分享");
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_CANCEL, "user cancel share");
}
};
重写onActivityResult
/** TencentQQ在某些低端机上调用登录后,由于内存紧张导致APP被系统回收,登录成功后无法成功回传数据。 * 解决办法为在调用login的Activity或者Fragment重写onActivityResult方法 */
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Constants.REQUEST_LOGIN ||
requestCode == Constants.REQUEST_APPBAR) {
Tencent.onActivityResultData(requestCode,resultCode,data, qqLoginListener);
}
if (requestCode == Constants.REQUEST_QQ_SHARE ||
requestCode == Constants.REQUEST_QZONE_SHARE)
{
Tencent.onActivityResultData(requestCode, resultCode, data, qqShareListener);
}
}
第三步:QQ登录,注销,分享
QQ登录
/** * qq登录 */
@JavascriptInterface
public void qqLogin(){
if (!mTencent.isSessionValid())
{
mTencent.login(mActivity, "all", qqLoginListener);
}else{
Log.i("space","当前为登录状态 openId="+mTencent.getOpenId());
JsCallbackExecutor.onSocialQQLoginResult(CallbackCode.LOGIN_ALREADY,mTencent.getOpenId());
}
}
QQ注销
/** * qq注销 */
@JavascriptInterface
public void qqLogout(){
if(mTencent != null){
mTencent.logout(mActivity);
JsCallbackExecutor.onSocialQQLogoutResult(CallbackCode.SUCCESS, "qq logout success");
}
}
分享消息
/** * 分享消息 * @param title 分享的标题(必填) * @param targetUrl 点击消息后的跳转URL(必填) * @param msg 分享的消息摘要,最长40个字 * @param imgUrl 分享图片的URL或者本地路径 * @param backName 手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替 */
@JavascriptInterface
public void shareMessageToQQ(String title,String targetUrl,String msg,String imgUrl,String backName)
{
if(mTencent == null){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_ERROR, "share error");
return;
}
if(TextUtils.isEmpty(title) || TextUtils.isEmpty(targetUrl)){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.PARAMS_ERROR, "title or targetUrl is null");
return;
}
final Bundle params = new Bundle();
//分享的类型(必填)
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
//分享的标题, 最长30个字符(必填)
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
//这条分享消息被好友点击后的跳转URL(必填)
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
//分享的消息摘要,最长40个字
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, msg);
if(!TextUtils.isEmpty(imgUrl)){
//分享图片的URL或者本地路径
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imgUrl);
}
//手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, backName);
//分享额外选项
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
mTencent.shareToQQ(mActivity, params, qqShareListener);
}
分享纯图片
/** * 分享纯图片 * @param imgLocalUrl 需要分享的本地图片路径(必填) * @param backName 手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替 */
@JavascriptInterface
public void shareImageToQQ(String imgLocalUrl,String backName)
{
if(mTencent == null){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_ERROR, "share error");
return;
}
if(TextUtils.isEmpty(imgLocalUrl)){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.PARAMS_ERROR, "imgLocalUrl is null");
return;
}
final Bundle params = new Bundle();
//分享的类型(必填)
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
//需要分享的本地图片路径(必填)
params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, imgLocalUrl);
//手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, backName);
//分享额外选项
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
mTencent.shareToQQ(mActivity, params, qqShareListener);
}
分享音乐到QQ
/** * 分享音乐到QQ * @param title 分享的标题(必填) * @param targetUrl 这条分享消息被好友点击后的跳转URL(必填) * @param musicNetUrl 分享音乐文件的远程链接, 以URL的形式传入, 不支持本地音乐。(必填) * @param msg 分享的摘要,最长40个字符 * @param imgUrl 分享图片的URL或者本地路径 * @param backName 手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替 */
@JavascriptInterface
public void shareMusicToQQ(String title,String targetUrl,String musicNetUrl,String msg,String imgUrl,String backName)
{
if(mTencent == null){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_ERROR, "share error");
return;
}
if(TextUtils.isEmpty(title) ||TextUtils.isEmpty(targetUrl) || TextUtils.isEmpty(musicNetUrl)){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.PARAMS_ERROR, "title ,targetUrl or musicNetUrl is null");
return;
}
final Bundle params = new Bundle();
//分享的类型(必填)
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_AUDIO);
//分享的标题(必填)
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
//这条分享消息被好友点击后的跳转URL(必填)
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
//分享音乐文件的远程链接, 以URL的形式传入, 不支持本地音乐。(必填)
params.putString(QQShare.SHARE_TO_QQ_AUDIO_URL, musicNetUrl);
if(!TextUtils.isEmpty(msg)){
//分享的摘要,最长40个字符
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, msg);
}
if(!TextUtils.isEmpty(imgUrl)){
//分享图片的URL或者本地路径
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imgUrl);
}
//手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, backName);
//分享额外选项
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
mTencent.shareToQQ(mActivity, params, qqShareListener);
}
分享应用到QQ
/** * 分享应用到QQ * @param title 分享的标题(必填) * @param msg 分享的摘要,最长40个字符 * @param imgUrl 分享图片的URL或者本地路径 * @param backName 手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替 */
@JavascriptInterface
public void shareAppToQQ(String title,String msg,String imgUrl,String backName)
{
if(mTencent == null){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_ERROR, "share error");
return;
}
if(TextUtils.isEmpty(title)){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.PARAMS_ERROR, "title is null");
return;
}
final Bundle params = new Bundle();
//分享的类型(必填)
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_APP);
//分享的标题(必填)
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
//分享的摘要,最长40个字符
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, msg);
if(!TextUtils.isEmpty(imgUrl)){
//分享图片的URL或者本地路径
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imgUrl);
}
//手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, backName);
//分享额外选项
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN);
mTencent.shareToQQ(mActivity, params, qqShareListener);
}
分享图文到QQ空间
/** * 分享图文到QQ空间 * @param title 分享的标题(必填) * @param targetUrl 这条分享消息被好友点击后的跳转URL(必填) * @param msg 分享的摘要,最长40个字符 * @param imageUrlJson 图片地址的json串 图片地址数组名为imgs */
@JavascriptInterface
public void shareToQzone(String title,String targetUrl,String msg,String imageUrlJson)
{
if(mTencent == null){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.SHARE_ERROR, "share error");
return;
}
if(TextUtils.isEmpty(title) || TextUtils.isEmpty(targetUrl)){
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.PARAMS_ERROR, "title or targetUrl is null");
return;
}
final Bundle params = new Bundle();
//分享的类型(必填)
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
//分享的标题(必填)
params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
//这条分享消息被好友点击后的跳转URL(必填)
params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
//分享的摘要,最长40个字符
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, msg);
if(!TextUtils.isEmpty(imageUrlJson)){
try {
ArrayList<String> imgList = new ArrayList<String>();
JSONObject object = new JSONObject(imageUrlJson);
JSONArray jsonArray = object.optJSONArray("imgs");
for (int i=0;i<jsonArray.length();i++){
imgList.add((String) jsonArray.get(i));
}
if(!imgList.isEmpty()){
//图片链接ArrayList
params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imgList);
}
} catch (JSONException e) {
JsCallbackExecutor.onSocialQQShareResult(CallbackCode.JSON_EXCEPTION, "imageUrlJson is error");
e.printStackTrace();
return;
}
}
mTencent.shareToQzone(mActivity, params, qqShareListener);
}
第四步:获取QQ用户信息 获取TencentQQ用户信息
/** * 获取TencentQQ用户信息 * @param token token * @param expires expires * @param openId openId */
@JavascriptInterface
public void getQQUserInfo(String token,String expires,String openId)
{
if(mTencent != null){
if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires)
&& !TextUtils.isEmpty(openId)) {
initOpenidAndToken(token,expires,openId);
}else{
JsCallbackExecutor.onSocialQQUserInfoResult(CallbackCode.PARAMS_ERROR, "token ,expires or openId is null");
return;
}
UserInfo info = new UserInfo(mActivity, mTencent.getQQToken());
info.getUserInfo(new IUiListener() {
@Override
public void onError(UiError arg0) {
Log.i("space", "获取用户信息异常");
JsCallbackExecutor.onSocialQQUserInfoResult(CallbackCode.GET_USER_INFO_ERROR, "get QQ user info error");
}
@Override
public void onComplete(Object obj) {
JSONObject jsonResponse = (JSONObject) obj;
Log.i("space", jsonResponse.toString());
if (0 == jsonResponse.optInt("ret")) {
JsCallbackExecutor.onSocialQQUserInfoResult(CallbackCode.SUCCESS, jsonResponse.toString());
}else{
JsCallbackExecutor.onSocialQQUserInfoResult(CallbackCode.GET_USER_INFO_FAIL, "get user info fail");
}
}
@Override
public void onCancel() {
Log.i("space", "取消获取用户信息");
JsCallbackExecutor.onSocialQQUserInfoResult(CallbackCode.GET_USER_INFO_CANCEL, "get user info cancel");
}
});
}else {
JsCallbackExecutor.onSocialQQUserInfoResult(CallbackCode.GET_USER_INFO_FAIL, "get user info error");
}
}
写在最后
请注意应用的签名是否与QQ开放平台中配置的是否一致查看签名的方法如果不一致的话是拉不起QQ授权的。
我这个是基于混合开发的,所以回调部分大家可以忽略,其他方法是通用的。
另外如果有不明白的地方可以留言。
ps:查看签名的方法:http://blog.csdn.net/sapce_fish/article/details/51636578