转载请注明出处:http://blog.csdn.net/yangyu20121224/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。Libs下载地址

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上注册的开发者帐号的AppKey2、所有集成到你项目的平台都应该为其在表格中填写相对应的开发者信息,以新浪微博为例:<SinaWeiboSortId="此平台在分享列表中的位置,由开发者自行定义,可以是任何整型数字,数值越大越靠后"AppKey="填写你在新浪微博上注册的AppKey"AppSecret="填写你在新浪微博上注册到的AppKey"Id="自定义字段,整形,用于你项目中对此平台的识别符"RedirectUrl="填写你在新浪微博上注册的RedirectUrl" />        各个平台注册应用信息的地址如下:新浪微博:http://open.weibo.com腾讯微博:http://dev.t.qq.comQQ空间:http://connect.qq.com/intro/login/网易微博:http://open.t.163.com搜狐微博:http://open.t.sohu.com豆瓣:http://developers.douban.com人人网:http://dev.renren.com开心网:http://open.kaixin001.comInstapaper:http://www.instapaper.com/main/request_oauth_consumer_token有道云笔记:http://note.youdao.com/open/developguide.html#appfacebook:https://developers.facebook.comtwitter:https://dev.twitter.com搜狐随身看:https://open.sohu.comQQ好友分享:http://mobile.qq.com/api/微信:http://open.weixin.qq.com--><ShareSDK AppKey = "api20"/> <!-- AppKey="104972cdd48" "23a9371d3a8"--><SinaWeiboSortId="1"AppKey="3201194191"AppSecret="0334252914651e8f76bad63337b3b78f"Id="1"RedirectUrl="http://appgo.cn" /><TencentWeiboSortId="2"AppKey="801307650"AppSecret="ae36f4ee3946e1cbb98d6965b0b2ff5c"RedirectUri="http://sharesdk.cn"Id="2" /><QZoneSortId="3"AppId="100371282"AppKey="aed9b0303e3ed1e27bae87c33761161d"Id="3"RedirectUrl="http://www.shareSDK.cn" /><RenrenSortId="4"AppId="226427"ApiKey="fc5b8aed373c4c27a05b712acba0f8c3"Id="4"SecretKey="f29df781abdd4f49beca5a2194676ca4" />  </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:

