实现第三方授权登录、分享以及获取用户资料

 这篇文章中,我们使用到了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:

[html]  view plain copy
  1. xml version="1.0" encoding="utf-8"?>  
  2. <DevInfor>  
  3.       
  4.       
  5.     <SinaWeibo  
  6.         SortId="1"  
  7.         AppKey="3201194191"  
  8.         AppSecret="0334252914651e8f76bad63337b3b78f"  
  9.         Id="1"  
  10.         RedirectUrl="http://appgo.cn" />  
  11.   
  12.     <TencentWeibo  
  13.         SortId="2"  
  14.         AppKey="801307650"  
  15.         AppSecret="ae36f4ee3946e1cbb98d6965b0b2ff5c"  
  16.         RedirectUri="http://sharesdk.cn"  
  17.         Id="2" />  
  18.   
  19.     <QZone  
  20.         SortId="3"  
  21.         AppId="100371282"  
  22.         AppKey="aed9b0303e3ed1e27bae87c33761161d"  
  23.         Id="3"  
  24.         RedirectUrl="http://www.shareSDK.cn" />  
  25.          
  26.     <Renren  
  27.         SortId="4"  
  28.         AppId="226427"  
  29.         ApiKey="fc5b8aed373c4c27a05b712acba0f8c3"  
  30.         Id="4"  
  31.         SecretKey="f29df781abdd4f49beca5a2194676ca4" />    
  32.          
  33. DevInfor>  

2、配置AndroidManifest.xml,不同的集成度需要在AndroidManifest.xml中添加的内容也不一样。但是首先你需要添加下面的权限列表:

[html]  view plain copy
  1. <uses-permission android:name="android.permission.INTERNET" />  
  2.     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
  3.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
  4.     <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />  
  5.     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />  
  6.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  7.     <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:

[html]  view plain copy
  1. <activity  
  2.             android:name="cn.sharesdk.framework.AuthorizeActivity"  
  3.             android:configChanges="keyboardHidden|orientation"  
  4.             android:screenOrientation="portrait"  
  5.             android:theme="@android:style/Theme.Translucent.NoTitleBar"  
  6.             android:windowSoftInputMode="stateHidden|adjustResize" >            
  7.         activity>  

AuthorizeActivity的路径是固定的,一定要在“cn.sharesdk.framework”下,因为他在Share-Core包中。

4、添加布局页面,首先是主界面的布局页面,activity_main.xml:

[html]  view plain copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <Button  
  7.         android:id="@+id/btnLogin"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="44dp"  
  10.         android:layout_above="@+id/btnShareAllGui"  
  11.         android:layout_centerHorizontal="true"  
  12.         android:layout_margin="5dp"  
  13.         android:background="@drawable/btn_back"  
  14.         android:text="用户授权登录"   
  15.         android:textSize="16dp"/>  
  16.          
  17.     <Button  
  18.         android:id="@+id/btnShareAllGui"  
  19.         android:layout_width="fill_parent"  
  20.         android:layout_height="44dp"  
  21.         android:layout_above="@+id/btnShareAll"  
  22.         android:layout_margin="5dp"  
  23.         android:background="@drawable/btn_back"  
  24.         android:text="分享全部(有分享界面)"  
  25.         android:textSize="16dp" />  
  26.   
  27.     <Button  
  28.         android:id="@+id/btnShareAll"  
  29.         android:layout_width="fill_parent"  
  30.         android:layout_height="44dp"  
  31.         android:layout_alignParentRight="true"  
  32.         android:layout_centerVertical="true"  
  33.         android:layout_margin="5dp"  
  34.         android:background="@drawable/btn_back"  
  35.         android:text="分享全部(无界面,直接分享)"  
  36.         android:textSize="16dp" />  
  37.   
  38.     <Button  
  39.         android:id="@+id/btnUserInfo"  
  40.         android:layout_width="fill_parent"  
  41.         android:layout_height="44dp"  
  42.         android:layout_below="@+id/btnShareAll"  
  43.         android:layout_margin="5dp"  
  44.         android:layout_marginTop="41dp"  
  45.         android:background="@drawable/btn_back"  
  46.         android:text="获取授权用户资料"   
  47.         android:textSize="16dp" />  
  48.   
  49. RelativeLayout>  

5、用户授权登录的布局页面,activity_auth.xml:

