文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2022-06-06 06:58

关注

由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字和图片等这样的效果,几经波折,查阅了一番资料,做了一个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://open.weibo.com 
      腾讯微博:http://dev.t.qq.com 
      QQ空间: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.com 
      Instapaper:http://www.instapaper.com/main/request_oauth_consumer_token 
      有道云笔记:http://note.youdao.com/open/developguide.html#app 
      facebook:https://developers.facebook.com 
      twitter:https://dev.twitter.com 
      搜狐随身看:https://open.sohu.com 
      QQ好友分享:http://mobile.qq.com/api/ 
      微信:http://open.weixin.qq.com--> 
  <ShareSDK  
    AppKey = "api20"/> <!-- AppKey="104972cdd48" "23a9371d3a8"--> 
  <SinaWeibo 
    SortId="1" 
    AppKey="3201194191" 
    AppSecret="0334252914651e8f76bad63337b3b78f" 
    Id="1" 
    RedirectUrl="http://appgo.cn" /> 
  <TencentWeibo 
    SortId="2" 
    AppKey="801307650" 
    AppSecret="ae36f4ee3946e1cbb98d6965b0b2ff5c" 
    RedirectUri="http://sharesdk.cn" 
    Id="2" /> 
  <QZone 
    SortId="3" 
    AppId="100371282" 
    AppKey="aed9b0303e3ed1e27bae87c33761161d" 
    Id="3" 
    RedirectUrl="http://www.shareSDK.cn" /> 
  <Renren 
    SortId="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:


<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="http://schemas.android.com/apk/res/android" 
  xmlns:tools="http://schemas.android.com/tools" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" > 
  <Button 
    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"/> 
  <Button 
    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" /> 
  <Button 
    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" /> 
  <Button 
    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="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.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="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.TitleLayout 
    android:id="@+id/llTitle" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="@drawable/title_back" /> 
      <Button 
        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" /> 
      <Button 
        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" /> 
      <Button 
        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" /> 
      <Button 
        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="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.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" > 
    <TextView 
      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.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; 
 
public class MainActivity extends Activity implements OnClickListener { 
  //定义图片存放的地址 
  public static String TEST_IMAGE; 
  //定义"账号登陆"按钮,"有分享界面按钮","无分享界面"按钮,"得到用户资料"按钮 
  private Button authLoginBtn,shareGuiBtn,shareBtn,getInfoBtn; 
  @Override 
  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"; 
      } 
      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; 
    } 
  } 
   
  @Override 
  public 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); 
  } 
   
  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:
 


 <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" /> 
    <activity 
      android: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; 
 
public class AuthActivity extends Activity implements Callback, OnClickListener, WeiboActionListener { 
  //定义CheckedTextView对象 
  private CheckedTextView sinaCt,qzoneCt,tengxunCt,renrenCt; 
  //定义Handler对象 
  private Handler handler; 
  //定义标题栏对象 
  private TitleLayout llTitle; 
  @Override 
  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);    
    //得到组件对象 
    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() {      
      @Override 
      public 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); 
      } 
    } 
  } 
   
  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); 
  } 
   
  @Override 
  public 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; 
  }     
   
  @Override 
  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);     
  } 
   
  @Override 
  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);   
  } 
   
  @Override 
  public void onCancel(AbstractWeibo weibo, int action) { 
    Message msg = new Message(); 
    msg.arg1 = 3; 
    msg.arg2 = action; 
    msg.obj = weibo; 
    handler.sendMessage(msg);   
  } 
   
  @Override 
  public 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; 
 
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); 
  } 
   
  @Override 
  public 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; 
 
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")); 
  } 
  @Override 
  public 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; 
 
public class JsonUtils { 
   
  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; 
  } 
   
  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; 
  } 
   
  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第三方登录之QQ登录Android第三方登录之腾讯QQ登录的实例代码Android实现第三方登录的上拉展开,下拉隐藏,下拉隐藏示例Android微信第三方登录(个人笔记)微信第三方登录Android实现代码Android 第三方登录、分享(ShareSDK、友盟)Android集成新浪微博第三方登录的方法Android调用第三方QQ登录代码分享React Native第三方平台分享的实例(Android,IOS双平台)Android实现QQ的第三方登录和分享


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