<activityandroid: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="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><Buttonandroid: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"/><Buttonandroid: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" /><Buttonandroid: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" /><Buttonandroid: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="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:background="#fff5f5f5"android:orientation="vertical" ><!--ShareSDK-Core包下封装的一个标题栏--><cn.sharesdk.framework.TitleLayoutandroid:id="@+id/llTitle"android:layout_width="fill_parent"android:layout_height="wrap_content"android:background="@drawable/title_back" /><LinearLayoutandroid: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" ><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="50dp"android:background="@drawable/list_item_first_normal"android:paddingLeft="10dp"android:paddingRight="10dp" ><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:layout_gravity="center_vertical"android:layout_marginRight="10dp"android:scaleType="centerInside"android:src="@drawable/sina_weibo" /><CheckedTextViewandroid: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><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="50dp"android:background="@drawable/list_item_middle_normal"android:paddingLeft="10dp"android:paddingRight="10dp" ><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:layout_gravity="center_vertical"android:layout_marginRight="10dp"android:scaleType="centerInside"android:src="@drawable/tencent_weibo" /><CheckedTextViewandroid: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><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="50dp"android:background="@drawable/list_item_middle_normal"android:paddingLeft="10dp"android:paddingRight="10dp" ><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:layout_gravity="center_vertical"android:layout_marginRight="10dp"android:scaleType="centerInside"android:src="@drawable/renren" /><CheckedTextViewandroid: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><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="50dp"android:background="@drawable/list_item_last_normal"android:paddingLeft="10dp"android:paddingRight="10dp" ><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:layout_gravity="center_vertical"android:layout_marginRight="10dp"android:scaleType="centerInside"android:src="@drawable/qzone" /><CheckedTextViewandroid: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="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:background="#fff5f5f5"android:orientation="vertical" ><!--ShareSDK-Core包下封装的一个标题栏--><cn.sharesdk.framework.TitleLayoutandroid:id="@+id/llTitle"android:layout_width="fill_parent"android:layout_height="wrap_content"android:background="@drawable/title_back" /><Buttonandroid: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" /><Buttonandroid: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" /><Buttonandroid: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" /><Buttonandroid: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="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:background="#fff5f5f5"android:orientation="vertical" ><!--ShareSDK-Core包下封装的一个标题栏--><cn.sharesdk.framework.TitleLayoutandroid:id="@+id/llTitle"android:layout_width="fill_parent"android:layout_height="wrap_content"android:background="@drawable/title_back" /><ScrollViewandroid: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" ><TextViewandroid: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.activity;import java.io.File;
import java.io.FileOutputStream;import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import cn.sharesdk.framework.AbstractWeibo;
import cn.sharesdk.onekeyshare.ShareAllGird;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,getInfoBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化ShareSDKAbstractWeibo.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";}else {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);pic.compress(CompressFormat.JPEG, 100, fos);fos.flush();fos.close();}} catch(Throwable t) {t.printStackTrace();TEST_IMAGE = null;}}/*** 按钮监听事件*/@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btnLogin:startActivity(new Intent(MainActivity.this,AuthActivity.class));break;case R.id.btnShareAllGui:showGrid(false);break;case R.id.btnShareAll:showGrid(true);break;case R.id.btnUserInfo:// 获取自己的资料Intent i = new Intent(this, GetInforActivity.class);startActivity(i);break;default:break;}}/*** 使用快捷分享完成图文分享*/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", "http://sharesdk.cn");// text是分享文本,所有平台都需要这个字段i.putExtra("text", this.getString(R.string.share_content));// imagePath是本地的图片路径,所有平台都支持这个字段,不提供,则表示不分享图片i.putExtra("imagePath", MainActivity.TEST_IMAGE);// url仅在微信(包括好友和朋友圈)中使用,否则可以不提供i.putExtra("url", "http://sharesdk.cn");// 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", "http://sharesdk.cn");// 是否直接分享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中插入下面的代码:

//初始化ShareSDKAbstractWeibo.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:

<activityandroid:name="cn.sharesdk.onekeyshare.ShareAllGird"android:configChanges="keyboardHidden|orientation"android:screenOrientation="portrait"android:theme="@android:style/Theme.Translucent.NoTitleBar"android:windowSoftInputMode="adjustPan|stateHidden" /><activityandroid:name="cn.sharesdk.onekeyshare.SharePage"android:configChanges="keyboardHidden|orientation"android:screenOrientation="portrait"android:windowSoftInputMode="stateHidden|adjustResize" />

9、帐号授权登录界面,AuthActivity.java:

package com.yangyu.activity;import java.util.HashMap;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckedTextView;
import android.widget.Toast;
import cn.sharesdk.framework.AbstractWeibo;
import cn.sharesdk.framework.TitleLayout;
import cn.sharesdk.framework.WeiboActionListener;
import cn.sharesdk.renren.Renren;
import cn.sharesdk.sina.weibo.SinaWeibo;
import cn.sharesdk.tencent.qzone.QZone;
import cn.sharesdk.tencent.weibo.TencentWeibo;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 Handler handler;//定义标题栏对象private TitleLayout llTitle;@Overrideprotected 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);     //得到组件对象sinaCt    = (CheckedTextView)findViewById(R.id.ctvSw);qzoneCt   = (CheckedTextView)findViewById(R.id.ctvQz);tengxunCt = (CheckedTextView)findViewById(R.id.ctvTc);renrenCt  = (CheckedTextView)findViewById(R.id.ctvRr);        }/*** 初始化数据*/private void initData(){llTitle.getBtnBack().setOnClickListener(new OnClickListener() {            @Overridepublic void onClick(View v) {finish();                }});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.length;i++){if (!weibos[i].isValid()) {continue;}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) v;}/*** 得到授权用户的用户名称*/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.sinaweibo;}else if (TencentWeibo.NAME.equals(name)) {res = R.string.tencentweibo;}       else if (Renren.NAME.equals(name)) {res = R.string.renren;}else if (QZone.NAME.equals(name)) {res = R.string.qzone;}      if (res == 0) {return name;}      return this.getResources().getString(res);}/*** 授权和取消授权的按钮点击监听事件*/@Overridepublic void onClick(View v) {               AbstractWeibo weibo = getWeibo(v.getId());CheckedTextView ctv = (CheckedTextView) v;if (weibo == null) {ctv.setChecked(false);ctv.setText(R.string.not_yet_authorized);return;}if (weibo.isValid()) {weibo.removeAccount();ctv.setChecked(false);ctv.setText(R.string.not_yet_authorized);return;}weibo.setWeiboActionListener(this);weibo.showUser(null);      }/*** 获得授权*/private AbstractWeibo getWeibo(int vid) {String name = null;switch (vid) {// 进入新浪微博的授权页面case R.id.ctvSw:name = SinaWeibo.NAME;break;// 进入腾讯微博的授权页面case R.id.ctvTc:name = TencentWeibo.NAME;break;// 进入人人网的授权页面case R.id.ctvRr:name = Renren.NAME;break;// 进入QQ空间的授权页面case R.id.ctvQz:name = QZone.NAME;break;}if (name != null) {return AbstractWeibo.getWeibo(this, name);}return null;}     /*** 授权成功的回调*  weibo - 回调的平台*   action - 操作的类型* res - 请求的数据通过res返回*/@Overridepublic void onComplete(AbstractWeibo weibo, int action,HashMap<String, Object> res) {Message msg = new Message();msg.arg1 = 1;msg.arg2 = action;msg.obj = weibo;handler.sendMessage(msg);       }/*** 授权失败的回调*/@Overridepublic void onError(AbstractWeibo weibo, int action, Throwable t) {t.printStackTrace();Message msg = new Message();msg.arg1 = 2;msg.arg2 = action;msg.obj = weibo;handler.sendMessage(msg);    }/*** 取消授权的回调*/@Overridepublic void onCancel(AbstractWeibo weibo, int action) {Message msg = new Message();msg.arg1 = 3;msg.arg2 = action;msg.obj = weibo;handler.sendMessage(msg);    }/** * 处理从授权页面返回的结果* * 如果获取到用户的名称,则显示名称;否则如果已经授权,则显示平台名称*/@Overridepublic boolean handleMessage(Message msg) {AbstractWeibo weibo = (AbstractWeibo) msg.obj;String text = MainActivity.actionToString(msg.arg2);switch (msg.arg1) {case 1: { // 成功text = weibo.getName() + " completed at " + text;Toast.makeText(this, text, Toast.LENGTH_SHORT).show();}break;case 2: { // 失败text = weibo.getName() + " caught error at " + text;Toast.makeText(this, text, Toast.LENGTH_SHORT).show();return false;}case 3: { // 取消text = weibo.getName() + " canceled at " + text;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.activity;import java.util.HashMap;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import cn.sharesdk.framework.AbstractWeibo;
import cn.sharesdk.framework.TitleLayout;
import cn.sharesdk.framework.WeiboActionListener;
import cn.sharesdk.renren.Renren;
import cn.sharesdk.sina.weibo.SinaWeibo;
import cn.sharesdk.tencent.qzone.QZone;
import cn.sharesdk.tencent.weibo.TencentWeibo;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 llTitle;private Button sinaBt,renrenBt,qzoneBt,tengxunBt;private Handler handler;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);//得到按钮对象sinaBt    = (Button) findViewById(R.id.btnSw);renrenBt  = (Button) findViewById(R.id.btnRr);qzoneBt   = (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);}/*** 点击按钮获取授权用户的资料*/@Overridepublic void onClick(View v) {if (v.equals(llTitle.getBtnBack())) {finish();return;}String name = null;     switch (v.getId()) {case R.id.btnSw:name = SinaWeibo.NAME;break;case R.id.btnTc:name = TencentWeibo.NAME;break;case R.id.btnRr:name = Renren.NAME;break;case R.id.btnQz:name = QZone.NAME;break;}   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 = action;msg.obj = weibo;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 = action;msg.obj = weibo;handler.sendMessage(msg);}public void onCancel(AbstractWeibo weibo, int action) {Message msg = new Message();msg.arg1 = 3;msg.arg2 = action;msg.obj = weibo;handler.sendMessage(msg);}/** 处理操作结果 */public boolean handleMessage(Message msg) {switch(msg.what) {case 1: {Intent i = new Intent(this, ShowInforActivity.class);i.putExtra("data", String.valueOf(msg.obj));startActivity(i);}break;default: {AbstractWeibo weibo = (AbstractWeibo) msg.obj;String text = MainActivity.actionToString(msg.arg2);switch (msg.arg1) {case 1: { // 成功text = weibo.getName() + " completed at " + text;}break;case 2: { // 失败text = weibo.getName() + " caught error at " + text;}break;case 3: { // 取消text = weibo.getName() + " canceled at " + text;}break;}Toast.makeText(this, text, Toast.LENGTH_SHORT).show();}break;}return false;}}