[html]  view plain copy
  1. xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="#fff5f5f5"  
  6.     android:orientation="vertical" >  
  7.   
  8.       
  9.     <cn.sharesdk.framework.TitleLayout  
  10.         android:id="@+id/llTitle"  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="wrap_content"  
  13.         android:background="@drawable/title_back" />  
  14.   
  15.     <LinearLayout  
  16.         android:id="@+id/llBody"  
  17.         android:layout_width="fill_parent"  
  18.         android:layout_height="wrap_content"  
  19.         android:layout_alignParentLeft="true"  
  20.         android:layout_alignParentTop="true"  
  21.         android:layout_marginTop="58dp"  
  22.         android:orientation="vertical"  
  23.         android:padding="10dp" >  
  24.   
  25.         <LinearLayout  
  26.             android:layout_width="fill_parent"  
  27.             android:layout_height="50dp"  
  28.             android:background="@drawable/list_item_first_normal"  
  29.             android:paddingLeft="10dp"  
  30.             android:paddingRight="10dp" >  
  31.   
  32.             <ImageView  
  33.                 android:layout_width="30dp"  
  34.                 android:layout_height="30dp"  
  35.                 android:layout_gravity="center_vertical"  
  36.                 android:layout_marginRight="10dp"  
  37.                 android:scaleType="centerInside"  
  38.                 android:src="@drawable/sina_weibo" />  
  39.   
  40.             <CheckedTextView  
  41.                 android:id="@+id/ctvSw"  
  42.                 android:layout_width="fill_parent"  
  43.                 android:layout_height="fill_parent"  
  44.                 android:layout_gravity="center_vertical"  
  45.                 android:drawablePadding="10dp"  
  46.                 android:drawableRight="@drawable/cb_drw"  
  47.                 android:gravity="center_vertical"  
  48.                 android:singleLine="true"  
  49.                 android:text="@string/not_yet_authorized"  
  50.                 android:textColor="#ff000000"  
  51.                 android:textSize="20dp" />  
  52.         LinearLayout>  
  53.   
  54.         <LinearLayout  
  55.             android:layout_width="fill_parent"  
  56.             android:layout_height="50dp"  
  57.             android:background="@drawable/list_item_middle_normal"  
  58.             android:paddingLeft="10dp"  
  59.             android:paddingRight="10dp" >  
  60.   
  61.             <ImageView  
  62.                 android:layout_width="30dp"  
  63.                 android:layout_height="30dp"  
  64.                 android:layout_gravity="center_vertical"  
  65.                 android:layout_marginRight="10dp"  
  66.                 android:scaleType="centerInside"  
  67.                 android:src="@drawable/tencent_weibo" />  
  68.   
  69.             <CheckedTextView  
  70.                 android:id="@+id/ctvTc"  
  71.                 android:layout_width="fill_parent"  
  72.                 android:layout_height="fill_parent"  
  73.                 android:layout_gravity="center_vertical"  
  74.                 android:drawablePadding="10dp"  
  75.                 android:drawableRight="@drawable/cb_drw"  
  76.                 android:gravity="center_vertical"  
  77.                 android:singleLine="true"  
  78.                 android:text="@string/not_yet_authorized"  
  79.                 android:textColor="#ff000000"  
  80.                 android:textSize="20dp" />  
  81.         LinearLayout>  
  82.   
  83.         <LinearLayout  
  84.             android:layout_width="fill_parent"  
  85.             android:layout_height="50dp"  
  86.             android:background="@drawable/list_item_middle_normal"  
  87.             android:paddingLeft="10dp"  
  88.             android:paddingRight="10dp" >  
  89.   
  90.             <ImageView  
  91.                 android:layout_width="30dp"  
  92.                 android:layout_height="30dp"  
  93.                 android:layout_gravity="center_vertical"  
  94.                 android:layout_marginRight="10dp"  
  95.                 android:scaleType="centerInside"  
  96.                 android:src="@drawable/renren" />  
  97.   
  98.             <CheckedTextView  
  99.                 android:id="@+id/ctvRr"  
  100.                 android:layout_width="fill_parent"  
  101.                 android:layout_height="fill_parent"  
  102.                 android:layout_gravity="center_vertical"  
  103.                 android:drawablePadding="10dp"  
  104.                 android:drawableRight="@drawable/cb_drw"  
  105.                 android:gravity="center_vertical"  
  106.                 android:singleLine="true"  
  107.                 android:text="@string/not_yet_authorized"  
  108.                 android:textColor="#ff000000"  
  109.                 android:textSize="20dp" />  
  110.         LinearLayout>  
  111.   
  112.         <LinearLayout  
  113.             android:layout_width="fill_parent"  
  114.             android:layout_height="50dp"  
  115.             android:background="@drawable/list_item_last_normal"  
  116.             android:paddingLeft="10dp"  
  117.             android:paddingRight="10dp" >  
  118.   
  119.             <ImageView  
  120.                 android:layout_width="30dp"  
  121.                 android:layout_height="30dp"  
  122.                 android:layout_gravity="center_vertical"  
  123.                 android:layout_marginRight="10dp"  
  124.                 android:scaleType="centerInside"  
  125.                 android:src="@drawable/qzone" />  
  126.   
  127.             <CheckedTextView  
  128.                 android:id="@+id/ctvQz"  
  129.                 android:layout_width="fill_parent"  
  130.                 android:layout_height="fill_parent"  
  131.                 android:layout_gravity="center_vertical"  
  132.                 android:drawablePadding="10dp"  
  133.                 android:drawableRight="@drawable/cb_drw"  
  134.                 android:gravity="center_vertical"  
  135.                 android:singleLine="true"  
  136.                 android:text="@string/not_yet_authorized"  
  137.                 android:textColor="#ff000000"  
  138.                 android:textSize="20dp" />  
  139.         LinearLayout>  
  140.     LinearLayout>  
  141.   
  142. RelativeLayout>  


6、获得用户信息布局界面,activity_userinfo.xml:

[html]  view plain copy
  1. xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="#fff5f5f5"  
  6.     android:orientation="vertical" >  
  7.   
  8.       
  9.     <cn.sharesdk.framework.TitleLayout  
  10.         android:id="@+id/llTitle"  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="wrap_content"  
  13.         android:background="@drawable/title_back" />  
  14.   
  15.             <Button  
  16.                 android:id="@+id/btnQz"  
  17.                 android:layout_width="fill_parent"  
  18.                 android:layout_height="44dp"  
  19.                 android:layout_centerVertical="true"  
  20.                 android:layout_margin="5dp"  
  21.                 android:background="@drawable/btn_back"  
  22.                 android:text="@string/get_user_info_qz"  
  23.                 android:textSize="16dp" />  
  24.   
  25.             <Button  
  26.                 android:id="@+id/btnRr"  
  27.                 android:layout_width="fill_parent"  
  28.                 android:layout_height="44dp"  
  29.                 android:layout_above="@+id/btnQz"  
  30.                 android:layout_margin="5dp"  
  31.                 android:background="@drawable/btn_back"  
  32.                 android:text="@string/get_user_info_rr"  
  33.                 android:textSize="16dp" />  
  34.   
  35.             <Button  
  36.                 android:id="@+id/btnSw"  
  37.                 android:layout_width="fill_parent"  
  38.                 android:layout_height="44dp"  
  39.                 android:layout_above="@+id/btnRr"  
  40.                 android:layout_margin="5dp"  
  41.                 android:background="@drawable/btn_back"  
  42.                 android:text="@string/get_user_info_sw"  
  43.                 android:textSize="16dp" />  
  44.   
  45.             <Button  
  46.                 android:id="@+id/btnTc"  
  47.                 android:layout_width="fill_parent"  
  48.                 android:layout_height="44dp"  
  49.                 android:layout_below="@+id/btnQz"  
  50.                 android:layout_centerHorizontal="true"  
  51.                 android:layout_margin="5dp"  
  52.                 android:background="@drawable/btn_back"  
  53.                 android:text="@string/get_user_info_tc"  
  54.                 android:textSize="16dp" />  
  55.   
  56. RelativeLayout>  


7、显示用户获得的信息布局界面,activity_userinfo.xml:

