蚂蚁交易客户端笔记客户端 能不能用第三方登录

Android微信第三方登录(个人笔记)
作者:丶贰九
字体:[ ] 类型:转载 时间:
这篇文章主要为大家详细介绍了Android微信第三方登录的具体过程,个人笔记分享,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
今天在写微信登录,花了半天时间搞定、然后写下自己的笔记,希望帮助更多的人。欢迎各位指教。
微信授权登录,官方说的不是很清楚、所以导致有一部分的坑。
微信注册应用平台的应用签名,下载
输入项目的packageName也可以查看到。
(注意:debug、Release 一定要区分,因为2种生成的微信签名不一致,会导致没有跳转、回调。。。。一般在微信开发者上面注册的是正式环境打包好的、)
申请微信开发者账号、应用申请省略。&
&1. AndroidManifest.xml 权限
&!-- 微信权限--&
&uses-permission android:name="android.permission.INTERNET"/&
&uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/&
&uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/&
&uses-permission android:name="android.permission.READ_PHONE_STATE"/&
&uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&
&2.在图一按钮上面,加上微信跳转方法、也就是启动微信登录的方法
private void loginToWeiXin(){
IWXAPI mApi = WXAPIFactory.createWXAPI(this, WXEntryActivity.WEIXIN_APP_ID, true);
mApi.registerApp(WXEntryActivity.WEIXIN_APP_ID);
if (mApi != null && mApi.isWXAppInstalled()) {
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wechat_sdk_demo_test_neng";
mApi.sendReq(req);
Toast.makeText(this, "用户未安装微信", Toast.LENGTH_SHORT).show();
3.在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity
&package(项目报名).wxapi.WXEntryActivity.Java
回调方法onResp() 方法没有触发回调、请监测WXEntryActivity onCreate中是否调用此方法& mApi.handleIntent(this.getIntent(), this);
package com.xxx.xxxx.android.
* 微信登录页面
* @author kevin_chen
下午19:03:45
* @version v1.0
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
private static final String APP_SECRET = "填写自己的AppSecret";
private IWXAPI mWeixinAPI;
public static final String WEIXIN_APP_ID = "填写自己的APP_id";
private static S
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWeixinAPI = WXAPIFactory.createWXAPI(this, WEIXIN_APP_ID, true);
mWeixinAPI.handleIntent(this.getIntent(), this);
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
mWeixinAPI.handleIntent(intent, this);//必须调用此句话
//微信发送的请求将回调到onReq方法
public void onReq(BaseReq req) {
LogUtils.log("onReq");
//发送到微信请求的响应结果
public void onResp(BaseResp resp) {
LogUtils.log("onResp");
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
LogUtils.log("ERR_OK");
//发送成功
SendAuth.Resp sendResp = (SendAuth.Resp)
if (sendResp != null) {
String code = sendResp.
getAccess_token(code);
case BaseResp.ErrCode.ERR_USER_CANCEL:
LogUtils.log("ERR_USER_CANCEL");
//发送取消
case BaseResp.ErrCode.ERR_AUTH_DENIED:
LogUtils.log("ERR_AUTH_DENIED");
//发送被拒绝
//发送返回
* 获取openid accessToken值用于后期操作
* @param code 请求码
private void getAccess_token(final String code) {
String path = "https://api./sns/oauth2/access_token?appid="
+ WEIXIN_APP_ID
+ "&secret="
+ APP_SECRET
+ "&code="
+ "&grant_type=authorization_code";
LogUtils.log("getAccess_token:" + path);
//网络请求,根据自己的请求方式
VolleyRequest.get(this, path, "getAccess_token", false, null, new VolleyRequest.Callback() {
public void onSuccess(String result) {
LogUtils.log("getAccess_token_result:" + result);
JSONObject jsonObject =
jsonObject = new JSONObject(result);
String openid = jsonObject.getString("openid").toString().trim();
String access_token = jsonObject.getString("access_token").toString().trim();
getUserMesg(access_token, openid);
} catch (JSONException e) {
e.printStackTrace();
public void onError(String errorMessage) {
* 获取微信的个人信息
* @param access_token
* @param openid
private void getUserMesg(final String access_token, final String openid) {
String path = "https://api./sns/userinfo?access_token="
+ access_token
+ "&openid="
LogUtils.log("getUserMesg:" + path);
//网络请求,根据自己的请求方式
VolleyRequest.get(this, path, "getAccess_token", false, null, new VolleyRequest.Callback() {
public void onSuccess(String result) {
LogUtils.log("getUserMesg_result:" + result);
JSONObject jsonObject =
jsonObject = new JSONObject(result);
String nickname = jsonObject.getString("nickname");
int sex = Integer.parseInt(jsonObject.get("sex").toString());
String headimgurl = jsonObject.getString("headimgurl");
LogUtils.log("用户基本信息:");
LogUtils.log("nickname:" + nickname);
LogUtils.log("sex:" + sex);
LogUtils.log("headimgurl:" + headimgurl);
} catch (JSONException e) {
e.printStackTrace();
public void onError(String errorMessage) {
5.在 AndroidManifest.xml 设置注册微信的页面
当授权时候进入WXEntryActivity、当前背景可能是黒或白,为了不影响用户体验,可以把当前Activity设置为透明:
android:theme="@android:style/Theme.Translucent"
&!--注册微信回调 WXEntryActivity --&
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent" /&
具体可参考:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料 - 大有@ - 博客园
转载请注明出处:http://blog.csdn.net/yangyu/article/details/9057257
& & & & 由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字和图片等这样的效果,几经波折,查阅了一番资料,做了一个Demo。实现起来的效果还是不错的,不敢独享,决定写一个总结的教程,供大家互相交流、学习和参考,博主只求能和大家共同进步。希望能多多支持!
& & & & 这篇文章中,我们使用到了Share SDK,它是为iOS、Android、WP8的APP提供社会化功能的一个组件,目前支持如QQ、微信、新浪微博、腾讯微博、开心网、人人网、豆瓣、网易微博、搜狐微博、facebook、twitter、google+等国内外主流社交平台。
一、实现的效果图
&&&&&&&&&&&&&&&主界面效果图&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 授权登录页面效果图
&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&点击分享按钮弹出分享分享界面&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&有界面图文分享,分享成功后会发送消息提示
&&&&&&&&&&
二、项目结构目录
三、编码前的准备工作
1、获取Libs&&&&
&&&&& Libs包含ShareSDK的类库,具体包括三个文件夹,分别是ShareSDK的全局依赖库、ShareSDK当前支持的所有平台工具库和ShareSDK可视化UI的一些支持库。&全局依赖库&是集成ShareSDK的基础,ShareSDK的任何平台都依赖于这个库,而&ShareSDK-GUI&提供的是一个测栏控件和一个快捷分享工具,以方便读者更快速地集成ShareSDK。
2、导入Libs
& & & &&1& 将&Libs\Global-Dependences&下的jar包复制到您的libs目录下。
& & & &&2& 从&Libs\Platforms&中选择您感兴趣的平台,比方说&新浪微博&、&QQ空间&、&腾讯微博&等,复制相应的压缩包到你项目的libs目录下并解压
& & & &&3& 如果你决定使用shareSDK提供的快捷分享工具,还需要复制&Libs\ShareSDK-GUI&中复制&cn.sharesdk.onekeyshare.jar&到你的项目中。
& & & &&4& 一般来说,ADT会自动将你添加到libs目录下的jar包添加到&Android Dependencies&中。但是如果你的开发环境不能自动加载ShareSDK的jar包到你的项目中,那么只能手动添加,如下图所示:
四、详细的编码实现
1、ShareSdK使用统一的格式管理你在不同平台上注册的开发者信息。这些信息都存放在项目的&assets/ShareSDKDevInfor.xml&中,ShareSDKDevInfor.xml:
&?xml version="1.0" encoding="utf-8"?&
&DevInfor&
&!--说明:
1、表格中的第一项
&ShareSDK AppKey="api20" /&
是必须的,其中的AppKey是你在Share SDK上注册的开发者帐号的AppKey
2、所有集成到你项目的平台都应该为其在表格中填写相对应的开发者信息,以新浪微博为例:
&SinaWeibo
SortId="此平台在分享列表中的位置,由开发者自行定义,可以是任何整型数字,数值越大越靠后"
AppKey="填写你在新浪微博上注册的AppKey"
AppSecret="填写你在新浪微博上注册到的AppKey"
Id="自定义字段,整形,用于你项目中对此平台的识别符"
RedirectUrl="填写你在新浪微博上注册的RedirectUrl" /&
各个平台注册应用信息的地址如下:
新浪微博:http://
腾讯微博:http://dev.
QQ空间:http:///intro/login/
网易微博:http://open.
搜狐微博:http://open.
豆瓣:http://
人人网:http://
开心网:http://
Instapaper:http:///main/request_oauth_consumer_token
有道云笔记:http:///open/developguide.html#app
facebook:https://
twitter:https://
搜狐随身看:https://
QQ好友分享:http:///api/
微信:http://open.--&
AppKey = "api20"/& &!-- AppKey="104972cdd48" "23a"--&
&SinaWeibo
SortId="1"
AppSecret="1e8f76badf"
RedirectUrl="" /&
&TencentWeibo
SortId="2"
AppSecret="ae36f4ee3946e1cbb98dff5c"
RedirectUri=""
SortId="3"
AppKey="aed9be27bae87cd"
RedirectUrl="" /&
SortId="4"
AppId="226427"
ApiKey="fc5b8aed373c4c27a05b712acba0f8c3"
SecretKey="f29df781abdd4f49beca5a" /&
&/DevInfor&
2、配置AndroidManifest.xml,不同的集成度需要在AndroidManifest.xml中添加的内容也不一样。但是首先你需要添加下面的权限列表:
&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_APN_SETTINGS" /&
&uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /&
&uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&
&uses-permission android:name="android.permission.READ_PHONE_STATE" /&
这些权限将允许你的项目和ShareSDK获取连接网络的权限、获取你的设备网络状态的权限、实现https安全连接的权限、读取手机设备状态的权限和保存必要配置的权限。一般来说,即便不集成ShareSDK,大部分的项目也都会注册申请这些权限。
&&&&&&&&注意:大家在加入这个"android.permission.WRITE_APN_SETTINGS"权限的时候,可能有些读者的编译器会报错,博主就遇到了这样的情况,这个是ADT Lint工具的问题。
&&&&&&&解决的办法是:依照下面的路径&Window &&&Preferences && android&&&lint error checking&打开lint的配置页面,然后去掉页面顶部的两个勾选,之后再clean项目就能处理。如下图所示:
3、其次,为了授权操作可以顺利完成,需要在application下注册下面的Activity:
android:name="cn.sharesdk.framework.AuthorizeActivity"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:windowSoftInputMode="stateHidden|adjustResize" &
&/activity&
AuthorizeActivity的路径是固定的,一定要在&cn.sharesdk.framework&下,因为他在Share-Core包中。4、添加布局页面,首先是主界面的布局页面,activity_main.xml:
&RelativeLayout xmlns:android="/apk/res/android"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" &
android:id="@+id/btnLogin"
android:layout_width="fill_parent"
android:layout_height="44dp"
android:layout_above="@+id/btnShareAllGui"
android:layout_centerHorizontal="true"
android:layout_margin="5dp"
android:background="@drawable/btn_back"
android:text="用户授权登录"
android:textSize="16dp"/&
android:id="@+id/btnShareAllGui"
android:layout_width="fill_parent"
android:layout_height="44dp"
android:layout_above="@+id/btnShareAll"
android:layout_margin="5dp"
android:background="@drawable/btn_back"
android:text="分享全部(有分享界面)"
android:textSize="16dp" /&
android:id="@+id/btnShareAll"
android:layout_width="fill_parent"
android:layout_height="44dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_margin="5dp"
android:background="@drawable/btn_back"
android:text="分享全部(无界面,直接分享)"
android:textSize="16dp" /&
android:id="@+id/btnUserInfo"
android:layout_width="fill_parent"
android:layout_height="44dp"
android:layout_below="@+id/btnShareAll"
android:layout_margin="5dp"
android:layout_marginTop="41dp"
android:background="@drawable/btn_back"
android:text="获取授权用户资料"
android:textSize="16dp" /&
&/RelativeLayout&
5、用户授权登录的布局页面,activity_auth.xml:
&?xml version="1.0" encoding="utf-8"?&
&RelativeLayout xmlns:android="/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff5f5f5"
android:orientation="vertical" &
&!--ShareSDK-Core包下封装的一个标题栏--&
&cn.sharesdk.framework.TitleLayout
android:id="@+id/llTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/title_back" /&
&LinearLayout
android:id="@+id/llBody"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="58dp"
android:orientation="vertical"
android:padding="10dp" &
&LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@drawable/list_item_first_normal"
android:paddingLeft="10dp"
android:paddingRight="10dp" &
&ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:scaleType="centerInside"
android:src="@drawable/sina_weibo" /&
&CheckedTextView
android:id="@+id/ctvSw"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:drawablePadding="10dp"
android:drawableRight="@drawable/cb_drw"
android:gravity="center_vertical"
android:singleLine="true"
android:text="@string/not_yet_authorized"
android:textColor="#ff000000"
android:textSize="20dp" /&
&/LinearLayout&
&LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@drawable/list_item_middle_normal"
android:paddingLeft="10dp"
android:paddingRight="10dp" &
&ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:scaleType="centerInside"
android:src="@drawable/tencent_weibo" /&
&CheckedTextView
android:id="@+id/ctvTc"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:drawablePadding="10dp"
android:drawableRight="@drawable/cb_drw"
android:gravity="center_vertical"
android:singleLine="true"
android:text="@string/not_yet_authorized"
android:textColor="#ff000000"
android:textSize="20dp" /&
&/LinearLayout&
&LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@drawable/list_item_middle_normal"
android:paddingLeft="10dp"
android:paddingRight="10dp" &
&ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:scaleType="centerInside"
android:src="@drawable/renren" /&
&CheckedTextView
android:id="@+id/ctvRr"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:drawablePadding="10dp"
android:drawableRight="@drawable/cb_drw"
android:gravity="center_vertical"
android:singleLine="true"
android:text="@string/not_yet_authorized"
android:textColor="#ff000000"
android:textSize="20dp" /&
&/LinearLayout&
&LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@drawable/list_item_last_normal"
android:paddingLeft="10dp"
android:paddingRight="10dp" &
&ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:scaleType="centerInside"
android:src="@drawable/qzone" /&
&CheckedTextView
android:id="@+id/ctvQz"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:drawablePadding="10dp"
android:drawableRight="@drawable/cb_drw"
android:gravity="center_vertical"
android:singleLine="true"
android:text="@string/not_yet_authorized"
android:textColor="#ff000000"
android:textSize="20dp" /&
&/LinearLayout&
&/LinearLayout&
&/RelativeLayout&
6、获得用户信息布局界面,activity_userinfo.xml:
&?xml version="1.0" encoding="utf-8"?&
&RelativeLayout xmlns:android="/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff5f5f5"
android:orientation="vertical" &
&!--ShareSDK-Core包下封装的一个标题栏--&
&cn.sharesdk.framework.TitleLayout
android:id="@+id/llTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/title_back" /&
android:id="@+id/btnQz"
android:layout_width="fill_parent"
android:layout_height="44dp"
android:layout_centerVertical="true"
android:layout_margin="5dp"
android:background="@drawable/btn_back"
android:text="@string/get_user_info_qz"
android:textSize="16dp" /&
android:id="@+id/btnRr"
android:layout_width="fill_parent"
android:layout_height="44dp"
android:layout_above="@+id/btnQz"
android:layout_margin="5dp"
android:background="@drawable/btn_back"
android:text="@string/get_user_info_rr"
android:textSize="16dp" /&
android:id="@+id/btnSw"
android:layout_width="fill_parent"
android:layout_height="44dp"
android:layout_above="@+id/btnRr"
android:layout_margin="5dp"
android:background="@drawable/btn_back"
android:text="@string/get_user_info_sw"
android:textSize="16dp" /&
android:id="@+id/btnTc"
android:layout_width="fill_parent"
android:layout_height="44dp"
android:layout_below="@+id/btnQz"
android:layout_centerHorizontal="true"
android:layout_margin="5dp"
android:background="@drawable/btn_back"
android:text="@string/get_user_info_tc"
android:textSize="16dp" /&
&/RelativeLayout&
7、显示用户获得的信息布局界面,activity_userinfo.xml:
&?xml version="1.0" encoding="utf-8"?&
&RelativeLayout xmlns:android="/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff5f5f5"
android:orientation="vertical" &
&!--ShareSDK-Core包下封装的一个标题栏--&
&cn.sharesdk.framework.TitleLayout
android:id="@+id/llTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/title_back" /&
&ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="@id/llTitle"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingTop="10dp" &
android:id="@+id/tvJson"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:autoLink="all"
android:background="@drawable/list_item_single_normal"
android:textColor="#ff000000" /&
&/ScrollView&
&/RelativeLayout&
8、主界面入口Activity类,MainActivity.java:
package com.yangyu.
import java.io.F
import java.io.FileOutputS
import android.app.A
import android.content.I
import android.graphics.B
import android.pressF
import android.graphics.BitmapF
import android.os.B
import android.os.E
import android.view.V
import android.view.View.OnClickL
import android.widget.B
import cn.sharesdk.framework.AbstractW
import cn.sharesdk.onekeyshare.ShareAllG
import com.yangyu.mysharethings.R;
* @author yangyu
功能描述:主Activity类,程序的入口类
public class MainActivity extends Activity implements OnClickListener {
//定义图片存放的地址
public static String TEST_IMAGE;
//定义"账号登陆"按钮,"有分享界面按钮","无分享界面"按钮,"得到用户资料"按钮
private Button authLoginBtn,shareGuiBtn,shareBtn,getInfoB
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化ShareSDK
AbstractWeibo.initSDK(this);
initImagePath();
initView();
initData();
* 初始化组件
private void initView(){
authLoginBtn = (Button)findViewById(R.id.btnLogin);
shareGuiBtn = (Button)findViewById(R.id.btnShareAllGui);
shareBtn = (Button)findViewById(R.id.btnShareAll);
getInfoBtn = (Button)findViewById(R.id.btnUserInfo);
* 初始化数据
private void initData(){
//设置按钮监听事件
authLoginBtn.setOnClickListener(this);
shareGuiBtn.setOnClickListener(this);
shareBtn.setOnClickListener(this);
getInfoBtn.setOnClickListener(this);
* 初始化分享的图片
private void initImagePath() {
try {//判断SD卡中是否存在此文件夹
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
&& Environment.getExternalStorageDirectory().exists()) {
TEST_IMAGE = Environment.getExternalStorageDirectory().getAbsolutePath() + "/pic.png";
TEST_IMAGE = getApplication().getFilesDir().getAbsolutePath() + "/pic.png";
File file = new File(TEST_IMAGE);
//判断图片是否存此文件夹中
if (!file.exists()) {
file.createNewFile();
Bitmap pic = BitmapFactory.decodeResource(getResources(), R.drawable.pic);
FileOutputStream fos = new FileOutputStream(file);
press(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch(Throwable t) {
t.printStackTrace();
TEST_IMAGE = null;
* 按钮监听事件
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnLogin:
startActivity(new Intent(MainActivity.this,AuthActivity.class));
case R.id.btnShareAllGui:
showGrid(false);
case R.id.btnShareAll:
showGrid(true);
case R.id.btnUserInfo:
// 获取自己的资料
Intent i = new Intent(this, GetInforActivity.class);
startActivity(i);
* 使用快捷分享完成图文分享
private void showGrid(boolean silent) {
Intent i = new Intent(this, ShareAllGird.class);
// 分享时Notification的图标
i.putExtra("notif_icon", R.drawable.ic_launcher);
// 分享时Notification的标题
i.putExtra("notif_title", this.getString(R.string.app_name));
// title标题,在印象笔记、邮箱、信息、微信(包括好友和朋友圈)、人人网和QQ空间使用,否则可以不提供
i.putExtra("title", this.getString(R.string.share));
// titleUrl是标题的网络链接,仅在人人网和QQ空间使用,否则可以不提供
i.putExtra("titleUrl", "");
// text是分享文本,所有平台都需要这个字段
i.putExtra("text", this.getString(R.string.share_content));
// imagePath是本地的图片路径,所有平台都支持这个字段,不提供,则表示不分享图片
i.putExtra("imagePath", MainActivity.TEST_IMAGE);
// url仅在微信(包括好友和朋友圈)中使用,否则可以不提供
i.putExtra("url", "");
// thumbPath是缩略图的本地路径,仅在微信(包括好友和朋友圈)中使用,否则可以不提供
i.putExtra("thumbPath", MainActivity.TEST_IMAGE);
// appPath是待分享应用程序的本地路劲,仅在微信(包括好友和朋友圈)中使用,否则可以不提供
i.putExtra("appPath", MainActivity.TEST_IMAGE);
// comment是我对这条分享的评论,仅在人人网和QQ空间使用,否则可以不提供
i.putExtra("comment", this.getString(R.string.share));
// site是分享此内容的网站名称,仅在QQ空间使用,否则可以不提供
i.putExtra("site", this.getString(R.string.app_name));
// siteUrl是分享此内容的网站地址,仅在QQ空间使用,否则可以不提供
i.putExtra("siteUrl", "");
// 是否直接分享
i.putExtra("silent", silent);
this.startActivity(i);
* 将action转换为String
public static String actionToString(int action) {
switch (action) {
case AbstractWeibo.ACTION_AUTHORIZING: return "ACTION_AUTHORIZING";
case AbstractWeibo.ACTION_GETTING_FRIEND_LIST: return "ACTION_GETTING_FRIEND_LIST";
case AbstractWeibo.ACTION_FOLLOWING_USER: return "ACTION_FOLLOWING_USER";
case AbstractWeibo.ACTION_SENDING_DIRECT_MESSAGE: return "ACTION_SENDING_DIRECT_MESSAGE";
case AbstractWeibo.ACTION_TIMELINE: return "ACTION_TIMELINE";
case AbstractWeibo.ACTION_USER_INFOR: return "ACTION_USER_INFOR";
case AbstractWeibo.ACTION_SHARE: return "ACTION_SHARE";
default: {
return "UNKNOWN";
protected void onDestroy() {
//结束ShareSDK的统计功能并释放资源
AbstractWeibo.stopSDK(this);
super.onDestroy();
集成ShareSDK需要至少在两个地方添加代码,包括:
&1&&&在onCreate中插入下面的代码:
//初始化ShareSDK
AbstractWeibo.initSDK(this);
&这行代码会初始化ShareSDK,此后对ShareSDK的操作都依次为基础。如果不在所有ShareSDK的操作之前调用这行代码,会抛出空指针异常。
&2& 在项目的出口Activity的onDestroy方法的第一行插入下面的代码:
protected void onDestroy() {
//结束ShareSDK的统计功能并释放资源
AbstractWeibo.stopSDK(this);
super.onDestroy();
这行代码会结束ShareSDK的统计功能并释放资源。如果这行代码没有被调用,那么
&应用启动次数&的统计将不会准确,因为应用可能从来没有被关闭。
&&&&&&&&&&InitSDK是可以重复调用的,其实ShareSDK建议在你不确定的时候调用这个方法,
来保证ShareSDK被正确初始化。而stopSDK一旦调用了,就必须重新调用InitSDK才能使
用ShareSDK的功能,否则会出现空指针异常。
&在这段代码中,还使用到了快捷分享,如下图所示,点击按钮弹出快捷分享界面:
&&&&&&&&&&&&&
&&&&& 什么是快捷分享呢?快捷分享是ShareSDK提供的一套基于其接口的GUI。通过简单的配置,可以在不考虑平台的情况下,调用很少的代码,就完成分享的操作。快捷分享的jar包放在SDK解压目录的"Libs\ShareSDK-GUI"中,叫做"cn.sharesdk.oneshare.jar"。快捷分享使用了两个Activity,需要在AndroidManifest.xml中注册这两个Activity:
android:name="cn.sharesdk.onekeyshare.ShareAllGird"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:windowSoftInputMode="adjustPan|stateHidden" /&
android:name="cn.sharesdk.onekeyshare.SharePage"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize" /&
9、帐号授权登录界面,AuthActivity.java:
package com.yangyu.
import java.util.HashM
import android.app.A
import android.os.B
import android.os.H
import android.os.Handler.C
import android.os.M
import android.view.V
import android.view.View.OnClickL
import android.widget.CheckedTextV
import android.widget.T
import cn.sharesdk.framework.AbstractW
import cn.sharesdk.framework.TitleL
import cn.sharesdk.framework.WeiboActionL
import cn.sharesdk.renren.R
import cn.sharesdk.sina.weibo.SinaW
import cn.sharesdk.tencent.qzone.QZ
import cn.sharesdk.tencent.weibo.TencentW
import com.yangyu.mysharethings.R;
* @author yangyu
功能描述:授权和取消授权Activity,由于UI显示需要授权过的平台显示账户的名称,
因此此页面事实上展示的是&获取用户资料&和&取消授权&两个功能。
public class AuthActivity extends Activity implements Callback, OnClickListener, WeiboActionListener {
//定义CheckedTextView对象
private CheckedTextView
sinaCt,qzoneCt,tengxunCt,renrenCt;
//定义Handler对象
//定义标题栏对象
private TitleLayout llT
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auth);
initView();
initData();
* 初始化组件
private void initView(){
//实例化Handler对象并设置信息回调监听接口
handler = new Handler(this);
//得到标题栏对象
llTitle = (TitleLayout) findViewById(R.id.llTitle);
//得到组件对象
= (CheckedTextView)findViewById(R.id.ctvSw);
= (CheckedTextView)findViewById(R.id.ctvQz);
tengxunCt = (CheckedTextView)findViewById(R.id.ctvTc);
= (CheckedTextView)findViewById(R.id.ctvRr);
* 初始化数据
private void initData(){
llTitle.getBtnBack().setOnClickListener(new OnClickListener() {
public void onClick(View v) {
llTitle.getTvTitle().setText("用户授权登录");
//设置监听
sinaCt.setOnClickListener(this);
qzoneCt.setOnClickListener(this);
tengxunCt.setOnClickListener(this);
renrenCt.setOnClickListener(this);
//获取平台列表
AbstractWeibo[] weibos = AbstractWeibo.getWeiboList(this);
for(int i = 0;i & weibos.i++){
if (!weibos[i].isValid()) {
CheckedTextView ctv = getView(weibos[i]);
if (ctv != null) {
ctv.setChecked(true);
// 得到授权用户的用户名称
String userName = weibos[i].getDb().get("nickname");
if (userName == null || userName.length() &= 0 || "null".equals(userName)) {
// 如果平台已经授权却没有拿到帐号名称,则自动获取用户资料,以获取名称
userName = getWeiboName(weibos[i]);
//添加平台事件监听
weibos[i].setWeiboActionListener(this);
//显示用户资料,null表示显示自己的资料
weibos[i].showUser(null);
ctv.setText(userName);
* 在CheckedTextView组件中显示授权用户的名称
private CheckedTextView getView(AbstractWeibo weibo) {
if (weibo == null) {
return null;
String name = weibo.getName();
if (name == null) {
return null;
View v = null;
if (SinaWeibo.NAME.equals(name)) {
v = findViewById(R.id.ctvSw);
else if (TencentWeibo.NAME.equals(name)) {
v = findViewById(R.id.ctvTc);
else if (Renren.NAME.equals(name)) {
v = findViewById(R.id.ctvRr);
else if (QZone.NAME.equals(name)) {
v = findViewById(R.id.ctvQz);
if (v == null) {
return null;
if (! (v instanceof CheckedTextView)) {
return null;
return (CheckedTextView)
* 得到授权用户的用户名称
private String getWeiboName(AbstractWeibo weibo) {
if (weibo == null) {
return null;
String name = weibo.getName();
if (name == null) {
return null;
int res = 0;
if (SinaWeibo.NAME.equals(name)) {
res = R.string.
else if (TencentWeibo.NAME.equals(name)) {
res = R.string.
else if (Renren.NAME.equals(name)) {
res = R.string.
else if (QZone.NAME.equals(name)) {
res = R.string.
if (res == 0) {
return this.getResources().getString(res);
* 授权和取消授权的按钮点击监听事件
public void onClick(View v) {
AbstractWeibo weibo = getWeibo(v.getId());
CheckedTextView ctv = (CheckedTextView)
if (weibo == null) {
ctv.setChecked(false);
ctv.setText(R.string.not_yet_authorized);
if (weibo.isValid()) {
weibo.removeAccount();
ctv.setChecked(false);
ctv.setText(R.string.not_yet_authorized);
weibo.setWeiboActionListener(this);
weibo.showUser(null);
* 获得授权
private AbstractWeibo getWeibo(int vid) {
String name = null;
switch (vid) {
// 进入新浪微博的授权页面
case R.id.ctvSw:
name = SinaWeibo.NAME;
// 进入腾讯微博的授权页面
case R.id.ctvTc:
name = TencentWeibo.NAME;
// 进入人人网的授权页面
case R.id.ctvRr:
name = Renren.NAME;
// 进入QQ空间的授权页面
case R.id.ctvQz:
name = QZone.NAME;
if (name != null) {
return AbstractWeibo.getWeibo(this, name);
return null;
* 授权成功的回调
weibo - 回调的平台
action - 操作的类型
res - 请求的数据通过res返回
public void onComplete(AbstractWeibo weibo, int action,HashMap&String, Object& res) {
Message msg = new Message();
msg.arg1 = 1;
msg.arg2 =
handler.sendMessage(msg);
* 授权失败的回调
public void onError(AbstractWeibo weibo, int action, Throwable t) {
t.printStackTrace();
Message msg = new Message();
msg.arg1 = 2;
msg.arg2 =
handler.sendMessage(msg);
* 取消授权的回调
public void onCancel(AbstractWeibo weibo, int action) {
Message msg = new Message();
msg.arg1 = 3;
msg.arg2 =
handler.sendMessage(msg);
* 处理从授权页面返回的结果
* 如果获取到用户的名称,则显示名称;否则如果已经授权,则显示平台名称
public boolean handleMessage(Message msg) {
AbstractWeibo weibo = (AbstractWeibo) msg.
String text = MainActivity.actionToString(msg.arg2);
switch (msg.arg1) {
case 1: { // 成功
text = weibo.getName() + " completed at " +
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
case 2: { // 失败
text = weibo.getName() + " caught error at " +
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
return false;
case 3: { // 取消
text = weibo.getName() + " canceled at " +
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
return false;
CheckedTextView ctv = getView(weibo);
if (ctv != null) {
ctv.setChecked(true);
String userName = weibo.getDb().get("nickname"); // getAuthedUserName();
if (userName == null || userName.length() &= 0
|| "null".equals(userName)) {
userName = getWeiboName(weibo);
ctv.setText(userName);
return false;
10、获取用户信息界面,GetInfoActivity.java:
package com.yangyu.
import java.util.HashM
import android.app.A
import android.content.I
import android.os.B
import android.os.H
import android.os.Handler.C
import android.os.M
import android.view.V
import android.view.View.OnClickL
import android.widget.B
import android.widget.T
import cn.sharesdk.framework.AbstractW
import cn.sharesdk.framework.TitleL
import cn.sharesdk.framework.WeiboActionL
import cn.sharesdk.renren.R
import cn.sharesdk.sina.weibo.SinaW
import cn.sharesdk.tencent.qzone.QZ
import cn.sharesdk.tencent.weibo.TencentW
import com.yangyu.mysharethings.R;
* @author yangyu
功能描述:获取用户资料
* 启动页面时传递一个int类型的字段type,用于标记获取自己的资料(type = 0)还是别人的资料(type = 1)。
* 如果尝试获取别人的资料,示例代码会获取不同平台Share SDK的官方帐号的资料。
* 如果资料获取成功,会通过{@link ShowInforPage}展示
public class GetInforActivity
extends Activity implements Callback, OnClickListener, WeiboActionListener {
//定义标题栏布局对象
private TitleLayout llT
private Button sinaBt,renrenBt,qzoneBt,tengxunBt;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler(this);
setContentView(R.layout.activity_userinfo);
initView();
initData();
* 初始化组件
private void initView(){
//得到标题栏对象
llTitle = (TitleLayout) findViewById(R.id.llTitle);
//得到按钮对象
= (Button) findViewById(R.id.btnSw);
= (Button) findViewById(R.id.btnRr);
= (Button) findViewById(R.id.btnQz);
tengxunBt = (Button) findViewById(R.id.btnTc);
* 初始化数据
private void initData(){
//标题栏设置返回按钮监听
llTitle.getBtnBack().setOnClickListener(this);
//设置标题栏的标题文本
llTitle.getTvTitle().setText(R.string.get_my_info);
//设置监听
sinaBt.setOnClickListener(this);
renrenBt.setOnClickListener(this);
qzoneBt.setOnClickListener(this);
tengxunBt.setOnClickListener(this);
* 点击按钮获取授权用户的资料
public void onClick(View v) {
if (v.equals(llTitle.getBtnBack())) {
String name = null;
switch (v.getId()) {
case R.id.btnSw:
name = SinaWeibo.NAME;
case R.id.btnTc:
name = TencentWeibo.NAME;
case R.id.btnRr:
name = Renren.NAME;
case R.id.btnQz:
name = QZone.NAME;
if (name != null) {
AbstractWeibo weibo = AbstractWeibo.getWeibo(this, name);
weibo.setWeiboActionListener(this);
String account = null;
weibo.showUser(account);
public void onComplete(AbstractWeibo weibo, int action,HashMap&String, Object& res) {
Message msg = new Message();
msg.arg1 = 1;
msg.arg2 =
handler.sendMessage(msg);
Message msg2 = new Message();
msg2.what = 1;
JsonUtils ju = new JsonUtils();
String json = ju.fromHashMap(res);
msg2.obj = ju.format(json);
handler.sendMessage(msg2);
public void onError(AbstractWeibo weibo, int action, Throwable t) {
t.printStackTrace();
Message msg = new Message();
msg.arg1 = 2;
msg.arg2 =
handler.sendMessage(msg);
public void onCancel(AbstractWeibo weibo, int action) {
Message msg = new Message();
msg.arg1 = 3;
msg.arg2 =
handler.sendMessage(msg);
/** 处理操作结果 */
public boolean handleMessage(Message msg) {
switch(msg.what) {
Intent i = new Intent(this, ShowInforActivity.class);
i.putExtra("data", String.valueOf(msg.obj));
startActivity(i);
default: {
AbstractWeibo weibo = (AbstractWeibo) msg.
String text = MainActivity.actionToString(msg.arg2);
switch (msg.arg1) {
case 1: { // 成功
text = weibo.getName() + " completed at " +
case 2: { // 失败
text = weibo.getName() + " caught error at " +
case 3: { // 取消
text = weibo.getName() + " canceled at " +
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
return false;
11、显示用户信息界面,ShowInfoActivity.java:
package com.yangyu.
import android.app.A
import android.os.B
import android.view.V
import android.view.View.OnClickL
import android.widget.TextV
import cn.sharesdk.framework.TitleL
import com.yangyu.mysharethings.R;
* @author yangyu
功能描述:显示用户信息资料
public class ShowInforActivity
extends Activity implements OnClickListener {
private TitleLayout llT
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_userinfo);
llTitle = (TitleLayout) findViewById(R.id.llTitle);
llTitle.getBtnBack().setOnClickListener(this);
llTitle.getTvTitle().setText("用户资料");
TextView tvJson = (TextView) findViewById(R.id.tvJson);
tvJson.setText(getIntent().getStringExtra("data"));
public void onClick(View v) {
if (v.equals(llTitle.getBtnBack())) {
12、这里还定义了一个Json解析类去读取授权用户的信息,JsonUtils.java:
package com.yangyu.
import java.util.ArrayL
import java.util.HashM
import java.util.I
import java.util.Map.E
import org.json.JSONA
import org.json.JSONE
import org.json.JSONO
* @author yangyu
功能描述:这是一个简易的Json-HashMap转换工具,可以将普通的json数据(字符串)
转换为一个HashMap&Srting, Object&表格,也可以反过来操作。此外还支
持将json数据格式化。
public class JsonUtils {
* 将指定的json数据转成 HashMap&String, Object&对象
public HashMap&String, Object& fromJson(String jsonStr) {
if (jsonStr.startsWith("[")
&& jsonStr.endsWith("]")) {
jsonStr = "{\"fakelist\":" + jsonStr + "}";
JSONObject json = new JSONObject(jsonStr);
return fromJson(json);
} catch (Throwable t) {
t.printStackTrace();
return new HashMap&String, Object&();
private HashMap&String, Object& fromJson(JSONObject json) throws JSONException {
HashMap&String, Object& map = new HashMap&String, Object&();
@SuppressWarnings("unchecked")
Iterator&String& iKey = json.keys();
while(iKey.hasNext()) {
String key = iKey.next();
Object value = json.opt(key);
if (JSONObject.NULL.equals(value)) {
value = null;
if (value != null) {
if (value instanceof JSONObject) {
value = fromJson((JSONObject)value);
else if (value instanceof JSONArray) {
value = fromJson((JSONArray)value);
map.put(key, value);
private ArrayList&Object& fromJson(JSONArray array)
throws JSONException {
ArrayList&Object& list = new ArrayList&Object&();
for (int i = 0, size = array.length(); i & i++) {
Object value = array.opt(i);
if (value instanceof JSONObject) {
value = fromJson((JSONObject)value);
else if (value instanceof JSONArray) {
value = fromJson((JSONArray)value);
list.add(value);
* 将指定的HashMap&String, Object&对象转成json数据
public String fromHashMap(HashMap&String, Object& map) {
return getJSONObject(map).toString();
} catch (Throwable t) {
t.printStackTrace();
return "";
@SuppressWarnings("unchecked")
private JSONObject getJSONObject(HashMap&String, Object& map)
throws JSONException {
JSONObject json = new JSONObject();
for (Entry&String, Object& entry : map.entrySet()) {
Object value = entry.getValue();
if (value instanceof HashMap&?, ?&) {
value = getJSONObject((HashMap&String, Object&)value);
else if (value instanceof ArrayList&?&) {
value = getJSONArray((ArrayList&Object&)value);
json.put(entry.getKey(), value);
@SuppressWarnings("unchecked")
private JSONArray getJSONArray(ArrayList&Object& list)
throws JSONException {
JSONArray array = new JSONArray();
for (Object value : list) {
if (value instanceof HashMap&?, ?&) {
value = getJSONObject((HashMap&String, Object&)value);
else if (value instanceof ArrayList&?&) {
value = getJSONArray((ArrayList&Object&)value);
array.put(value);
* 格式化一个json串
public String format(String jsonStr) {
return format("", fromJson(jsonStr));
} catch (Throwable t) {
t.printStackTrace();
return "";
@SuppressWarnings("unchecked")
private String format(String sepStr, HashMap&String, Object& map) {
StringBuffer sb = new StringBuffer();
sb.append("{\n");
String mySepStr = sepStr + "\t";
int i = 0;
for (Entry&String, Object& entry : map.entrySet()) {
if (i & 0) {
sb.append(",\n");
sb.append(mySepStr).append('\"').append(entry.getKey()).append("\":");
Object value = entry.getValue();
if (value instanceof HashMap&?, ?&) {
sb.append(format(mySepStr, (HashMap&String, Object&)value));
else if (value instanceof ArrayList&?&) {
sb.append(format(mySepStr, (ArrayList&Object&)value));
else if (value instanceof String) {
sb.append('\"').append(value).append('\"');
sb.append(value);
sb.append('\n').append(sepStr).append('}');
return sb.toString();
@SuppressWarnings("unchecked")
private String format(String sepStr, ArrayList&Object& list) {
StringBuffer sb = new StringBuffer();
sb.append("[\n");
String mySepStr = sepStr + "\t";
int i = 0;
for (Object value : list) {
if (i & 0) {
sb.append(",\n");
sb.append(mySepStr);
if (value instanceof HashMap&?, ?&) {
sb.append(format(mySepStr, (HashMap&String, Object&)value));
else if (value instanceof ArrayList&?&) {
sb.append(format(mySepStr, (ArrayList&Object&)value));
else if (value instanceof String) {
sb.append('\"').append(value).append('\"');
sb.append(value);
sb.append('\n').append(sepStr).append(']');
return sb.toString();
讲到这里关于这一篇的内容就差不多已经讲完了,下一篇是关于微信开放平台的授权以及分享,因为微信平台不同于其它第三方平台,实现起来稍微复杂一点,所以博主打算在下一篇的文章中详细讲解。这个下一篇文章估计要等到三天后了吧,博主和女友早就商量好趁着三天小长假出去散散心了,在这里祝大家端午节快乐!博主将会长期坚持更新关于Android、Java、Cocos2d-x、Unity3d等各个不同知识领域的实例讲解和开发!希望大家继续支持!
随笔 - 121

我要回帖

更多关于 第三方微博客户端 的文章

 

随机推荐