11、显示用户信息界面,ShowInfoActivity.java:

package com.yangyu.activity;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import cn.sharesdk.framework.TitleLayout;import com.yangyu.mysharethings.R;/*** @author yangyu*    功能描述:显示用户信息资料*/
public class ShowInforActivity  extends Activity implements OnClickListener {private TitleLayout llTitle;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"));}@Overridepublic void onClick(View v) {if (v.equals(llTitle.getBtnBack())) {finish();}   }}

12、这里还定义了一个Json解析类去读取授权用户的信息,JsonUtils.java:

package com.yangyu.activity;import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;/*** @author yangyu*    功能描述:这是一个简易的Json-HashMap转换工具,可以将普通的json数据(字符串)* 转换为一个HashMap<Srting, Object>表格,也可以反过来操作。此外还支*  持将json数据格式化。*/
public class JsonUtils {/*** 将指定的json数据转成 HashMap<String, Object>对象*/public HashMap<String, Object> fromJson(String jsonStr) {try {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);}}return map;}private ArrayList<Object> fromJson(JSONArray array) throws JSONException {ArrayList<Object> list = new ArrayList<Object>();for (int i = 0, size = array.length(); i < size; 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);}return list;}/*** 将指定的HashMap<String, Object>对象转成json数据 */public String fromHashMap(HashMap<String, Object> map) {try {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);}return json;}@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);}return array;}/*** 格式化一个json串*/public String format(String jsonStr) {try {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('\"');}else {sb.append(value);}i++;}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('\"');}else {sb.append(value);}i++;}sb.append('\n').append(sepStr).append(']');return sb.toString();}}

讲到这里关于这一篇的内容就差不多已经讲完了,下一篇是关于微信开放平台的授权以及分享,因为微信平台不同于其它第三方平台,实现起来稍微复杂一点,所以博主打算在下一篇的文章中详细讲解。这个下一篇文章估计要等到三天后了吧,博主和女友早就商量好趁着三天小长假出去散散心了,在这里祝大家端午节快乐!博主将会长期坚持更新关于Android、Java、Cocos2d-x、Unity3d等各个不同知识领域的实例讲解和开发!希望大家继续支持!

源码下载地址