[html]  view plain copy
  1. xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="#fff5f5f5"  
  6.     android:orientation="vertical" >  
  7.   
  8.       
  9.     <cn.sharesdk.framework.TitleLayout  
  10.         android:id="@+id/llTitle"  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="wrap_content"  
  13.         android:background="@drawable/title_back" />  
  14.   
  15.     <ScrollView  
  16.         android:layout_width="fill_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:layout_alignParentBottom="true"  
  19.         android:layout_below="@id/llTitle"  
  20.         android:paddingBottom="10dp"  
  21.         android:paddingLeft="10dp"  
  22.         android:paddingTop="10dp" >  
  23.   
  24.         <TextView  
  25.             android:id="@+id/tvJson"  
  26.             android:layout_width="fill_parent"  
  27.             android:layout_height="wrap_content"  
  28.             android:layout_marginRight="10dp"  
  29.             android:autoLink="all"  
  30.             android:background="@drawable/list_item_single_normal"  
  31.             android:textColor="#ff000000" />  
  32.     ScrollView>  
  33.   
  34. RelativeLayout>  

 

8、主界面入口Activity类,MainActivity.java:

[java]  view plain copy
  1. package com.yangyu.activity;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.Intent;  
  8. import android.graphics.Bitmap;  
  9. import android.graphics.Bitmap.CompressFormat;  
  10. import android.graphics.BitmapFactory;  
  11. import android.os.Bundle;  
  12. import android.os.Environment;  
  13. import android.view.View;  
  14. import android.view.View.OnClickListener;  
  15. import android.widget.Button;  
  16. import cn.sharesdk.framework.AbstractWeibo;  
  17. import cn.sharesdk.onekeyshare.ShareAllGird;  
  18.   
  19. import com.yangyu.mysharethings.R;  
  20.   
  21. /** 
  22.  * @author yangyu 
  23.  *  功能描述:主Activity类,程序的入口类 
  24.  */  
  25. public class MainActivity extends Activity implements OnClickListener {  
  26.     //定义图片存放的地址  
  27.     public static String TEST_IMAGE;  
  28.   
  29.     //定义"账号登陆"按钮,"有分享界面按钮","无分享界面"按钮,"得到用户资料"按钮  
  30.     private Button authLoginBtn,shareGuiBtn,shareBtn,getInfoBtn;  
  31.       
  32.     @Override  
  33.     protected void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         setContentView(R.layout.activity_main);  
  36.           
  37.         //初始化ShareSDK  
  38.         AbstractWeibo.initSDK(this);      
  39.           
  40.         initImagePath();                      
  41.           
  42.         initView();  
  43.           
  44.         initData();  
  45.     }  
  46.   
  47.     /** 
  48.      * 初始化组件 
  49.      */  
  50.     private void initView(){  
  51.         authLoginBtn = (Button)findViewById(R.id.btnLogin);  
  52.         shareGuiBtn = (Button)findViewById(R.id.btnShareAllGui);  
  53.         shareBtn = (Button)findViewById(R.id.btnShareAll);  
  54.         getInfoBtn = (Button)findViewById(R.id.btnUserInfo);  
  55.     }  
  56.       
  57.     /** 
  58.      * 初始化数据 
  59.      */  
  60.     private void initData(){  
  61.         //设置按钮监听事件  
  62.         authLoginBtn.setOnClickListener(this);  
  63.         shareGuiBtn.setOnClickListener(this);  
  64.         shareBtn.setOnClickListener(this);  
  65.         getInfoBtn.setOnClickListener(this);  
  66.     }  
  67.       
  68.     /** 
  69.      * 初始化分享的图片 
  70.      */  
  71.     private void initImagePath() {  
  72.         try {//判断SD卡中是否存在此文件夹  
  73.             if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())  
  74.                     && Environment.getExternalStorageDirectory().exists()) {  
  75.                 TEST_IMAGE = Environment.getExternalStorageDirectory().getAbsolutePath() + "/pic.png";  
  76.             }  
  77.             else {  
  78.                 TEST_IMAGE = getApplication().getFilesDir().getAbsolutePath() + "/pic.png";  
  79.             }  
  80.             File file = new File(TEST_IMAGE);  
  81.             //判断图片是否存此文件夹中  
  82.             if (!file.exists()) {  
  83.                 file.createNewFile();  
  84.                 Bitmap pic = BitmapFactory.decodeResource(getResources(), R.drawable.pic);  
  85.                 FileOutputStream fos = new FileOutputStream(file);  
  86.                 pic.compress(CompressFormat.JPEG, 100, fos);  
  87.                 fos.flush();  
  88.                 fos.close();  
  89.             }  
  90.         } catch(Throwable t) {  
  91.             t.printStackTrace();  
  92.             TEST_IMAGE = null;  
  93.         }  
  94.     }  
  95.       
  96.     /** 
  97.      * 按钮监听事件 
  98.      */  
  99.     @Override  
  100.     public void onClick(View v) {  
  101.         switch (v.getId()) {  
  102.         case R.id.btnLogin:  
  103.             startActivity(new Intent(MainActivity.this,AuthActivity.class));  
  104.             break;  
  105.         case R.id.btnShareAllGui:  
  106.             showGrid(false);  
  107.             break;  
  108.         case R.id.btnShareAll:  
  109.             showGrid(true);  
  110.             break;  
  111.         case R.id.btnUserInfo:  
  112.             // 获取自己的资料  
  113.             Intent i = new Intent(this, GetInforActivity.class);  
  114.             startActivity(i);  
  115.             break;  
  116.         default:  
  117.             break;  
  118.         }  
  119.           
  120.     }  
  121.   
  122.     /** 
  123.      * 使用快捷分享完成图文分享 
  124.      */  
  125.     private void showGrid(boolean silent) {  
  126.         Intent i = new Intent(this, ShareAllGird.class);  
  127.         // 分享时Notification的图标  
  128.         i.putExtra("notif_icon", R.drawable.ic_launcher);  
  129.         // 分享时Notification的标题  
  130.         i.putExtra("notif_title"this.getString(R.string.app_name));  
  131.   
  132.         // title标题,在印象笔记、邮箱、信息、微信(包括好友和朋友圈)、人人网和QQ空间使用,否则可以不提供  
  133.         i.putExtra("title"this.getString(R.string.share));  
  134.         // titleUrl是标题的网络链接,仅在人人网和QQ空间使用,否则可以不提供  
  135.         i.putExtra("titleUrl""http://sharesdk.cn");  
  136.         // text是分享文本,所有平台都需要这个字段  
  137.         i.putExtra("text"this.getString(R.string.share_content));  
  138.         // imagePath是本地的图片路径,所有平台都支持这个字段,不提供,则表示不分享图片  
  139.         i.putExtra("imagePath", MainActivity.TEST_IMAGE);  
  140.         // url仅在微信(包括好友和朋友圈)中使用,否则可以不提供  
  141.         i.putExtra("url""http://sharesdk.cn");  
  142.         // thumbPath是缩略图的本地路径,仅在微信(包括好友和朋友圈)中使用,否则可以不提供  
  143.         i.putExtra("thumbPath", MainActivity.TEST_IMAGE);  
  144.         // appPath是待分享应用程序的本地路劲,仅在微信(包括好友和朋友圈)中使用,否则可以不提供  
  145.         i.putExtra("appPath", MainActivity.TEST_IMAGE);  
  146.         // comment是我对这条分享的评论,仅在人人网和QQ空间使用,否则可以不提供  
  147.         i.putExtra("comment"this.getString(R.string.share));  
  148.         // site是分享此内容的网站名称,仅在QQ空间使用,否则可以不提供  
  149.         i.putExtra("site"this.getString(R.string.app_name));  
  150.         // siteUrl是分享此内容的网站地址,仅在QQ空间使用,否则可以不提供  
  151.         i.putExtra("siteUrl""http://sharesdk.cn");  
  152.   
  153.         // 是否直接分享  
  154.         i.putExtra("silent", silent);  
  155.         this.startActivity(i);  
  156.     }  
  157.       
  158.     /** 
  159.      * 将action转换为String 
  160.      */  
  161.     public static String actionToString(int action) {  
  162.         switch (action) {  
  163.             case AbstractWeibo.ACTION_AUTHORIZING: return "ACTION_AUTHORIZING";  
  164.             case AbstractWeibo.ACTION_GETTING_FRIEND_LIST: return "ACTION_GETTING_FRIEND_LIST";  
  165.             case AbstractWeibo.ACTION_FOLLOWING_USER: return "ACTION_FOLLOWING_USER";  
  166.             case AbstractWeibo.ACTION_SENDING_DIRECT_MESSAGE: return "ACTION_SENDING_DIRECT_MESSAGE";  
  167.             case AbstractWeibo.ACTION_TIMELINE: return "ACTION_TIMELINE";  
  168.             case AbstractWeibo.ACTION_USER_INFOR: return "ACTION_USER_INFOR";  
  169.             case AbstractWeibo.ACTION_SHARE: return "ACTION_SHARE";  
  170.             default: {  
  171.                 return "UNKNOWN";  
  172.             }  
  173.         }  
  174.     }  
  175.       
  176.     protected void onDestroy() {  
  177.         //结束ShareSDK的统计功能并释放资源  
  178.         AbstractWeibo.stopSDK(this);  
  179.         super.onDestroy();  
  180.     }  
  181. }  

 集成ShareSDK需要至少在两个地方添加代码,包括:

