android 实现qq登录

关于QQ授权登录的实现,官网有详细描述

这里根据自己的实现过程简单介绍一下整个过程:

1. 注册成为开发者,创建应用,获取appid,这个appid后面要用到。详情步骤请查看官网链接

2. 在你的Android工程中导入SDK库文件 open_sdk.jar   和mta-sdk.jar

3. 配置AndroidManifest

    申请权限,加入appid,声明SDK中的activity

4. 创建Tencent类实例,实现回调接口IUiListener,IRequestListener

5. 调用QQ登录接口 

scope参数官网上竟然没有给说明是什么,官方demo中指定的是"all"

     调用Tencent.login(this, Scope, listener)

     其中listener是IUiListener接口,在登录成功后会调用onComplete回调,返回类似下面格式的JSONObject对象:

{
"ret":0,   //表示登录成功
"pay_token":"xxxxxxxxxxxxxxxx",
"pf":"openmobile_android",
"expires_in":"7776000",
"openid":"xxxxxxxxxxxxxxxxxxx",
"pfkey":"xxxxxxxxxxxxxxxxxxx",
"msg":"sucess",
"access_token":"xxxxxxxxxxxxxxxxxxxxx"
}


6. 获取用户信息

    在登录成功后,调用如下接口获取用户信息,此时的listener是IUiListener接口

   

// 获得用户的详细信息,返回的是一个json字符串
	public void getUserInfo() {
		/*
		 * qq官方api中使用的这种方法,不过Constants.GRAPH_SIMPLE_USER_INFO参数找不到表示很蛋疼
		 * 然后去看官方的demo,得知demo中使用的是userinfo的对象..下面是获取信息的代码,返回的是json字符串
		 * tencent.requestAsync(Constants.GRAPH_SIMPLE_USER_INFO, null,
		 * Constants.HTTP_GET, new BaseApiListener("get_simple_userinfo",
		 * false), null);
		 */
		
		//官方的demo中new BaseIuiListener(Main.this,"get_simple_userinfo")第二个参数也没有用到
		//好吧..这个就算没有第二个参数也是可以的...表示很不理解啊..官方个坑货
		UserInfo userInfo = new UserInfo(Main.this, tencent.getQQToken());
		userInfo.getUserInfo(new BaseIuiListener(Main.this));
		ValueTextView.setText(userInfo.toString());

	}


    {
"is_yellow_year_vip": "0",
"ret": 0,
"figureurl_qq_1":
"http://q.qlogo.cn/qqapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/40",
"figureurl_qq_2":
"http://q.qlogo.cn/qqapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/100",
"nickname": "小罗",
"yellow_vip_level": "0",
"msg": "",
"figureurl_1":
"http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/50",
"vip": "0",
"level": "0",
"figureurl_2":
"http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/100",
"is_yellow_vip": "0",
"gender": "男",
"figureurl":
"http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/30"
}

7.分享到qq

//分享...这个腾讯给提供的也不是正确的...或者时过境迁了...
	//方法里面本来有一个view类型的参数
	public void share() {
		Bundle bundle = new Bundle();
		// 这条分享消息被好友点击后的跳转URL。
		bundle.putString(QQShare.SHARE_TO_QQ_TARGET_URL, "http://connect.qq.com/");
		// 分享的标题。注:PARAM_TITLE、PARAM_IMAGE_URL、PARAM_ SUMMARY不能全为空,最少必须有一个是有值的。
		bundle.putString(QQShare.SHARE_TO_QQ_TITLE, "我在测试");
		// 分享的图片URL
		bundle.putString(QQShare.SHARE_TO_QQ_IMAGE_URL,
				"http://img3.cache.netease.com/photo/0005/2013-03-07/8PBKS8G400BV0005.jpg");
		// 分享的消息摘要,最长50个字
		bundle.putString(QQShare.SHARE_TO_QQ_SUMMARY, "测试_我是摘要");
		// 手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替
		bundle.putString(QQShare.SHARE_TO_QQ_APP_NAME, "我在测试_appname");
		// 标识该消息的来源应用,值为应用名称+AppId。
		bundle.putString(QQShare.SHARE_TO_QQ_KEY_TYPE, "星期几" + idString);

		tencent.shareToQQ(this, bundle, new BaseIuiListener(Main.this));
	}


到这里已经基本完成了QQ授权登录。


有几个问题还需要注意:

1.appid的有效性

  应用要上线并且通过审核后,使用的appid才可以正常进行QQ授权,否则只有你注册的QQ号可以成功授权登录,换其他QQ号登录时授权会失败。

  解决办法:

  a.应用申请上线,不过有的应用需要提供软件著作权

  b.设置协作者账号(点击官网说明,默认情况是注册的QQ为协作者帐号,可以添加多个)

  c.使用官网给的测试用的appid(222222)


2.没有调用回调

如果发生这种情况,检查一下这一条:

应用调用Andriod_SDK接口时,如果要成功接收到回调,需要在调用接口的Activity的onActivityResult方法中增加如下代码:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mTencent.onActivityResult(requestCode, resultCode, data);
}


下面是我自己的demo的代码

package com.example.testQQloginshare;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;

import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.testQQloginshare.R.id;
import com.tencent.connect.UserInfo;
import com.tencent.connect.auth.QQToken;
import com.tencent.connect.common.Constants;
import com.tencent.connect.share.QQShare;
import com.tencent.open.utils.HttpUtils.HttpStatusException;
import com.tencent.open.utils.HttpUtils.NetworkUnavailableException;
import com.tencent.tauth.IRequestListener;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;

public class Main extends Activity {

	private Button qqloginButton, qqlogoutButton, qqgetuserinfo, btn_share;
	private TextView ValueTextView;
	private Tencent tencent;
	// 现在使用的appid是腾讯提供的..因为我们的id需要项目上线之后才可以正常使用
	private String idString = "222222";
	private String idStringmy = "1104296989 ";
	private static String tag = "testqq";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		tencent = Tencent
				.createInstance(idString, this.getApplicationContext());

