extends : http://blog.csdn.net/arjinmc/article/details/38439957
相关官方文档及下载地址:
如果只用分享和登陆,用lite包就可以,体积小
http://wiki.open.qq.com/wiki/mobile/API%E8%B0%83%E7%94%A8%E8%AF%B4%E6%98%8E#1.13_.E5.88.86.E4.BA.AB.E6.B6.88.E6.81.AF.E5.88.B0QQ.EF.BC.88.E6.97.A0.E9.9C.80QQ.E7.99.BB.E5.BD.95.EF.BC.89http://wiki.open.qq.com/wiki/mobile/SDK%E4%B8%8B%E8%BD%BD
本文基于QQ open sdk V2.4.1。
QQ登录应用有一个地方是需要注意的, QQ申请同一品牌应用(包括网站和app),需要相互依赖申请,因为在QQ互联中,一个应用对应一个app key,如果网站和app的app key是不同的,这样相同用户使用QQ登录时候所产生的openid就会不同了,此时无法判断是否为同一个用户。在QQ互联中,一个用户的openid是对应一个应用,也就是说,如果这个用户去登录别的应用,QQ互联返回的openid是不同的。
准备工作:
1.注册腾讯开发者账号,上http://open.qq.com注册,填写好详细信息认证开发者信息,大概等1个工作日就可以审核完毕。
2.审核通过后可以在“管理资料”中创建应用,在这里我们选择的是移动应用。
3.下载open qq给的sdk包(http://wiki.open.qq.com/wiki/mobile/SDK%E4%B8%8B%E8%BD%BD),解压看到,doc是需集成移动数据分析才会使用到,也是一个教程,在这里不介绍了。jar就是open qq提供的jar包,但这里我们只需要用到mta-sdk-1.6.2.jar.我们把这个包复制到我们项目中的libs中,然后配置要引用路径java path。
4.在Manifest中申明权限:
<uses-permissionandroid:nameuses-permissionandroid:name="android.permission.INTERNET" /> <uses-permissionandroid:nameuses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE" />
5.在Manifest中添加这些Activity
<activity android:name="com.tencent.tauth.AuthActivity" android:noHistory="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" /> <!--下面这个XXXXXXXXXXXX就是你申请腾讯开发平台所给的app key--> <data android:scheme="tencentXXXXXXXXXXXX" /> </intent-filter> </activity> <activity android:name="com.tencent.connect.common.AssistActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:configChanges="orientation|keyboardHidden"/>
QQ登录
1. 我们需要一个全局变量public static Tencent mTencent,当然你也可以声明为私有的非静态类型,这个是open qq给的例子中是这么写,为什么要这么用,后面会解释。
2.使用QQ登录:
private void loginByQQ(){ // Constant.QQ_KEY 这里是申请open qq给的app key mTencent =Tencent.createInstance(Constant.QQ_KEY, LoginActivity.this); if (!mTencent.isSessionValid()) { IUiListener listener = newBaseUiListener() { @Override protected voiddoComplete(JSONObject values) { //Log.e("qq",values.toString()); try { //在这里我们可以去到唯一QQ互联可以给我们识别不同QQ用户的openid qqOpenId= values.getString("openid"); } catch(JSONException e) { //TODO Auto-generated catch block e.printStackTrace(); }finally{ if(qqOpenId==null){ qqOpenId= ""; } } ToastUtil.showToast(LoginActivity.this,"login success"); updateUserInfo(); //Log.e("SDKQQAgentPref","AuthorSwitch_SDK:" + SystemClock.elapsedRealtime()); } }; mTencent.login(this,"all", listener); //Log.e("SDKQQAgentPref","FirstLaunch_SDK:" + SystemClock.elapsedRealtime()); } else { mTencent.logout(this); } }
3. 获取QQ登录用户信息
privatevoid updateUserInfo() { if (mTencent != null &&mTencent.isSessionValid()) { IUiListener listener = newIUiListener() { @Override public voidonError(UiError e) { //获取不到这个信息 } @Override public voidonComplete(final Object response) { JSONObjectjson = (JSONObject)response; //Log.e("qquser info", json.toString());可以在这里打印来看看获取到了用户的什么信息,如果你想获取QQ号,那是不可能的 //因为open qq没有提供这样的接口。 StringnickName = getString(R.string.qq_user);//比如QQ昵称 try { nickName= json.getString("nickname"); } catch (JSONException e) { e.printStackTrace(); } } @Override public voidonCancel() { //获取用户信息被取消 } }; UserInfo mInfo = newUserInfo(this, mTencent.getQQToken()); mInfo.getUserInfo(listener); } else { } }
4. 最重还需要一个回调类
private classBaseUiListener implements IUiListener { @Override public void onComplete(Objectresponse) { //V2.0版本,参数类型由JSONObject 改成了Object,具体类型参考api文档 doComplete((JSONObject)response); } protected void doComplete(JSONObjectvalues) { //在这里可以做一些登录成功的处理 ToastUtil.showToast(LoginActivity.this,getString(R.string.login_success)); } @Override public void onError(UiError e) { //在这里可以做登录失败的处理 ToastUtil.showToast(LoginActivity.this,getString(R.string.qq_login_fail)); } @Override public void onCancel() { //在这里可以做登录被取消的处理 ToastUtil.showToast(LoginActivity.this,getString(R.string.qq_login_cancel)); } }
分享到QQ空间
方式一:
在登录的时候,前面我们有用到public static Tencent mTencent,这个变量声明为静态变量,因为在demo例子中,这个mTencent对象在最底的Activty,所以它一直都没有被关闭,一直有效。因此,在这种情况下,我们可以直接用下面这个方法来做QQ分享。
1.分享方法:
privatevoid shareToQQzone(){ mQzoneShare = new QzoneShare(this,LoginActivity.mTencent.getQQToken()); final Bundle params = new Bundle(); //设置分享类型:图文并茂加链接。其他类型见帮助文档 int shareType = QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT; params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, shareType); //标题 params.putString(QzoneShare.SHARE_TO_QQ_TITLE, "测试"); //内容 params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, "contenttext"); if (shareType !=QzoneShare.SHARE_TO_QZONE_TYPE_APP) { //app分享不支持传目标链接 params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL,"http://www.hicsg.com"); } // // 支持传多个imageUrl,在这里我测试只放一张图片,最多可以放9张 ArrayList<String> imageUrls = newArrayList<String>(); imageUrls.add("http://media-cdn.tripadvisor.com/media/photo-s/01/3e/05/40/the-sandbar-that-links.jpg"); // for (int i = 0; i <mImageContainerLayout.getChildCount(); i++) { // LinearLayout addItem = (LinearLayout)mImageContainerLayout.getChildAt(i); // EditText editText = (EditText)addItem.getChildAt(1); // imageUrls.add(editText.getText().toString()); // } // String imageUrl = "XXX"; // params.putString(Tencent.SHARE_TO_QQ_IMAGE_URL,imageUrl); params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls); doShareToQzone(params); }
2. 回调方法:
privatevoid doShareToQzone(final Bundle params) { //final Activity activity =ProductDetailActivity.this; new Thread(new Runnable() { @Override public void run() { Log.e("share","qzone"); // TODO Auto-generated methodstub mQzoneShare.shareToQzone(ProductDetailActivity.this,params, new IUiListener() { @Override public void onCancel() { //取消分享 Log.e("qzone share", "cancel"); } @Override public void onError(UiErrore) { //分享错误 Log.e("qzone share", "error: "+e.errorDetail); } @Override publicvoid onComplete(Object response) { //分享成功 Log.e("qzoneshare", "success"); } }); } }).start(); }
方式二:
当然上面那种方式是比较不符合我们的使用习惯的,比如,我登录了一段时间,先把Activity关闭,我再打开app但是不登录,此时需要做分享处理,上面那个方法就会报空指针异常。此时,我们就需要用这个方法
1. 分享到QQ空间
private void shareToQQzone() { 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, "Test"); params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, "content infro"); params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, "http://www.hicsg.com"); ArrayList<String> imageUrls = new ArrayList<String>(); imageUrls.add("http://media-cdn.tripadvisor.com/media/photo-s/01/3e/05/40/the-sandbar-that-links.jpg"); params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls); params.putInt(QzoneShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN); Tencent mTencent = Tencent.createInstance(Constant.QQ_KEY,ProductDetailActivity.this); mTencent.shareToQzone(ProductDetailActivity.this, params, newBaseUiListener()); }
2. 回调
privateclass BaseUiListener implements IUiListener { @Override public void onComplete(Objectresponse) { //V2.0版本,参数类型由JSONObject 改成了Object,具体类型参考api文档 doComplete((JSONObject)response); } protected void doComplete(JSONObjectvalues) { //分享成功 } @Override public void onError(UiError e) { //在这里处理错误信息 if(e.errorDetail == null){ ToastUtil.showToast(ProductDetailActivity.this,getString(R.string.no_qq)); }else{ ToastUtil.showToast(ProductDetailActivity.this, getString(R.string.share_fail)+":"+e.errorDetail); } } @Override public void onCancel() { //分享被取消 ToastUtil.showToast(ProductDetailActivity.this,getString(R.string.share_cancel)); } }
别忘了要在代码混淆中添加
-keep class com.tencent.open.TDialog$*
-keep class com.tencent.open.TDialog$* {*;}
-keep class com.tencent.open.PKDialog
-keep class com.tencent.open.PKDialog {*;}
-keep class com.tencent.open.PKDialog$*
-keep class com.tencent.open.PKDialog$* {*;}
P.S
测试的时候,需要开发者账号QQ或者加这个QQ为好友才可以进行测试。
-------------------------------------------个人分享方法------------------------------------------
public void shareToQQ() { final Bundle params = new Bundle(); params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT); //分享的标题。注:PARAM_TITLE、PARAM_IMAGE_URL、PARAM_ SUMMARY不能全为空,最少必须有一个是有值的。 params.putString(QQShare.SHARE_TO_QQ_TITLE, shareTitle); params.putString(QQShare.SHARE_TO_QQ_SUMMARY, shareContent); //这条分享消息被好友点击后的跳转URL。 params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, shareUrlLink); //分享的图片URL params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, shareImageLink); //手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替 params.putString(QQShare.SHARE_TO_QQ_APP_NAME, mActivity.getString(R.string.app_name)); // params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, "其他附加功能"); Tencent mTencent = Tencent.createInstance(AppConstants.KEY_QQ, mActivity); mTencent.shareToQQ(mActivity, params, new BaseUiListener()); }
private void shareToQQzone() { 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, shareTitle); params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, shareContent); params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, shareUrlLink); ArrayList<String> imageUrls = new ArrayList<String>(); imageUrls.add(shareImageLink); params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls); params.putInt(QzoneShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN); Tencent mTencent = Tencent.createInstance(AppConstants.KEY_QQ, mActivity); mTencent.shareToQzone(mActivity, params, new BaseUiListener()); }
private class BaseUiListener implements IUiListener { @Override public void onComplete(Object response) { //V2.0版本,参数类型由JSONObject 改成了Object,具体类型参考api文档 doComplete((JSONObject) response); } protected void doComplete(JSONObject values) { //分享成功 // AppUtils.showToast(mActivity, "分享成功"); } @Override public void onError(UiError e) { //在这里处理错误信息 if (e.errorDetail == null) { Log.e("QQShareError", "unknown error"); } else { Log.e("QQShareError", e.errorDetail); } } @Override public void onCancel() { //分享被取消 } }