<1>  在onCreate中插入下面的代码:

[java]  view plain copy
  1. //初始化ShareSDK  
  2.         AbstractWeibo.initSDK(this);  

      这行代码会初始化ShareSDK,此后对ShareSDK的操作都依次为基础。如果不在所有ShareSDK的操作之前调用这行代码,会抛出空指针异常。

<2> 在项目的出口Activity的onDestroy方法的第一行插入下面的代码:

[java]  view plain copy
  1. protected void onDestroy() {  
  2.         //结束ShareSDK的统计功能并释放资源  
  3.         AbstractWeibo.stopSDK(this);  
  4.         super.onDestroy();  
  5.     }  

        这行代码会结束ShareSDK的统计功能并释放资源。如果这行代码没有被调用,那么

“应用启动次数”的统计将不会准确,因为应用可能从来没有被关闭。

          InitSDK是可以重复调用的,其实ShareSDK建议在你不确定的时候调用这个方法,

来保证ShareSDK被正确初始化。而stopSDK一旦调用了,就必须重新调用InitSDK才能使

用ShareSDK的功能,否则会出现空指针异常。

 

 在这段代码中,还使用到了快捷分享,如下图所示,点击按钮弹出快捷分享界面:

             


      什么是快捷分享呢?快捷分享是ShareSDK提供的一套基于其接口的GUI。通过简单的配置,可以在不考虑平台的情况下,调用很少的代码,就完成分享的操作。快捷分享的jar包放在SDK解压目录的"Libs\ShareSDK-GUI"中,叫做"cn.sharesdk.oneshare.jar"。快捷分享使用了两个Activity,需要在AndroidManifest.xml中注册这两个Activity:

[html]  view plain copy
  1. <activity  
  2.             android:name="cn.sharesdk.onekeyshare.ShareAllGird"  
  3.             android:configChanges="keyboardHidden|orientation"  
  4.             android:screenOrientation="portrait"  
  5.             android:theme="@android:style/Theme.Translucent.NoTitleBar"  
  6.             android:windowSoftInputMode="adjustPan|stateHidden" />  
  7.         <activity  
  8.             android:name="cn.sharesdk.onekeyshare.SharePage"  
  9.             android:configChanges="keyboardHidden|orientation"  
  10.             android:screenOrientation="portrait"  
  11.             android:windowSoftInputMode="stateHidden|adjustResize" />  

  

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