		initView();
	}

	private void initView() {

		Btnlistener btnlistener = new Btnlistener();
		// 登录按钮
		qqloginButton = (Button) findViewById(R.id.btn_qqlogin);
		qqloginButton.setOnClickListener(btnlistener);
		// 注销按钮
		qqlogoutButton = (Button) findViewById(R.id.btn_qqlogout);
		qqlogoutButton.setOnClickListener(btnlistener);
		// 获得用户信息
		qqgetuserinfo = (Button) findViewById(R.id.btn_getuserinfo);
		qqgetuserinfo.setOnClickListener(btnlistener);
		// 分享按钮
		btn_share = (Button) findViewById(R.id.btn_share);
		btn_share.setOnClickListener(btnlistener);

		ValueTextView = (TextView) findViewById(R.id.tv_value);
	}

	// 登录函数
	public void login() {
		// 我擦..前面的感叹号很重要,,,天哪...竟然在这里出问题..浪费了很多时间,而且官方文档里面竟然没有对
		// login的第二个参数进行说明.这个还是去看demo才知道要写什么的
		if (!tencent.isSessionValid()) {
			tencent.login(Main.this, "all", new BaseIuiListener(Main.this));
		}
	}

	// 注销函数
	public void logout() {
		tencent.logout(this);
	}

	// 获得用户的详细信息,返回的是一个json字符串
	public void getUserInfo() {
		/*
		 * qq官方api中使用的这种方法,不过Constants.GRAPH_SIMPLE_USER_INFO参数找不到表示很蛋疼
		 * 然后去看官方的demo,得知demo中使用的是userinfo的对象..下面是获取信息的代码,返回的是json字符串
		 * tencent.requestAsync(Constants.GRAPH_SIMPLE_USER_INFO, null,
		 * Constants.HTTP_GET, new BaseApiListener("get_simple_userinfo",
		 * false), null);
		 */
		
		//官方的demo中new BaseIuiListener(Main.this,"get_simple_userinfo")第二个参数也没有用到
		//好吧..这个就算没有第二个参数也是可以的...表示很不理解啊..官方个坑货
		UserInfo userInfo = new UserInfo(Main.this, tencent.getQQToken());
		userInfo.getUserInfo(new BaseIuiListener(Main.this));
		ValueTextView.setText(userInfo.toString());

	}

	//分享...这个腾讯给提供的也不是正确的...或者时过境迁了...
	//方法里面本来有一个view类型的参数
	public void share() {
		Bundle bundle = new Bundle();
		// 这条分享消息被好友点击后的跳转URL。
		bundle.putString(QQShare.SHARE_TO_QQ_TARGET_URL, "http://connect.qq.com/");
		// 分享的标题。注:PARAM_TITLE、PARAM_IMAGE_URL、PARAM_ SUMMARY不能全为空,最少必须有一个是有值的。
		bundle.putString(QQShare.SHARE_TO_QQ_TITLE, "我在测试");
		// 分享的图片URL
		bundle.putString(QQShare.SHARE_TO_QQ_IMAGE_URL,
				"http://img3.cache.netease.com/photo/0005/2013-03-07/8PBKS8G400BV0005.jpg");
		// 分享的消息摘要,最长50个字
		bundle.putString(QQShare.SHARE_TO_QQ_SUMMARY, "测试_我是摘要");
		// 手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替
		bundle.putString(QQShare.SHARE_TO_QQ_APP_NAME, "我在测试_appname");
		// 标识该消息的来源应用,值为应用名称+AppId。
		bundle.putString(QQShare.SHARE_TO_QQ_KEY_TYPE, "星期几" + idString);

		tencent.shareToQQ(this, bundle, new BaseIuiListener(Main.this));
	}

	// 即使没有这个依然是可以实现登录的啊
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		tencent.onActivityResult(requestCode, resultCode, data);
	}

	private class Btnlistener implements OnClickListener {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.btn_qqlogin:
				Toast.makeText(Main.this, "点击了登录按钮", Toast.LENGTH_LONG).show();
				login();
				break;
			case R.id.btn_qqlogout:
				logout();
				break;
			case R.id.btn_getuserinfo:
				getUserInfo();
				break;
			case R.id.btn_share:
				share();
				break;
			default:
				break;
			}
		}

	}

	// 登录的时候是使用的这个回调,获取用户详细信息的时候还是这个回调,分享的时候也是使用的这个监听
	//调用SDK已经封装好的接口时,例如:登录、快速支付登录、应用分享、应用邀请等接口,需传入该回调的实例。
	//IUiListener的实现示例代码如下:
	private class BaseIuiListener implements IUiListener {

		private Context mContext;
		private String mScope;

		public BaseIuiListener(Context mContext) {
			super();
			this.mContext = mContext;
		}

		public BaseIuiListener(Context mContext, String mScope) {
			super();
			this.mContext = mContext;
			this.mScope = mScope;
		}

		@Override
		public void onCancel() {
			Toast.makeText(Main.this, "onCancel", Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onComplete(Object arg0) {
			Toast.makeText(Main.this, "onComplete:" + arg0.toString(),
					Toast.LENGTH_SHORT).show();
			ValueTextView.setText(arg0.toString());
		}

		@Override
		public void onError(UiError arg0) {
			Toast.makeText(Main.this, "onError", Toast.LENGTH_SHORT).show();
		}

	}

	//使用requestAsync、request等通用方法调用sdk未封装的接口时,例如上传图片、查看相册等,需传入该回调的实例。
	//本工程没有使用到这个监听
	//IRequestListener的实现示例代码如下:
	public class BaseApiListener implements IRequestListener {
		@Override
		public void onComplete(JSONObject arg0) {
			Toast.makeText(Main.this,
					"BaseApiListener onComplete:" + arg0.toString(),
					Toast.LENGTH_SHORT).show();
			ValueTextView.setText(arg0.toString());
		}

		@Override
		public void onConnectTimeoutException(ConnectTimeoutException arg0) {
			Toast.makeText(Main.this, "onConnectTimeoutException",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onHttpStatusException(HttpStatusException arg0) {
			Toast.makeText(Main.this, "onHttpStatusException",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onIOException(IOException arg0) {
			Toast.makeText(Main.this, "onIOException", Toast.LENGTH_SHORT)
					.show();
		}

		@Override
		public void onJSONException(JSONException arg0) {
			Toast.makeText(Main.this, "onJSONException", Toast.LENGTH_SHORT)
					.show();
		}

		@Override
		public void onMalformedURLException(MalformedURLException arg0) {
			Toast.makeText(Main.this, "onMalformedURLException",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onNetworkUnavailableException(
				NetworkUnavailableException arg0) {
			Toast.makeText(Main.this, "onNetworkUnavailableException",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onSocketTimeoutException(SocketTimeoutException arg0) {
			Toast.makeText(Main.this, "onSocketTimeoutException",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onUnknowException(Exception arg0) {
			Toast.makeText(Main.this, "onUnknowException", Toast.LENGTH_SHORT)
					.show();
		}

	}
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值