【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料相关推荐

  1. 《Android游戏开发详解》一2.9 类

    本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.9节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区 ...

  2. 《Android游戏开发详解》一1.1 什么是编程

    本节书摘来异步社区<Android游戏开发详解>一书中的第1章,第1.1节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.1 ...

  3. 《Android游戏开发详解》——第2章,第2.13节调用对象的行为

    本节书摘来自异步社区<Android游戏开发详解>一书中的第2章,第2.13节调用对象的行为,作者 [美]Jonathan S. Harbour,更多章节内容可以访问云栖社区"异 ...

  4. 《Android游戏开发详解》一3.6 图形

    本节书摘来异步社区<Android游戏开发详解>一书中的第3章,第3.6节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区 ...

  5. 《Android游戏开发详解》——第3章,第3.6节图形

    本节书摘来自异步社区<Android游戏开发详解>一书中的第3章,第3.6节图形,作者 [美]Jonathan S. Harbour,更多章节内容可以访问云栖社区"异步社区&qu ...

  6. 《Android游戏开发详解》——第1章,第1.6节函数(在Java中称为“方法”更好)...

    本节书摘来自异步社区<Android游戏开发详解>一书中的第1章,第1.6节函数(在Java中称为"方法"更好),作者 [美]Jonathan S. Harbour,更 ...

  7. JMessage Android 端开发详解

    JMessage Android 端开发详解 目前越来越多的应用会需要集成即时通讯功能,这里就为大家详细讲一下如何通过集成 JMessage 来为你的 App 增加即时通讯功能. 首先,一个最基础的 ...

  8. 《Android游戏开发详解》一2.16 区分类和对象

    本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.16节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社 ...

  9. 《Android游戏开发详解》一3.1 构造方法

    本节书摘来异步社区<Android游戏开发详解>一书中的第3章,第3.1节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区 ...

  10. 《Android游戏开发详解》一导读

    前 言 Android游戏开发详解 作为对编程知之甚少或者毫无所知的初学者,开始学习Android游戏开发,可能会觉得就像是穿越陌生的星际的旅程.有太多的事情要尝试,太多的知识要学习,令人遗憾的是,还 ...

最新文章

  1. mysql select * f
  2. Java记录 -74- 自定义泛型
  3. 面试题6--利用前序和中序遍历重构二叉树--递归方法
  4. .net学习之母版页执行顺序、jsonp跨域请求原理、IsPostBack原理、服务器端控件按钮Button点击时的过程、缓存、IHttpModule 过滤器...
  5. Linux --Solr 安装/配置
  6. xamarin和mysql_Xamarin.Android 使用 SQLiteOpenHelper 进行数据库操作
  7. SpringBoot(四):mybatis之通用mapper、分页插件PageHelper
  8. html怎么让鼠标自动移动位置,手把手教你编作弊软件之 鼠标自动移动/点击
  9. linux 内核 sd卡驱动,Linux3.4内核SD卡驱动移植
  10. c++ 多边形求交集代码(凸多边形与凸多边形交集)
  11. 「运维有小邓」ADAudit Plus(AD域审计工具)的主要优势?
  12. ByteV打造3D海上风电监控平台 ——助力风电能源可持续发展
  13. 小米8 twrp recovery_橙狐Recovery-一款另类功能丰富的第三方刷机工具-支持MIUI OTA
  14. ASP.NET Core WEB部署:Kestrel
  15. Qt接入阿里云SDK,OSS工程,实现头像上传,Mac和Win编译库文件。
  16. Pycharm2019使用方法(六)——鼠标放代码中单击Edit后菜单功能
  17. 公众号接口消息推送+VB+WebService实战
  18. win11文件夹如何显示缩略图?文件夹显示缩略图的方法
  19. 直播系统开发,完整的系统框架架构,打造完美的直播系统
  20. 【LabVIEW花样翻新】前言

热门文章

  1. css 恢复ulli_CSS Ul(列表样式)
  2. android 全局换字体,Android 全局替换字体
  3. —— GPS测量原理及应用复习-8 ——
  4. 学生学习时长统计--python程序设计
  5. 美颜SDK是什么?美颜SDK和美颜APP有什么区别?
  6. Java 使用word模板创建word文档报告教程
  7. 成功解决wps文档中输入英文单词出现对应英文单词下边红色波浪线(英文拼写自动检测)去掉或加上图文教程
  8. Python 05 包Packet
  9. alexa与CISI指数—网站世界排名准则(转)
  10. 苹果 开发者账号如下