[java]  view plain copy
  1. package com.yangyu.activity;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. import android.app.Activity;  
  6. import android.os.Bundle;  
  7. import android.os.Handler;  
  8. import android.os.Handler.Callback;  
  9. import android.os.Message;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.CheckedTextView;  
  13. import android.widget.Toast;  
  14. import cn.sharesdk.framework.AbstractWeibo;  
  15. import cn.sharesdk.framework.TitleLayout;  
  16. import cn.sharesdk.framework.WeiboActionListener;  
  17. import cn.sharesdk.renren.Renren;  
  18. import cn.sharesdk.sina.weibo.SinaWeibo;  
  19. import cn.sharesdk.tencent.qzone.QZone;  
  20. import cn.sharesdk.tencent.weibo.TencentWeibo;  
  21.   
  22. import com.yangyu.mysharethings.R;  
  23.   
  24. /** 
  25.  * @author yangyu 
  26.  *  功能描述:授权和取消授权Activity,由于UI显示需要授权过的平台显示账户的名称, 
  27.  *    因此此页面事实上展示的是“获取用户资料”和“取消授权”两个功能。 
  28.  */  
  29. public class AuthActivity extends Activity implements Callback, OnClickListener, WeiboActionListener {  
  30.     //定义CheckedTextView对象  
  31.     private CheckedTextView  sinaCt,qzoneCt,tengxunCt,renrenCt;  
  32.       
  33.     //定义Handler对象  
  34.     private Handler handler;  
  35.   
  36.     //定义标题栏对象  
  37.     private TitleLayout llTitle;  
  38.   
  39.     @Override  
  40.     protected void onCreate(Bundle savedInstanceState) {  
  41.         super.onCreate(savedInstanceState);  
  42.         setContentView(R.layout.activity_auth);  
  43.           
  44.         initView();  
  45.           
  46.         initData();  
  47.     }  
  48.   
  49.     /** 
  50.      * 初始化组件 
  51.      */  
  52.     private void initView(){  
  53.         //实例化Handler对象并设置信息回调监听接口  
  54.         handler = new Handler(this);  
  55.   
  56.         //得到标题栏对象  
  57.         llTitle = (TitleLayout) findViewById(R.id.llTitle);       
  58.           
  59.         //得到组件对象  
  60.         sinaCt    = (CheckedTextView)findViewById(R.id.ctvSw);  
  61.         qzoneCt   = (CheckedTextView)findViewById(R.id.ctvQz);  
  62.         tengxunCt = (CheckedTextView)findViewById(R.id.ctvTc);  
  63.         renrenCt  = (CheckedTextView)findViewById(R.id.ctvRr);        
  64.     }  
  65.       
  66.     /** 
  67.      * 初始化数据 
  68.      */  
  69.     private void initData(){  
  70.         llTitle.getBtnBack().setOnClickListener(new OnClickListener() {           
  71.             @Override  
  72.             public void onClick(View v) {  
  73.                 finish();                 
  74.             }  
  75.         });  
  76.         llTitle.getTvTitle().setText("用户授权登录");  
  77.           
  78.         //设置监听  
  79.         sinaCt.setOnClickListener(this);  
  80.         qzoneCt.setOnClickListener(this);  
  81.         tengxunCt.setOnClickListener(this);  
  82.         renrenCt.setOnClickListener(this);  
  83.   
  84.         //获取平台列表  
  85.         AbstractWeibo[] weibos = AbstractWeibo.getWeiboList(this);  
  86.           
  87.         for(int i = 0;i < weibos.length;i++){  
  88.             if (!weibos[i].isValid()) {  
  89.                 continue;  
  90.             }  
  91.               
  92.             CheckedTextView ctv = getView(weibos[i]);  
  93.             if (ctv != null) {  
  94.                 ctv.setChecked(true);  
  95.                 // 得到授权用户的用户名称  
  96.                 String userName = weibos[i].getDb().get("nickname");   
  97.                 if (userName == null || userName.length() <= 0 || "null".equals(userName)) {  
  98.                     // 如果平台已经授权却没有拿到帐号名称,则自动获取用户资料,以获取名称  
  99.                     userName = getWeiboName(weibos[i]);  
  100.                     //添加平台事件监听  
  101.                     weibos[i].setWeiboActionListener(this);  
  102.                     //显示用户资料,null表示显示自己的资料  
  103.                     weibos[i].showUser(null);  
  104.                 }  
  105.                 ctv.setText(userName);  
  106.             }  
  107.         }  
  108.     }  
  109.       
  110.     /** 
  111.      * 在CheckedTextView组件中显示授权用户的名称 
  112.      */  
  113.     private CheckedTextView getView(AbstractWeibo weibo) {  
  114.         if (weibo == null) {  
  115.             return null;  
  116.         }  
  117.           
  118.         String name = weibo.getName();  
  119.         if (name == null) {  
  120.             return null;  
  121.         }  
  122.           
  123.         View v = null;  
  124.         if (SinaWeibo.NAME.equals(name)) {  
  125.             v = findViewById(R.id.ctvSw);  
  126.         }  
  127.         else if (TencentWeibo.NAME.equals(name)) {  
  128.             v = findViewById(R.id.ctvTc);  
  129.         }         
  130.         else if (Renren.NAME.equals(name)) {  
  131.             v = findViewById(R.id.ctvRr);  
  132.         }  
  133.         else if (QZone.NAME.equals(name)) {  
  134.             v = findViewById(R.id.ctvQz);  
  135.         }         
  136.           
  137.         if (v == null) {  
  138.             return null;  
  139.         }  
  140.           
  141.         if (! (v instanceof CheckedTextView)) {  
  142.             return null;  
  143.         }  
  144.           
  145.         return (CheckedTextView) v;  
  146.     }  
  147.       
  148.     /** 
  149.      * 得到授权用户的用户名称 
  150.      */  
  151.     private String getWeiboName(AbstractWeibo weibo) {  
  152.         if (weibo == null) {  
  153.             return null;  
  154.         }  
  155.           
  156.         String name = weibo.getName();  
  157.         if (name == null) {  
  158.             return null;  
  159.         }  
  160.           
  161.         int res = 0;  
  162.         if (SinaWeibo.NAME.equals(name)) {  
  163.             res = R.string.sinaweibo;  
  164.         }  
  165.         else if (TencentWeibo.NAME.equals(name)) {  
  166.             res = R.string.tencentweibo;  
  167.         }         
  168.         else if (Renren.NAME.equals(name)) {  
  169.             res = R.string.renren;  
  170.         }  
  171.         else if (QZone.NAME.equals(name)) {  
  172.             res = R.string.qzone;  
  173.         }         
  174.           
  175.         if (res == 0) {  
  176.             return name;  
  177.         }         
  178.         return this.getResources().getString(res);  
  179.     }  
  180.       
  181.     /** 
  182.      * 授权和取消授权的按钮点击监听事件 
  183.      */  
  184.     @Override  
  185.     public void onClick(View v) {                 
  186.         AbstractWeibo weibo = getWeibo(v.getId());  
  187.           
  188.         CheckedTextView ctv = (CheckedTextView) v;  
  189.         if (weibo == null) {  
  190.             ctv.setChecked(false);  
  191.             ctv.setText(R.string.not_yet_authorized);  
  192.             return;  
  193.         }  
  194.           
  195.         if (weibo.isValid()) {  
  196.             weibo.removeAccount();  
  197.             ctv.setChecked(false);  
  198.             ctv.setText(R.string.not_yet_authorized);  
  199.             return;  
  200.         }  
  201.           
  202.         weibo.setWeiboActionListener(this);  
  203.         weibo.showUser(null);         
  204.     }  
  205.   
  206.     /** 
  207.      * 获得授权 
  208.      */  
  209.     private AbstractWeibo getWeibo(int vid) {  
  210.         String name = null;  
  211.         switch (vid) {  
  212.         // 进入新浪微博的授权页面  
  213.         case R.id.ctvSw:  
  214.             name = SinaWeibo.NAME;  
  215.             break;  
  216.         // 进入腾讯微博的授权页面  
  217.         case R.id.ctvTc:  
  218.             name = TencentWeibo.NAME;  
  219.             break;  
  220.         // 进入人人网的授权页面  
  221.         case R.id.ctvRr:  
  222.             name = Renren.NAME;  
  223.             break;  
  224.         // 进入QQ空间的授权页面  
  225.         case R.id.ctvQz:  
  226.             name = QZone.NAME;  
  227.             break;  
  228.         }  
  229.           
  230.         if (name != null) {  
  231.             return AbstractWeibo.getWeibo(this, name);  
  232.         }  
  233.         return null;  
  234.     }         
  235.   
  236.     /** 
  237.      * 授权成功的回调 
  238.      *  weibo - 回调的平台 
  239.      *  action - 操作的类型 
  240.      *  res - 请求的数据通过res返回 
  241.      */  
  242.     @Override  
  243.     public void onComplete(AbstractWeibo weibo, int action,HashMap res) {  
  244.         Message msg = new Message();  
  245.         msg.arg1 = 1;  
  246.         msg.arg2 = action;  
  247.         msg.obj = weibo;  
  248.         handler.sendMessage(msg);         
  249.     }  
  250.   
  251.     /** 
  252.      * 授权失败的回调 
  253.      */  
  254.     @Override  
  255.     public void onError(AbstractWeibo weibo, int action, Throwable t) {  
  256.         t.printStackTrace();  
  257.           
  258.         Message msg = new Message();  
  259.         msg.arg1 = 2;  
  260.         msg.arg2 = action;  
  261.         msg.obj = weibo;  
  262.         handler.sendMessage(msg);     
  263.     }  
  264.       
  265.     /** 
  266.      * 取消授权的回调 
  267.      */  
  268.     @Override  
  269.     public void onCancel(AbstractWeibo weibo, int action) {  
  270.         Message msg = new Message();  
  271.         msg.arg1 = 3;  
  272.         msg.arg2 = action;  
  273.         msg.obj = weibo;  
  274.         handler.sendMessage(msg);     
  275.     }  
  276.   
  277.     /**  
  278.      * 处理从授权页面返回的结果 
  279.      *  
  280.      * 如果获取到用户的名称,则显示名称;否则如果已经授权,则显示平台名称 
  281.      */  
  282.     @Override  
  283.     public boolean handleMessage(Message msg) {  
  284.         AbstractWeibo weibo = (AbstractWeibo) msg.obj;  
  285.         String text = MainActivity.actionToString(msg.arg2);  
  286.   
  287.         switch (msg.arg1) {  
  288.             case 1: { // 成功  
  289.                 text = weibo.getName() + " completed at " + text;  
  290.                 Toast.makeText(this, text, Toast.LENGTH_SHORT).show();  
  291.             }  
  292.             break;  
  293.             case 2: { // 失败  
  294.                 text = weibo.getName() + " caught error at " + text;  
  295.                 Toast.makeText(this, text, Toast.LENGTH_SHORT).show();  
  296.                 return false;  
  297.             }  
  298.             case 3: { // 取消  
  299.                 text = weibo.getName() + " canceled at " + text;  
  300.                 Toast.makeText(this, text, Toast.LENGTH_SHORT).show();  
  301.                 return false;  
  302.             }  
  303.         }  
  304.   
  305.         CheckedTextView ctv = getView(weibo);  
  306.         if (ctv != null) {  
  307.             ctv.setChecked(true);  
  308.             String userName = weibo.getDb().get("nickname"); // getAuthedUserName();  
  309.             if (userName == null || userName.length() <= 0  
  310.                     || "null".equals(userName)) {  
  311.                 userName = getWeiboName(weibo);  
  312.             }  
  313.             ctv.setText(userName);  
  314.         }  
  315.         return false;  
  316.     }  
  317. }  

