本文讲述三种实现微博三方登录的接口方法,其实说是三种,但他们只有一个微小的区别,就是进入授权页面前调用的方法名不同而已
1. SSO单点登录方式授权,调用这种方法只能在你手机安装了新浪微博APP的前提下才能实现
2. Web页面登录方式授权,这种方法会跳出一个微博登录的Web页面,从而实现登录
3. all in one方式授权,此种授权方式会根据手机是否安装微博客户端来决定使用sso授权还是网页授权,如果安装有微博客户端 则调用微博客户端授权,否则调用Web页面方式授权
下面是具体实现的流程:
一、授权部分(在代码中获取到一个Oauth2AccessToken对象)
1.上新浪微博开放平台申请APP key 和App secret ,具体步骤省略,无非就是填写一些应用程序的信息,还是非常容易的申请到的(未注册新浪的开发者账号可能需要先注册一个账号),下面是申请成功后的界面
http://open.weibo.com/
2.在上面的界面中“基本信息”目录下填写Android 包名(你项目的包名)、Android签名(需要下载签名工具生成项目对应的签名)等信息,然后点击保存
然后在“高级信息”下添加回调页(http://api.weibo.com/oauth2/default.html),然后点击提交
如果运行测试的时候,登录的账号不是注册应用的账号,那么还需要在“测试信息”下添加测试账号,然后点击保存
3.下载SDK 地址:http://open.weibo.com/wiki/SDK
4.在工程的main文件夹下新建一个jniLibs文件夹(不要拼错),将SDK中libs文件夹下的所有文件夹全部拷到工程中jnilib目录下。再将weiboSDKCore_3.1.4.jar包引入到工程中。
5.添加权限
7.Java代码中需要三个对象
初始化对象
8.定义一个WeiBoAuthListener的实现类,不管是上面提到的哪一种授权方式,都会需要这个实现类
9.下面是各种授权方式调用的方法(可以看到,三种登录方式主要的不同就表现在这——ssohandler对象调用方法不同)
注意:如果是使用web授权,则需要在AndroidManifest.xml中申明以下Activity
10.很容易落下的一步,重写onActivityResult方法,否则调不到回调方法
如此,授权部分便全部实现了
二、获取用户的基本信息(通过上面获取到的Oauth2AccessToken对象获取用户基本信息)
11.要获取信息,应该需要将SDK中的weibosdk作为库引入到工程中(我直接引了它的jar包,经验证可以实现)。
先声明一个变量
然后在上面weiboAuthListener的onComplete回调方法中将getUserInfo();那句代码的注释去掉。getUserInfo()方法的实现如下。
这样就可以获取到用户的基本信息了!
User类中的各项信息可参考: http://open.weibo.com/wiki/2/users/show
本demo参照SDK中“新文档”文件夹下的Word文档6.1、7.1完成。
Demo下载地址:http://download.csdn.net/detail/highboys/9597488
做过新浪微博第三方登录的朋友都清楚,他们的官方文档写的真心糟糕,添加新应用也很麻烦。我也是一边看文档,一边看demo,摸爬滚打才实现第三方登录的功能。今天和大家分享一个完整的开发流程,从申请开发者账号,到集成SDK,到代码编写。ps:我所使用的是SDK版本是weiboSDKCore_3.1.2
第一步:申请开发者账号,官网http://open.weibo.com
登录或注册新浪微博账号
然后创建新应用,创建的时候要注意几点:
拿到APPID,我的应用->应用信息->基本信息
我的应用->应用信息->基本信息
包名是指AndroidManifest.xml文件里面package属性对应的内容
签名必须通过官方提供的MD5签名工具生成,可百度搜索,我这里也有链接http://pan.baidu.com/s/1qWlD1LE
大概长这个样儿,对照着签名填写到官网的Android签名那栏就好。
点击我的应用->应用信息->高级信息,填写回调地址,这个是授权成功后调用的地址,后续再代码编写的时候会用到,必须保持一致,可以使用http://www.sina.com
添加测试账号,
第二步:集成SDK,
到官网下载最新的SDK文件,
或者用我这里提供的
http://pan.baidu.com/s/1sjFxEbz
把目录weibo_android_sdk-master\libs下的6个文件夹拷贝到工程的libs文件中,
和weibo_android_sdk-master目录下的weiboSDKCore_3.1.2.jar复制到libs文件中
然后再选中weiboSDKCore_3.1.2.jar右键Build Path->Add to Build Path
至此集成已经成功一半
修改AndroidManifest.xml文件,添加以下代码
<activity
android:name="com.sina.weibo.sdk.component.WeiboSdkBrowser"
android:configChanges="keyboardHidden|orientation"
android:exported="false"
android:windowSoftInputMode="adjustResize" >
</activity>
<service
android:name="com.sina.weibo.sdk.net.DownloadService"
android:exported="false" >
</service>
添加权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
这样SDK算是集成完毕了
第三步:代码编写
我主要是参考官方demo来写的,关键是三个java文件
LoginActivity,集中调用新浪微博API的类,实现了第三方授权,登录,退出,登录时显示用户信息的功能
package com.example.thirdpartyloginafc;
import java.text.SimpleDateFormat;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
import com.sina.weibo.sdk.auth.WeiboAuthListener;
import com.sina.weibo.sdk.auth.sso.SsoHandler;
import com.sina.weibo.sdk.exception.WeiboException;
public class LoginActivity extends Activity implements OnClickListener {
private AuthInfo mAuthInfo;
private Button btnweibo;
private Button btnlogout;
private TextView tv;
private String nickname="";
/** 封装了 "access_token","expires_in","refresh_token",并提供了他们的管理功能 */
private Oauth2AccessToken mAccessToken;
/** 注意:SsoHandler 仅当 SDK 支持 SSO 时有效 */
private SsoHandler mSsoHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initweibologin();
initViews();
initEvents();
initData();
}
private void initData() {
// TODO Auto-generated method stub
// 从 SharedPreferences 中读取上次已保存好 AccessToken 等信息,
// 第一次启动本应用,AccessToken 不可用
mAccessToken = AccessTokenKeeper.readAccessToken(this);
if (mAccessToken.isSessionValid()) {
updateTokenView(true);
}
}
private void initViews() {
btnweibo = (Button) findViewById(R.id.btn_weibo_login);
btnlogout = (Button) findViewById(R.id.btnlogout);
tv = (TextView) findViewById(R.id.content);
// 获取 Token View,并让提示 View 的内容可滚动(小屏幕可能显示不全)
tv.setMovementMethod(new ScrollingMovementMethod());
}
private void initEvents() {
btnweibo.setOnClickListener(this);
btnlogout.setOnClickListener(this);
}
/**
* 进行微博授权初始化操作
*/
private void initweibologin() {
// TODO Auto-generated method stub
// 初始化授权类对象,将应用的信息保存
mAuthInfo = new AuthInfo(this, Constants.APP_KEY,
Constants.REDIRECT_URL, Constants.SCOPE);
mSsoHandler = new SsoHandler(LoginActivity.this, mAuthInfo);
}
/**
* 当 SSO 授权 Activity 退出时,该函数被调用。
*
* @see {@link Activity#onActivityResult}
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// SSO 授权回调
// 重要:发起 SSO 登陆的 Activity 必须重写 onActivityResults
if (mSsoHandler != null) {
mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_weibo_login:// SSO 授权, ALL IN ONE
// 如果手机安装了微博客户端则使用客户端授权,没有则进行网页授权
mSsoHandler.authorize(new AuthListener());
break;
case R.id.btnlogout:// 用户登出
nickname = "";
AccessTokenKeeper.clear(getApplicationContext());
mAccessToken = new Oauth2AccessToken();
updateTokenView(false);
break;
default:
break;
}
}
/**
* 微博认证授权回调类。 1. SSO 授权时,需要在 {@link #onActivityResult} 中调用
* {@link SsoHandler#authorizeCallBack} 后, 该回调才会被执行。 2. 非 SSO
* 授权时,当授权结束后,该回调就会被执行。 当授权成功后,请保存该 access_token、expires_in、uid 等信息到
* SharedPreferences 中。
*/
class AuthListener implements WeiboAuthListener {
@Override
public void onCancel() {
// TODO Auto-generated method stub
Toast.makeText(LoginActivity.this, "取消授权", Toast.LENGTH_LONG)
.show();
}
@Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
// 从 Bundle 中解析 Token
mAccessToken = Oauth2AccessToken.parseAccessToken(values);
if (mAccessToken.isSessionValid()) {
nickname = "用户名:"
+ String.valueOf(values
.get("com.sina.weibo.intent.extra.NICK_NAME"));
// 显示 Token
updateTokenView(false);
// 保存 Token 到 SharedPreferences
AccessTokenKeeper.writeAccessToken(LoginActivity.this,
mAccessToken);
Toast.makeText(LoginActivity.this, "授权成功", Toast.LENGTH_SHORT)
.show();
// Toast.makeText(
// LoginActivity.this,
// "头像地址:"
// + String.valueOf(values
// .get("com.sina.weibo.intent.extra.USER_ICON")),
// Toast.LENGTH_LONG).show();
Toast.makeText(LoginActivity.this, nickname, Toast.LENGTH_LONG)
.show();
} else {
// 以下几种情况,您会收到 Code:
// 1. 当您未在平台上注册的应用程序的包名与签名时;
// 2. 当您注册的应用程序包名与签名不正确时;
// 3. 当您在平台上注册的包名和签名与您当前测试的应用的包名和签名不匹配时。
String code = values.getString("code");
String message = "授权失败";
if (!TextUtils.isEmpty(code)) {
message = message + "\nObtained the code: " + code;
}
Toast.makeText(LoginActivity.this, message, Toast.LENGTH_LONG)
.show();
}
}
@Override
public void onWeiboException(WeiboException e) {
// TODO Auto-generated method stub
Toast.makeText(LoginActivity.this,
"Auth exception : " + e.getMessage(), Toast.LENGTH_LONG)
.show();
}
}
/**
* 显示当前 Token 信息。
*
* @param hasExisted
* 配置文件中是否已存在 token 信息并且合法
*/
private void updateTokenView(boolean hasExisted) {
String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
.format(new java.util.Date(mAccessToken.getExpiresTime()));
String format = getString(R.string.weibosdk_demo_token_to_string_format_1);
tv.setText(String.format(format, mAccessToken.getToken(), date));
String message = String.format(format, mAccessToken.getToken(), date);
if (hasExisted) {
message = getString(R.string.weibosdk_demo_token_has_existed)
+ "\n" + message;
}
message += "\n" + nickname;
tv.setText(message);
}
}
package com.example.thirdpartyloginafc;
/*
* Copyright (C) 2010-2013 The SINA WEIBO Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
/**
* 该类定义了微博授权时所需要的参数。
*
* @author SINA
* @since 2013-10-07
*/
public class AccessTokenKeeper {
private static final String PREFERENCES_NAME = "com_weibo_sdk_android";
private static final String KEY_UID = "uid";
private static final String KEY_ACCESS_TOKEN = "access_token";
private static final String KEY_EXPIRES_IN = "expires_in";
private static final String KEY_REFRESH_TOKEN = "refresh_token";
/**
* 保存 Token 对象到 SharedPreferences。
*
* @param context
* 应用程序上下文环境
* @param token
* Token 对象
*/
public static void writeAccessToken(Context context, Oauth2AccessToken token) {
if (null == context || null == token) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME,
Context.MODE_APPEND);
Editor editor = pref.edit();
editor.putString(KEY_UID, token.getUid());
editor.putString(KEY_ACCESS_TOKEN, token.getToken());
editor.putString(KEY_REFRESH_TOKEN, token.getRefreshToken());
editor.putLong(KEY_EXPIRES_IN, token.getExpiresTime());
editor.commit();
}
/**
* 从 SharedPreferences 读取 Token 信息。
*
* @param context
* 应用程序上下文环境
*
* @return 返回 Token 对象
*/
public static Oauth2AccessToken readAccessToken(Context context) {
if (null == context) {
return null;
}
Oauth2AccessToken token = new Oauth2AccessToken();
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME,
Context.MODE_APPEND);
token.setUid(pref.getString(KEY_UID, ""));
token.setToken(pref.getString(KEY_ACCESS_TOKEN, ""));
token.setRefreshToken(pref.getString(KEY_REFRESH_TOKEN, ""));
token.setExpiresTime(pref.getLong(KEY_EXPIRES_IN, 0));
return token;
}
/**
* 清空 SharedPreferences 中 Token信息。
*
* @param context
* 应用程序上下文环境
*/
public static void clear(Context context) {
if (null == context) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME,
Context.MODE_APPEND);
Editor editor = pref.edit();
editor.clear();
editor.commit();
}
}
package com.example.thirdpartyloginafc;
public class Constants {
public static final String APP_KEY = "自己的id";
public static final String REDIRECT_URL = "与网页对应的回调地址;
public static final String SCOPE = "email,direct_messages_read,direct_messages_write,"
+ "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
+ "follow_app_official_microblog," + "invitation_write";
}
运行结果
授权成功
官方开放了三种登录方式,第一种是通过客户端登录,第二种是通过web登录,第三种是先尝试通过客户端登录,如果没有安装客户端,就通过web登录,这里使用的是第三种方式
本例子的代码:http://pan.baidu.com/s/1nttlgt7
导入工程之后,记得修改Constants里面的APP_KEY和REDIRECT_URL,有问题欢迎交流!!
微博开发sdk 及开发帮助文档的地址
https://github.com/sinaweibosdk/weibo_android_sdk
Android 实现QQ第三方登录
在项目中需要实现QQ第三方登录,经过一番努力算是写出来了,现在总结以下,以防以后遗忘,能帮到其他童鞋就更好了。
首先肯定是去下载SDK和DEMO
http://wiki.open.qq.com/wiki/mobile/SDK下载
本文是我自己整合后的简单DEMO。
先看下效果图吧
原理:我们要使用QQ登录我们的应用,不是不用注册,是我们在后台为用户注册了,但是用户不知道,注册需要唯一标识,上图的那串字母与数字的组合就是我们要获得的唯一标识:OpenID.
跟着代码来说吧。
首先,我们要加载open_sdk.jar和mta-sdk-1.00.jar这两个架包顺便看下我总共用到的类
其中,AppConstant中是用来放置APPID的,由于考虑到还可能引入其他第三方登录,为方便管理,故创建此类。Util是根据路径从网上获取图片的处理类
好了进入主题
首先在AndroidManifest.xml中进行两个定义如果不定义是不行的
01.
<activity
02.
android:name=
"com.tencent.tauth.AuthActivity"
03.
android:launchMode=
"singleTask"
04.
android:noHistory=
"true"
>
05.
<intent-filter>
06.
<action android:name=
"android.intent.action.VIEW"
/>
07.
08.
<category android:name=
"android.intent.category.DEFAULT"
/>
09.
<category android:name=
"android.intent.category.BROWSABLE"
/>
10.
11.
<data android:scheme=
"tencent222222"
/><!—注意在这里用你的appid替换
222222
-->
12.
</intent-filter>
13.
</activity>
14.
<activity android:name=
"com.tencent.connect.common.AssistActivity"
15.
android:theme=
"@android:style/Theme.Translucent.NoTitleBar"
16.
android:screenOrientation=
"portrait"
/>
然后是两个权限
1.
<uses-permission android:name=
"android.permission.INTERNET"
/>
2.
<uses-permission android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
接下来是布局文件,activity_main.xml登录按钮,获取头像、昵称、openid的textview
01.
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
02.
xmlns:tools=
"http://schemas.android.com/tools"
03.
android:layout_width=
"fill_parent"
04.
android:layout_height=
"fill_parent"
05.
android:orientation=
"vertical"
>
06.
<Button
07.
android:id=
"@+id/login"
08.
android:layout_width=
"fill_parent"
09.
android:layout_height=
"wrap_content"
10.
android:text=
"登录"
/>
11.
<ImageView
12.
android:id=
"@+id/user_logo"
13.
android:layout_width=
"wrap_content"
14.
android:layout_height=
"wrap_content"
15.
/>
16.
<TextView
17.
android:id=
"@+id/user_nickname"
18.
android:layout_width=
"wrap_content"
19.
android:layout_height=
"wrap_content"
20.
android:textColor=
"#80505050"
21.
android:textSize=
"18sp"
22.
/>
23.
<TextView
24.
android:id=
"@+id/user_openid"
25.
android:layout_width=
"wrap_content"
26.
android:layout_height=
"wrap_content"
27.
/>
28.
29.
</LinearLayout>
然后是MainActivity
01.
public
class
MainActivity
extends
Activity
implements
OnClickListener {
02.
TextView openidTextView;
03.
TextView nicknameTextView;
04.
Button loginButton;
05.
ImageView userlogo;
06.
private
Tencent mTencent;
07.
public
static
QQAuth mQQAuth;
08.
public
static
String mAppid;
09.
public
static
String openidString;
10.
public
static
String nicknameString;
11.
public
static
String TAG=
"MainActivity"
;
12.
Bitmap bitmap =
null
;
13.
@Override
14.
public
void
onCreate(Bundle savedInstanceState) {
15.
super
.onCreate(savedInstanceState);
16.
setContentView(R.layout.activity_main);
17.
//用来登录的Button
18.
loginButton=(Button)findViewById(R.id.login);
19.
loginButton.setOnClickListener(
this
);
20.
//用来显示OpenID的textView
21.
openidTextView=(TextView)findViewById(R.id.user_openid);
22.
//用来显示昵称的textview
23.
nicknameTextView=(TextView)findViewById(R.id.user_nickname);
24.
//用来显示头像的Imageview
25.
userlogo=(ImageView)findViewById(R.id.user_logo);
26.
27.
}
28.
public
void
onClick(View v) {
29.
// TODO Auto-generated method stub
30.
switch
(v.getId()) {
31.
case
R.id.login:
32.
LoginQQ();
33.
break
;
34.
35.
default
:
36.
break
;
37.
}
38.
}
39.
//这里是调用QQ登录的关键代码
40.
public
void
LoginQQ() {
41.
//这里的APP_ID请换成你应用申请的APP_ID,我这里使用的是DEMO中官方提供的测试APP_ID 222222
42.
mAppid = AppConstant.APP_ID;
43.
//第一个参数就是上面所说的申请的APPID,第二个是全局的Context上下文,这句话实现了调用QQ登录
44.
mTencent = Tencent.createInstance(mAppid,getApplicationContext());
45.
/**通过这句代码,SDK实现了QQ的登录,这个方法有三个参数,第一个参数是context上下文,第二个参数SCOPO 是一个String类型的字符串,表示一些权限
46.
官方文档中的说明:应用需要获得哪些API的权限,由“,”分隔。例如:SCOPE = “get_user_info,add_t”;所有权限用“all”
47.
第三个参数,是一个事件监听器,IUiListener接口的实例,这里用的是该接口的实现类 */
48.
mTencent.login(MainActivity.
this
,
"all"
,
new
BaseUiListener());
49.
50.
}
51.
/**当自定义的监听器实现IUiListener接口后,必须要实现接口的三个方法,
52.
* onComplete onCancel onError
53.
*分别表示第三方登录成功,取消 ,错误。*/
54.
private
class
BaseUiListener
implements
IUiListener {
55.
56.
public
void
onCancel() {
57.
// TODO Auto-generated method stub
58.
59.
}
60.
public
void
onComplete(Object response) {
61.
// TODO Auto-generated method stub
62.
Toast.makeText(getApplicationContext(),
"登录成功"
,
0
).show();
63.
try
{
64.
//获得的数据是JSON格式的,获得你想获得的内容
65.
//如果你不知道你能获得什么,看一下下面的LOG
66.
Log.e(TAG,
"-------------"
+response.toString());
67.
openidString = ((JSONObject) response).getString(
"openid"
);
68.
openidTextView.setText(openidString);
69.
Log.e(TAG,
"-------------"
+openidString);
70.
//access_token= ((JSONObject) response).getString("access_token"); //expires_in = ((JSONObject) response).getString("expires_in");
71.
}
catch
(JSONException e) {
72.
// TODO Auto-generated catch block
73.
e.printStackTrace();
74.
}
75.
/**到此已经获得OpneID以及其他你想获得的内容了
76.
QQ登录成功了,我们还想获取一些QQ的基本信息,比如昵称,头像什么的,这个时候怎么办?
77.
sdk给我们提供了一个类UserInfo,这个类中封装了QQ用户的一些信息,我么可以通过这个类拿到这些信息
78.
如何得到这个UserInfo类呢? */
79.
Q<a href=
"http://www.it165.net/pro/pkqt/"
target=
"_blank"
class
=
"keylink"
>QT</a>oken qqToken = mTencent.getQ<a href=
"http://www.it165.net/pro/pkqt/"
target=
"_blank"
class
=
"keylink"
>QT</a>oken();
80.
UserInfo info =
new
UserInfo(getApplicationContext(), <a href=
"http://www.it165.net/qq/"
target=
"_blank"
class
=
"keylink"
>qq</a>Token);
81.
//这样我们就拿到这个类了,之后的操作就跟上面的一样了,同样是解析JSON
01.
info.getUserInfo(
new
IUiListener() {
02.
03.
public
void
onComplete(
final
Object response) {
04.
// TODO Auto-generated method stub
05.
Log.e(TAG,
"---------------111111"
);
06.
Message msg =
new
Message();
07.
msg.obj = response;
08.
msg.what =
0
;
09.
mHandler.sendMessage(msg);
10.
Log.e(TAG,
"-----111---"
+response.toString());
11.
/**由于图片需要下载所以这里使用了线程,如果是想获得其他文字信息直接
12.
* 在mHandler里进行操作
13.
*
14.
*/
15.
new
Thread(){
16.
17.
@Override
18.
public
void
run() {
19.
// TODO Auto-generated method stub
20.
JSONObject json = (JSONObject)response;
21.
try
{
22.
bitmap = Util.getbitmap(json.getString(
"figureurl_<a href="
http:
//www.it165.net/qq/" target="_blank" class="keylink">qq</a>_2"));
23.
}
catch
(JSONException e) {
24.
// TODO Auto-generated catch block
25.
e.printStackTrace();
26.
}
27.
Message msg =
new
Message();
28.
msg.obj = bitmap;
29.
msg.what =
1
;
30.
mHandler.sendMessage(msg);
31.
}
32.
}.start();
33.
}
34.
public
void
onCancel() {
35.
Log.e(TAG,
"--------------111112"
);
36.
// TODO Auto-generated method stub
37.
}
38.
public
void
onError(UiError arg0) {
39.
// TODO Auto-generated method stub
40.
Log.e(TAG,
"-111113"
+
":"
+arg0);
41.
}
42.
43.
});
44.
45.
}
46.
47.
public
void
onError(UiError arg0) {
48.
// TODO Auto-generated method stub
49.
50.
}
51.
52.
}
53.
Handler mHandler =
new
Handler() {
54.
55.
@Override
56.
public
void
handleMessage(Message msg) {
57.
if
(msg.what ==
0
) {
58.
JSONObject response = (JSONObject) msg.obj;
59.
if
(response.has(
"nickname"
)) {
60.
try
{
61.
nicknameString=response.getString(
"nickname"
);
62.
63.
nicknameTextView.setText(nicknameString);
64.
Log.e(TAG,
"--"
+nicknameString);
65.
}
catch
(JSONException e) {
66.
// TODO Auto-generated catch block
67.
e.printStackTrace();
68.
}
69.
}
70.
}
else
if
(msg.what ==
1
){
71.
Bitmap bitmap = (Bitmap)msg.obj;
72.
userlogo.setImageBitmap(bitmap);
73.
74.
}
75.
}
76.
77.
};
78.
79.
80.
}
上图是登录Q的返回LOG
上图是我们获得腾讯提供的UserInfo返回的LOG
然后是AppConstant.Java
1.
public
class
AppConstant {
2.
public
static
String APP_ID=
"222222"
;
3.
}
然后是Util.java
01.
public
class
Util {
02.
public
static
String TAG=
"UTIL"
;
03.
public
static
Bitmap getbitmap(String imageUri) {
04.
Log.v(TAG,
"getbitmap:"
+ imageUri);
05.
// 显示网络上的图片
06.
Bitmap bitmap =
null
;
07.
try
{
08.
URL myFileUrl =
new
URL(imageUri);
09.
HttpURLConnection conn = (HttpURLConnection) myFileUrl
10.
.openConnection();
11.
conn.setDoInput(
true
);
12.
conn.connect();
13.
InputStream is = conn.getInputStream();
14.
bitmap = BitmapFactory.decodeStream(is);
15.
is.close();
16.
17.
Log.v(TAG,
"image download finished."
+ imageUri);
18.
}
catch
(IOException e) {
19.
e.printStackTrace();
20.
Log.v(TAG,
"getbitmap bmp fail---"
);
21.
return
null
;
22.
}
23.
return
bitmap;
24.
}
25.
}
至此全部代码就在这里了,我们获得了OpenID这个唯一标识最关键的东西,然后看项目中需要登录的接口还需要什么信息,获取到就能实现登陆了。
qq 官方文档参考
http://wiki.open.qq.com/wiki/创建并配置工程
http://wiki.open.qq.com/wiki/创建实例并实现回调
http://wiki.open.qq.com/wiki/QQ登录和注销
http://wiki.open.qq.com/wiki/mobile/ SDK下载地址
Android 微信第三方登录
这两天,解决了微信第三方授权登录的问题,作为一个新手,想想也是一把辛酸泪。我想着,就把我的遇到的坑给大家分享一下,避免新手遇到我这样的问题能够顺利避开。
步骤一 微信开发者平台
我开始的解决思路是,去微信开发者平台看API文档。
这个API文档的主要意思呢,有三点:
1、你得下载这几样东西(下载链接),一个是他的范例代码,一个是他的签名生成工具。
2、如果你自己的APP想要微信第三方授权,你得去申请一个APPID,这个APPID呢,就是微信给咱们APP分配的一个代号。当然微信不是免费给你服务,为了获得这个第三方授权的功能,你得给微信交300块钱。申请到这个授权之后,你需要填写一个应用包名,和一个应用签名。
应用包名
应用签名
使用签名生成工具,输入包名,查询到应用签名
3、然后打开DEMO
程序的入口WXEntryActivity是我们所最需要关注的
1
2
3
4
5
|
// 微信发送请求到第三方应用时,会回调到该方法
@Override
public
void
onReq(BaseReq req) {
// TODO
}
|
当点击授权登陆的界面的时候,会自动调用这个onResp方法,所以我们可以在这里面取得所需要token。注意andorid里叫token,ios里面叫code,而不是因为sdk版本的问题,这是需要注意的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
@Override
public
void
onResp(BaseResp resp) {
int
result = 0;
switch
(resp.errCode) {
case
BaseResp.ErrCode.ERR_OK:
result = R.
string
.errcode_success;
/*获取token*/
SendAuth.Resp sendResp = (SendAuth.Resp) resp;
String code = sendResp.token;
Log.d(
"Tag"
,
"code\t"
+ code);
break
;
case
BaseResp.ErrCode.ERR_USER_CANCEL:
result = R.
string
.errcode_cancel;
break
;
case
BaseResp.ErrCode.ERR_AUTH_DENIED:
result = R.
string
.errcode_deny;
break
;
default
:
result = R.
string
.errcode_unknown;
break
;
}
|
APP_ID 替换为你的应用从官方网站申请到的合法appId
1
2
3
4
|
public
class
Constants {
// APP_ID 替换为你的应用从官方网站申请到的合法appId
public
static
final String APP_ID =
"wx77777"
;
}
|
1
2
3
4
5
6
7
|
// IWXAPI 是第三方app和微信通信的openapi接口
private
IWXAPI api;
final SendAuth.Req req =
new
SendAuth.Req();
req.scope =
"snsapi_userinfo"
;
req.state =
"wechat_sdk_demo_test"
;
//发送授权登陆请求
api.sendReq(req);
|
这一步就是和微信要code。执行了这一段代码之后。微信会调用刚才WXEntityActivity类里面的onResp()方法。并且把code返回来了。见上面那一段代码。获取到code之后就可以通过code获取access_token了。
请求以下链接获取access_token:
这步和微信通信获得access_token就是普通的访问链接。 用httpClient就行了,而不是接入指南里说的那个和微信通信的方法onReq().然后还是这样的方式通过access_token.就可以调用接口获得用户基本信息了。具体返回参数什么的接入指南里面说的很清楚。至此微信授权基本是成功了。
这里,我们要添加Custom debug keystore。上面的那个debug keystore不会和微信通信。
而我们添加的这个keystore 也要符合一些规范所以要改一改。
不过在开发的过程中要注意一下debug keystore。
步骤二 Android studio如何生成keystore文件
第一步 创建签名文件
第二步 填写签名参数
第三步 选择构建类型
第四步 查看生成第apk文件
步骤三 Android studio如何定位keystore文件
在运行微信分享Demo及新浪微博分享Demo时,需要修改使用Demo中的debug.keystore才能运行授权及和分享。
在进行Android开发中,所用到的工具,就Eclispse和Android Studio比较多。其中,使用Eclipse里修改debug.keystore的方式新浪微博文档有介绍,在Eclipse里点击"Windows-->Preferences-->Android-->Build",在右边的"Custom debug keystore"选择Demo中的debug.keystore即可。
在Android Studio中的做法是"Project Structure"中“Modules”中的应用的模块。然后选择"Signing",点击"+"号,起名为“debug”,并在“Store File”里选择Demo中的debug.keystore,如下图
然后在选择“Build Types”在“debug”中的"Signing Config"选择上面配置的"debug",如下图
点击“OK”,重新编译就可以了。
通过上面配置完后,会自动在项目模块中的build.gradle里的android {}里生成
1
2
3
4
5
|
signingConfigs {
debug {
storeFile file(
'.keystore里文件路径'
)
}
}
|
以及在buildTypes里生成
1
2
3
|
debug {
signingConfig signingConfigs.debug
}
|
当然啦,可以不用界面配置,直接在build.gradle里写上面的配置也都OK的
步骤四 获取签名 填写到微信开发者平台
接下来将定位到jks文件的工程烧写到程序中,然后将签名工具的MD码填写到微信开发者平台,就能调用第三方授权登陆了。
效果图
参考链接:
Android Studio修改debug.keystore
需要参考以下网址:android 接入 微信
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=&lang=zh_CN
移动应用微信登录开发指南
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=&lang=zh_CN
授权后接口调用(UnionID)
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317853&token=&lang=zh_CN