Android 实现QQ第三方登录(这种方法感觉不太实用了,因为友盟可以集成很多的第三方登录http://dev.umeng.com/social/android/android-update,有兴趣的可以看看,比较全,但是qq,weixin,sina等还是需要申请appkey的)
转载请加地址:http://blog.csdn.net/jing110fei/article/details/39159491
在项目中需要实现QQ第三方登录,经过一番努力算是写出来了,现在总结以下,以防以后遗忘,能帮到其他童鞋就更好了。
首先肯定是去下载SDK和DEMO
http://wiki.open.qq.com/wiki/mobile/SDK下载
加个SDK方便下载的地址 http://wiki.connect.qq.com/sdk%E4%B8%8B%E8%BD%BD#androidsdk
本文是我自己整合后的简单DEMO。
先看下效果图吧
原理:我们要使用QQ登录我们的应用,不是不用注册,是我们在后台为用户注册了,但是用户不知道,注册需要唯一标识,上图的那串字母与数字的组合就是我们要获得的唯一标识:OpenID.
跟着代码来说吧。
首先,我们要加载open_sdk.jar和mta-sdk-1.00.jar这两个架包顺便看下我总共用到的类
其中,AppConstant中是用来放置APPID的,由于考虑到还可能引入其他第三方登录,为方便管理,故创建此类。Util是根据路径从网上获取图片的处理类
好了进入主题
首先在AndroidManifest.xml中进行两个定义如果不定义是不行的
- <activity
- android:name="com.tencent.tauth.AuthActivity"
- android:launchMode="singleTask"
- android:noHistory="true" >
- <intent-filter>
- <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" /><!—注意在这里用你的appid替换222222 -->
- </intent-filter>
- </activity>
- <activity android:name="com.tencent.connect.common.AssistActivity"
- android:theme="@android:style/Theme.Translucent.NoTitleBar"
- android:screenOrientation="portrait"/>
<activity
android:name="com.tencent.tauth.AuthActivity"
android:launchMode="singleTask"
android:noHistory="true" >
<intent-filter>
<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" /><!—注意在这里用你的appid替换222222 -->
</intent-filter>
</activity>
<activity android:name="com.tencent.connect.common.AssistActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:screenOrientation="portrait"/>
然后是两个权限
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
接下来是布局文件,activity_main.xml登录按钮,获取头像、昵称、openid的textview
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical">
- <Button
- android:id="@+id/login"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="登录"/>
- <ImageView
- android:id="@+id/user_logo"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- <TextView
- android:id="@+id/user_nickname"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="#80505050"
- android:textSize="18sp"
- />
- <TextView
- android:id="@+id/user_openid"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="@+id/login"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="登录"/>
<ImageView
android:id="@+id/user_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/user_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#80505050"
android:textSize="18sp"
/>
<TextView
android:id="@+id/user_openid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
然后是MainActivity
- public class MainActivity extends Activity implements OnClickListener {
- TextView openidTextView;
- TextView nicknameTextView;
- Button loginButton;
- ImageView userlogo;
- private Tencent mTencent;
- public static QQAuth mQQAuth;
- public static String mAppid;
- public static String openidString;
- public static String nicknameString;
- public static String TAG="MainActivity";
- Bitmap bitmap = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //用来登录的Button
- loginButton=(Button)findViewById(R.id.login);
- loginButton.setOnClickListener(this);
- //用来显示OpenID的textView
- openidTextView=(TextView)findViewById(R.id.user_openid);
- //用来显示昵称的textview
- nicknameTextView=(TextView)findViewById(R.id.user_nickname);
- //用来显示头像的Imageview
- userlogo=(ImageView)findViewById(R.id.user_logo);
- }
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch (v.getId()) {
- case R.id.login:
- LoginQQ();
- break;
- default:
- break;
- }
- }
- //这里是调用QQ登录的关键代码
- public void LoginQQ() {
- //这里的APP_ID请换成你应用申请的APP_ID,我这里使用的是DEMO中官方提供的测试APP_ID 222222
- mAppid = AppConstant.APP_ID;
- //第一个参数就是上面所说的申请的APPID,第二个是全局的Context上下文,这句话实现了调用QQ登录
- mTencent = Tencent.createInstance(mAppid,getApplicationContext());
- /**通过这句代码,SDK实现了QQ的登录,这个方法有三个参数,第一个参数是context上下文,第二个参数SCOPO 是一个String类型的字符串,表示一些权限
- 官方文档中的说明:应用需要获得哪些API的权限,由“,”分隔。例如:SCOPE = “get_user_info,add_t”;所有权限用“all”
- 第三个参数,是一个事件监听器,IUiListener接口的实例,这里用的是该接口的实现类 */
- mTencent.login(MainActivity.this,"all", new BaseUiListener());
- }
- /**当自定义的监听器实现IUiListener接口后,必须要实现接口的三个方法,
- * onComplete onCancel onError
- *分别表示第三方登录成功,取消 ,错误。*/
- private class BaseUiListener implements IUiListener {
- public void onCancel() {
- // TODO Auto-generated method stub
- }
- public void onComplete(Object response) {
- // TODO Auto-generated method stub
- Toast.makeText(getApplicationContext(), "登录成功", 0).show();
- try {
- //获得的数据是JSON格式的,获得你想获得的内容
- //如果你不知道你能获得什么,看一下下面的LOG
- Log.e(TAG, "-------------"+response.toString());
- openidString = ((JSONObject) response).getString("openid");
- openidTextView.setText(openidString);
- Log.e(TAG, "-------------"+openidString);
- //access_token= ((JSONObject) response).getString("access_token"); //expires_in = ((JSONObject) response).getString("expires_in");
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- /**到此已经获得OpneID以及其他你想获得的内容了
- QQ登录成功了,我们还想获取一些QQ的基本信息,比如昵称,头像什么的,这个时候怎么办?
- sdk给我们提供了一个类UserInfo,这个类中封装了QQ用户的一些信息,我么可以通过这个类拿到这些信息
- 如何得到这个UserInfo类呢? */
- QQToken qqToken = mTencent.getQQToken();
- UserInfo info = new UserInfo(getApplicationContext(), qqToken);
- //这样我们就拿到这个类了,之后的操作就跟上面的一样了,同样是解析JSON
public class MainActivity extends Activity implements OnClickListener {
TextView openidTextView;
TextView nicknameTextView;
Button loginButton;
ImageView userlogo;
private Tencent mTencent;
public static QQAuth mQQAuth;
public static String mAppid;
public static String openidString;
public static String nicknameString;
public static String TAG="MainActivity";
Bitmap bitmap = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//用来登录的Button
loginButton=(Button)findViewById(R.id.login);
loginButton.setOnClickListener(this);
//用来显示OpenID的textView
openidTextView=(TextView)findViewById(R.id.user_openid);
//用来显示昵称的textview
nicknameTextView=(TextView)findViewById(R.id.user_nickname);
//用来显示头像的Imageview
userlogo=(ImageView)findViewById(R.id.user_logo);
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.login:
LoginQQ();
break;
default:
break;
}
}
//这里是调用QQ登录的关键代码
public void LoginQQ() {
//这里的APP_ID请换成你应用申请的APP_ID,我这里使用的是DEMO中官方提供的测试APP_ID 222222
mAppid = AppConstant.APP_ID;
//第一个参数就是上面所说的申请的APPID,第二个是全局的Context上下文,这句话实现了调用QQ登录
mTencent = Tencent.createInstance(mAppid,getApplicationContext());
/**通过这句代码,SDK实现了QQ的登录,这个方法有三个参数,第一个参数是context上下文,第二个参数SCOPO 是一个String类型的字符串,表示一些权限
官方文档中的说明:应用需要获得哪些API的权限,由“,”分隔。例如:SCOPE = “get_user_info,add_t”;所有权限用“all”
第三个参数,是一个事件监听器,IUiListener接口的实例,这里用的是该接口的实现类 */
mTencent.login(MainActivity.this,"all", new BaseUiListener());
}
/**当自定义的监听器实现IUiListener接口后,必须要实现接口的三个方法,
* onComplete onCancel onError
*分别表示第三方登录成功,取消 ,错误。*/
private class BaseUiListener implements IUiListener {
public void onCancel() {
// TODO Auto-generated method stub
}
public void onComplete(Object response) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "登录成功", 0).show();
try {
//获得的数据是JSON格式的,获得你想获得的内容
//如果你不知道你能获得什么,看一下下面的LOG
Log.e(TAG, "-------------"+response.toString());
openidString = ((JSONObject) response).getString("openid");
openidTextView.setText(openidString);
Log.e(TAG, "-------------"+openidString);
//access_token= ((JSONObject) response).getString("access_token"); //expires_in = ((JSONObject) response).getString("expires_in");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/**到此已经获得OpneID以及其他你想获得的内容了
QQ登录成功了,我们还想获取一些QQ的基本信息,比如昵称,头像什么的,这个时候怎么办?
sdk给我们提供了一个类UserInfo,这个类中封装了QQ用户的一些信息,我么可以通过这个类拿到这些信息
如何得到这个UserInfo类呢? */
QQToken qqToken = mTencent.getQQToken();
UserInfo info = new UserInfo(getApplicationContext(), qqToken);
//这样我们就拿到这个类了,之后的操作就跟上面的一样了,同样是解析JSON
- info.getUserInfo(new IUiListener() {
- public void onComplete(final Object response) {
- // TODO Auto-generated method stub
- Log.e(TAG, "---------------111111");
- Message msg = new Message();
- msg.obj = response;
- msg.what = 0;
- mHandler.sendMessage(msg);
- Log.e(TAG, "-----111---"+response.toString());
- /**由于图片需要下载所以这里使用了线程,如果是想获得其他文字信息直接
- * 在mHandler里进行操作
- *
- */
- new Thread(){
- @Override
- public void run() {
- // TODO Auto-generated method stub
- JSONObject json = (JSONObject)response;
- try {
- bitmap = Util.getbitmap(json.getString("figureurl_qq_2"));
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- Message msg = new Message();
- msg.obj = bitmap;
- msg.what = 1;
- mHandler.sendMessage(msg);
- }
- }.start();
- }
- public void onCancel() {
- Log.e(TAG, "--------------111112");
- // TODO Auto-generated method stub
- }
- public void onError(UiError arg0) {
- // TODO Auto-generated method stub
- Log.e(TAG, "-111113"+":"+arg0);
- }
- });
- }
- public void onError(UiError arg0) {
- // TODO Auto-generated method stub
- }
- }
- Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == 0) {
- JSONObject response = (JSONObject) msg.obj;
- if (response.has("nickname")) {
- try {
- nicknameString=response.getString("nickname");
- nicknameTextView.setText(nicknameString);
- Log.e(TAG, "--"+nicknameString);
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }else if(msg.what == 1){
- Bitmap bitmap = (Bitmap)msg.obj;
- userlogo.setImageBitmap(bitmap);
- }
- }
- };
- }
info.getUserInfo(new IUiListener() {
public void onComplete(final Object response) {
// TODO Auto-generated method stub
Log.e(TAG, "---------------111111");
Message msg = new Message();
msg.obj = response;
msg.what = 0;
mHandler.sendMessage(msg);
Log.e(TAG, "-----111---"+response.toString());
/**由于图片需要下载所以这里使用了线程,如果是想获得其他文字信息直接
* 在mHandler里进行操作
*
*/
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
JSONObject json = (JSONObject)response;
try {
bitmap = Util.getbitmap(json.getString("figureurl_qq_2"));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg = new Message();
msg.obj = bitmap;
msg.what = 1;
mHandler.sendMessage(msg);
}
}.start();
}
public void onCancel() {
Log.e(TAG, "--------------111112");
// TODO Auto-generated method stub
}
public void onError(UiError arg0) {
// TODO Auto-generated method stub
Log.e(TAG, "-111113"+":"+arg0);
}
});
}
public void onError(UiError arg0) {
// TODO Auto-generated method stub
}
}
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
JSONObject response = (JSONObject) msg.obj;
if (response.has("nickname")) {
try {
nicknameString=response.getString("nickname");
nicknameTextView.setText(nicknameString);
Log.e(TAG, "--"+nicknameString);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}else if(msg.what == 1){
Bitmap bitmap = (Bitmap)msg.obj;
userlogo.setImageBitmap(bitmap);
}
}
};
}
上图是登录Q的返回LOG
上图是我们获得腾讯提供的UserInfo返回的LOG
然后是AppConstant.java
- public class AppConstant {
- public static String APP_ID="222222";
- }
public class AppConstant {
public static String APP_ID="222222";
}
然后是Util.java
- public class Util {
- public static String TAG="UTIL";
- public static Bitmap getbitmap(String imageUri) {
- Log.v(TAG, "getbitmap:" + imageUri);
- // 显示网络上的图片
- Bitmap bitmap = null;
- try {
- URL myFileUrl = new URL(imageUri);
- HttpURLConnection conn = (HttpURLConnection) myFileUrl
- .openConnection();
- conn.setDoInput(true);
- conn.connect();
- InputStream is = conn.getInputStream();
- bitmap = BitmapFactory.decodeStream(is);
- is.close();
- Log.v(TAG, "image download finished." + imageUri);
- } catch (IOException e) {
- e.printStackTrace();
- Log.v(TAG, "getbitmap bmp fail---");
- return null;
- }
- return bitmap;
- }
- }
public class Util {
public static String TAG="UTIL";
public static Bitmap getbitmap(String imageUri) {
Log.v(TAG, "getbitmap:" + imageUri);
// 显示网络上的图片
Bitmap bitmap = null;
try {
URL myFileUrl = new URL(imageUri);
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
Log.v(TAG, "image download finished." + imageUri);
} catch (IOException e) {
e.printStackTrace();
Log.v(TAG, "getbitmap bmp fail---");
return null;
}
return bitmap;
}
}
至此全部代码就在这里了,我们获得了OpenID这个唯一标识最关键的东西,然后看项目中需要登录的接口还需要什么信息,获取到就能实现登陆了。
结束。