10、获取用户信息界面,GetInfoActivity.java:

[java]  view plain copy
  1. package com.yangyu.activity;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.Intent;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.os.Handler.Callback;  
  10. import android.os.Message;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14. import android.widget.Toast;  
  15. import cn.sharesdk.framework.AbstractWeibo;  
  16. import cn.sharesdk.framework.TitleLayout;  
  17. import cn.sharesdk.framework.WeiboActionListener;  
  18. import cn.sharesdk.renren.Renren;  
  19. import cn.sharesdk.sina.weibo.SinaWeibo;  
  20. import cn.sharesdk.tencent.qzone.QZone;  
  21. import cn.sharesdk.tencent.weibo.TencentWeibo;  
  22.   
  23. import com.yangyu.mysharethings.R;  
  24.   
  25. /** 
  26.  * @author yangyu 
  27.  *  功能描述:获取用户资料 
  28.  *  
  29.  * 启动页面时传递一个int类型的字段type,用于标记获取自己的资料(type = 0)还是别人的资料(type = 1)。 
  30.  * 如果尝试获取别人的资料,示例代码会获取不同平台Share SDK的官方帐号的资料。 
  31.  *  
  32.  * 如果资料获取成功,会通过{@link ShowInforPage}展示 
  33.  */  
  34. public class GetInforActivity  extends Activity implements Callback, OnClickListener, WeiboActionListener {  
  35.       
  36.     //定义标题栏布局对象  
  37.     private TitleLayout llTitle;  
  38.       
  39.     private Button sinaBt,renrenBt,qzoneBt,tengxunBt;  
  40.       
  41.     private Handler handler;  
  42.   
  43.     protected void onCreate(Bundle savedInstanceState) {  
  44.         super.onCreate(savedInstanceState);  
  45.                   
  46.         handler = new Handler(this);  
  47.           
  48.         setContentView(R.layout.activity_userinfo);  
  49.                       
  50.         initView();  
  51.           
  52.         initData();  
  53.                       
  54.     }  
  55.       
  56.     /** 
  57.      * 初始化组件 
  58.      */  
  59.     private void initView(){  
  60.         //得到标题栏对象  
  61.         llTitle = (TitleLayout) findViewById(R.id.llTitle);  
  62.   
  63.         //得到按钮对象  
  64.         sinaBt    = (Button) findViewById(R.id.btnSw);  
  65.         renrenBt  = (Button) findViewById(R.id.btnRr);  
  66.         qzoneBt   = (Button) findViewById(R.id.btnQz);  
  67.         tengxunBt = (Button) findViewById(R.id.btnTc);  
  68.           
  69.           
  70.     }  
  71.       
  72.     /** 
  73.      * 初始化数据 
  74.      */  
  75.     private void initData(){  
  76.         //标题栏设置返回按钮监听  
  77.         llTitle.getBtnBack().setOnClickListener(this);  
  78.         //设置标题栏的标题文本  
  79.         llTitle.getTvTitle().setText(R.string.get_my_info);  
  80.           
  81.         //设置监听  
  82.         sinaBt.setOnClickListener(this);  
  83.         renrenBt.setOnClickListener(this);  
  84.         qzoneBt.setOnClickListener(this);  
  85.         tengxunBt.setOnClickListener(this);  
  86.     }  
  87.       
  88.     /** 
  89.      * 点击按钮获取授权用户的资料 
  90.      */  
  91.     @Override  
  92.     public void onClick(View v) {  
  93.         if (v.equals(llTitle.getBtnBack())) {  
  94.             finish();  
  95.             return;  
  96.         }  
  97.           
  98.         String name = null;       
  99.           
  100.         switch (v.getId()) {  
  101.         case R.id.btnSw:  
  102.             name = SinaWeibo.NAME;  
  103.             break;  
  104.         case R.id.btnTc:  
  105.             name = TencentWeibo.NAME;  
  106.             break;  
  107.         case R.id.btnRr:  
  108.             name = Renren.NAME;  
  109.             break;  
  110.         case R.id.btnQz:  
  111.             name = QZone.NAME;  
  112.             break;  
  113.         }     
  114.           
  115.         if (name != null) {  
  116.             AbstractWeibo weibo = AbstractWeibo.getWeibo(this, name);  
  117.             weibo.setWeiboActionListener(this);  
  118.             String account = null;  
  119.               
  120.             weibo.showUser(account);  
  121.         }  
  122.     }  
  123.   
  124.     public void onComplete(AbstractWeibo weibo, int action,HashMap res) {  
  125.         Message msg = new Message();  
  126.         msg.arg1 = 1;  
  127.         msg.arg2 = action;  
  128.         msg.obj = weibo;  
  129.         handler.sendMessage(msg);  
  130.           
  131.         Message msg2 = new Message();  
  132.         msg2.what = 1;  
  133.         JsonUtils ju = new JsonUtils();  
  134.         String json = ju.fromHashMap(res);  
  135.         msg2.obj = ju.format(json);  
  136.         handler.sendMessage(msg2);  
  137.     }  
  138.   
  139.     public void onError(AbstractWeibo weibo, int action, Throwable t) {  
  140.         t.printStackTrace();  
  141.           
  142.         Message msg = new Message();  
  143.         msg.arg1 = 2;  
  144.         msg.arg2 = action;  
  145.         msg.obj = weibo;  
  146.         handler.sendMessage(msg);  
  147.     }  
  148.   
  149.     public void onCancel(AbstractWeibo weibo, int action) {  
  150.         Message msg = new Message();  
  151.         msg.arg1 = 3;  
  152.         msg.arg2 = action;  
  153.         msg.obj = weibo;  
  154.         handler.sendMessage(msg);  
  155.     }  
  156.   
  157.     /** 处理操作结果 */  
  158.     public boolean handleMessage(Message msg) {  
  159.         switch(msg.what) {  
  160.             case 1: {  
  161.                 Intent i = new Intent(this, ShowInforActivity.class);  
  162.                 i.putExtra("data", String.valueOf(msg.obj));  
  163.                 startActivity(i);  
  164.             }  
  165.             break;  
  166.             default: {  
  167.                 AbstractWeibo weibo = (AbstractWeibo) msg.obj;  
  168.                 String text = MainActivity.actionToString(msg.arg2);  
  169.                 switch (msg.arg1) {  
  170.                     case 1: { // 成功  
  171.                         text = weibo.getName() + " completed at " + text;  
  172.                     }  
  173.                     break;  
  174.                     case 2: { // 失败  
  175.                         text = weibo.getName() + " caught error at " + text;  
  176.                     }  
  177.                     break;  
  178.                     case 3: { // 取消  
  179.                         text = weibo.getName() + " canceled at " + text;  
  180.                     }  
  181.                     break;  
  182.                 }  
  183.                   
  184.                 Toast.makeText(this, text, Toast.LENGTH_SHORT).show();  
  185.             }  
  186.             break;  
  187.         }  
  188.         return false;  
  189.     }  
  190.   
  191.       
  192. }  

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

