編輯:關於Android編程
寫在前面的話
應用要接入QQ登錄,分享,需要在QQ的開發者平台上進行提交應用,並且審核通過,應用已經獲取到appId。
官網下載:
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中進行如下配置:
第二步:初始化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 imgList = new ArrayList();
JSONObject object = new JSONObject(imageUrlJson);
JSONArray jsonArray = object.optJSONArray("imgs");
for (int i=0;i
第四步:獲取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授權的。
我這個是基於混合開發的,所以回調部分大家可以忽略,其他方法是通用的。
隨著Android設備增多,不少網站都開始設備Android設備,而Android主流設備類型以手機和平板為主。網站在適配時通過User Agent(用戶代理,以下簡稱U
第一步:注冊開發者賬號,—->微信開放平台https://open.weixin.qq.com/第二步:創建一個應用,並通過審核(其中需要填寫項目中的D
大家好,感覺好像已經很久沒更新博客了。前段時間主要是忙於新書的事情,時間比較緊張。而現在新書已經完稿,剩下的事情就都 是出版社的工作了,那麼我又可以抽出時間來寫寫博客了。
使用SlidingTabLayout需要准備2個類,分別是 SlidingTabLayout,與SlidingTabStrip,,放進項目中時只用修改下包名即可。效果制作