[java]  view plain copy
  1. package com.yangyu.activity;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.TextView;  
  8. import cn.sharesdk.framework.TitleLayout;  
  9.   
  10. import com.yangyu.mysharethings.R;  
  11.   
  12. /** 
  13.  * @author yangyu 
  14.  *  功能描述:显示用户信息资料 
  15.  */  
  16. public class ShowInforActivity  extends Activity implements OnClickListener {  
  17.     private TitleLayout llTitle;  
  18.   
  19.     protected void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.activity_show_userinfo);  
  22.           
  23.         llTitle = (TitleLayout) findViewById(R.id.llTitle);  
  24.         llTitle.getBtnBack().setOnClickListener(this);  
  25.         llTitle.getTvTitle().setText("用户资料");  
  26.           
  27.         TextView tvJson = (TextView) findViewById(R.id.tvJson);  
  28.         tvJson.setText(getIntent().getStringExtra("data"));  
  29.     }  
  30.       
  31.     @Override  
  32.     public void onClick(View v) {  
  33.         if (v.equals(llTitle.getBtnBack())) {  
  34.             finish();  
  35.         }     
  36.     }  
  37.   
  38. }  

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

[java]  view plain copy
  1. package com.yangyu.activity;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.Iterator;  
  6. import java.util.Map.Entry;  
  7. import org.json.JSONArray;  
  8. import org.json.JSONException;  
  9. import org.json.JSONObject;  
  10.   
  11. /** 
  12.  * @author yangyu 
  13.  *  功能描述:这是一个简易的Json-HashMap转换工具,可以将普通的json数据(字符串) 
  14.  *  转换为一个HashMap表格,也可以反过来操作。此外还支 
  15.  *  持将json数据格式化。 
  16.  */  
  17. public class JsonUtils {  
  18.       
  19.     /** 
  20.      * 将指定的json数据转成 HashMap对象 
  21.      */  
  22.     public HashMap fromJson(String jsonStr) {  
  23.         try {  
  24.             if (jsonStr.startsWith("[")  
  25.                     && jsonStr.endsWith("]")) {  
  26.                 jsonStr = "{\"fakelist\":" + jsonStr + "}";  
  27.             }  
  28.               
  29.             JSONObject json = new JSONObject(jsonStr);  
  30.             return fromJson(json);  
  31.         } catch (Throwable t) {  
  32.             t.printStackTrace();  
  33.         }  
  34.         return new HashMap();  
  35.     }  
  36.       
  37.     private HashMap fromJson(JSONObject json) throws JSONException {  
  38.         HashMap map = new HashMap();  
  39.         @SuppressWarnings("unchecked")  
  40.         Iterator iKey = json.keys();  
  41.         while(iKey.hasNext()) {  
  42.             String key = iKey.next();  
  43.             Object value = json.opt(key);  
  44.             if (JSONObject.NULL.equals(value)) {  
  45.                 value = null;  
  46.             }  
  47.             if (value != null) {  
  48.                 if (value instanceof JSONObject) {  
  49.                     value = fromJson((JSONObject)value);  
  50.                 }  
  51.                 else if (value instanceof JSONArray) {  
  52.                     value = fromJson((JSONArray)value);  
  53.                 }  
  54.                 map.put(key, value);  
  55.             }  
  56.         }  
  57.         return map;  
  58.     }  
  59.   
  60.     private ArrayList fromJson(JSONArray array)   
  61.             throws JSONException {  
  62.         ArrayList list = new ArrayList();  
  63.         for (int i = 0, size = array.length(); i < size; i++) {  
  64.             Object value = array.opt(i);  
  65.             if (value instanceof JSONObject) {  
  66.                 value = fromJson((JSONObject)value);  
  67.             }  
  68.             else if (value instanceof JSONArray) {  
  69.                 value = fromJson((JSONArray)value);  
  70.             }  
  71.             list.add(value);  
  72.         }  
  73.         return list;  
  74.     }  
  75.   
  76.     /** 
  77.      * 将指定的HashMap对象转成json数据  
  78.      */  
  79.     public String fromHashMap(HashMap map) {  
  80.         try {  
  81.             return getJSONObject(map).toString();  
  82.         } catch (Throwable t) {  
  83.             t.printStackTrace();  
  84.         }  
  85.         return "";  
  86.     }  
  87.       
  88.     @SuppressWarnings("unchecked")  
  89.     private JSONObject getJSONObject(HashMap map)   
  90.             throws JSONException {  
  91.         JSONObject json = new JSONObject();  
  92.         for (Entry entry : map.entrySet()) {  
  93.             Object value = entry.getValue();  
  94.             if (value instanceof HashMap) {  
  95.                 value = getJSONObject((HashMap)value);  
  96.             }  
  97.             else if (value instanceof ArrayList) {  
  98.                 value = getJSONArray((ArrayList)value);  
  99.             }  
  100.             json.put(entry.getKey(), value);  
  101.         }  
  102.         return json;  
  103.     }  
  104.       
  105.     @SuppressWarnings("unchecked")  
  106.     private JSONArray getJSONArray(ArrayList list)   
  107.             throws JSONException {  
  108.         JSONArray array = new JSONArray();  
  109.         for (Object value : list) {  
  110.             if (value instanceof HashMap) {  
  111.                 value = getJSONObject((HashMap)value);  
  112.             }  
  113.             else if (value instanceof ArrayList) {  
  114.                 value = getJSONArray((ArrayList)value);  
  115.             }  
  116.             array.put(value);  
  117.         }  
  118.         return array;  
  119.     }  
  120.       
  121.     /** 
  122.      * 格式化一个json串 
  123.      */  
  124.     public String format(String jsonStr) {  
  125.         try {  
  126.             return format("", fromJson(jsonStr));  
  127.         } catch (Throwable t) {  
  128.             t.printStackTrace();  
  129.         }  
  130.         return "";  
  131.     }  
  132.       
  133.     @SuppressWarnings("unchecked")  
  134.     private String format(String sepStr, HashMap map) {  
  135.         StringBuffer sb = new StringBuffer();  
  136.         sb.append("{\n");  
  137.         String mySepStr = sepStr + "\t";  
  138.         int i = 0;  
  139.         for (Entry entry : map.entrySet()) {  
  140.             if (i > 0) {  
  141.                 sb.append(",\n");  
  142.             }  
  143.             sb.append(mySepStr).append('\"').append(entry.getKey()).append("\":");  
  144.             Object value = entry.getValue();  
  145.             if (value instanceof HashMap) {  
  146.                 sb.append(format(mySepStr, (HashMap)value));  
  147.             }  
  148.             else if (value instanceof ArrayList) {  
  149.                 sb.append(format(mySepStr, (ArrayList)value));  
  150.             }  
  151. 你可能感兴趣的:(Android)