Android 友盟社会化分享的集成与封装

分享是APP中非常高频的操作之一,在Android的开发环境中,第三方分享框架也有很多。比较流行的包括 极光社会化分享(sharesdk)、友盟社会化分享(Ushare)、Mob社会化分享以及在githut上比较流行的 ShareSDKShareUtilBiliShareShareLoginLib等等。 本篇文章基于友盟ShareSDK,介绍了其集成过程并对其进行模块化封装,以便在项目中更快捷的集成和使用。

集成前准备

  1. 获取友盟Appkey

    在【友盟+】官网注册并且添加新应用,获得Appkey。友盟后台的应用名与实际应用名和包名无关,建议命名为应用名+平台(iOS/Android),Android和IOS两个平台不能进行共用,需要进行分开。 建议使用企业邮箱注册,避免使用个人邮箱注册。

    获取友盟Appkey

  1. 三方账号申请

    因为涉及到和各个分享平台的交互,所以在集成前需要在各个平台创建应用并提交审核。创建应用后,分享、登录操作时显示的应用icon、名称和对应开放平台设置有关,必须要创建应用的平台为:微信、新浪、QQ、Facebook、Kakao、LinkeIn、Twitter、钉钉。

    目前集成的内容只包含微信、新浪、QQ三个平台,申请渠道如下:

    | 平台 | 申请地址 | | :----------: | :------------------------: | | 微信开放平台 | http://open.weixin.qq.com/ | | QQ互联平台 | http://connect.qq.com/ | | 微博开放平台 | http://open.weibo.com |

    注1:申请QQ登录一定要在QQ互联平台,不是在QQ开放平台(open.qq.com)

    注2:申请过程中可能需要企业相关资质,如法人身份证、营业执照、税务登记证等,需要提前准备好。

    注3:提交应用申请时,需要提交应用相关的信息(应用名称、介绍、图标、截图、授权回调域等),微信还需要提交《微信开放平台网站信息登记表》。

    注4: 建议大家用企业账号申请第三方开放平台,不要使用个人的QQ、微信、微博和邮箱进行申请,这样可以避免申请人在职位变动或者离职后,导致账号管理的风险和交接麻烦。

    注5:开放平台申请多数需要审核流程,因此在项目开始时,建议首先申请开放平台账号和创建应用,以免申请时间长影响开发进度。

    申请很复杂,所以一般直接找产品经历要就好啦(#笑)。如果是练习用的话,可以直接用官方Demo的包名com.umeng.soexample创建一个示例项目,沿用签名文件、Appkey以及各个三方的Appkey就好了。

集成友盟sdk

在后期模块化后,直接引入封装好的模块即可集成,这里先介绍一下通过添加sdk的方式集成,以及其中我遇到过的问题。

  1. 下载SDK

    最新SDK地址,可以看到友盟的分享包含很多平台,这里我们只用到了微博微信QQ的分享和登录功能,不包含支付等,所以选择默认下载的三个精简版即可。如有需求可以参考官方开发文档添加使用。

  1. 添加SDK

    解压下载的sdk压缩包,我们需要用到其中common和share文件夹下的内容。res顾名思义都是资源文件,复制到项目的res目录中,其他所有jar文件复制到项目的app/libs目录下,并确保在app的gradle依赖中包含implementation fileTree(include: ['*.jar'], dir: 'libs') ,将这个文件夹中所有jar包导入到项目里。

  2. 添加回调Activity

    用到的三个平台中,只有微信需要手动添加Activity。具体做法是,在包名目录下创建wxapi文件夹,新建一个名为WXEntryActivity的Activity继承WXCallbackActivity ,内容为空即可。

  3. 配置Android Manifest XML

    在项目的Manifest中添加各个回调Activity:

    <activity
        android:name=".wxapi.WXEntryActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:exported="true"
        android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    <activity
        android:name="com.umeng.socialize.media.WBShareCallBackActivity"
        android:configChanges="keyboardHidden|orientation"
        android:exported="false"
        android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
    <activity
        android:name="com.sina.weibo.sdk.web.WeiboSdkWebActivity"
        android:configChanges="keyboardHidden|orientation"
        android:exported="false"
        android:windowSoftInputMode="adjustResize"></activity>
    <activity
        android:name="com.sina.weibo.sdk.share.WbShareTransActivity"
        android:launchMode="singleTask"
        android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
        <intent-filter>
            <action android:name="com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    
    </activity>
    <activity
        android:name="com.tencent.tauth.AuthActivity"
        android:launchMode="singleTask"
        android:noHistory="true">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="tencent100424468" />
        </intent-filter>
    </activity>
    <activity
        android:name="com.tencent.connect.common.AssistActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:theme="@android:style/Theme.Translucent.NoTitleBar" />

    其中qq的appkey需要替换成自己申请的appkey,这里用的是友盟官方demo的以作测试用。

  4. 添加权限

    在AndroidManifest中添加以下权限:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

    如果项目的目标sdk版本高于Android6.0,即 targetSdkVersion >= 23 ,还需要在项目中添加权限的动态申请:

    if (Build.VERSION.SDK_INT >= 23) {
        String[] mPermissionList = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CALL_PHONE, Manifest.permission.READ_LOGS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.SET_DEBUG_APP, Manifest.permission.SYSTEM_ALERT_WINDOW, Manifest.permission.GET_ACCOUNTS, Manifest.permission.WRITE_APN_SETTINGS};
        ActivityCompat.requestPermissions(this, mPermissionList, 123);
    }
  5. 初始化设置

    将前面的都集成之后,接下来就可以正式进入到代码层面的操作啦。在Application中调用友盟的初始化接口,以及设置各个平台的appkey,这里全部用的是官方demo测试用的appkey。

    public class App extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            //初始化组件化基础库, 统计SDK/推送SDK/分享SDK都必须调用此初始化接口
            UMConfigure.init(this, "5bed13e1f1f5564655000404", "Umeng", UMConfigure.DEVICE_TYPE_PHONE,
                    "d9352161be267fb40fb12ad5eb04edf9");
            UMShareAPI.get(this);
        }
    
        //各个平台的配置
        {
            //微信
            PlatformConfig.setWeixin("wxdc1e388c3822c80b", "3baf1193c85774b3fd9d18447d76cab0");
            //新浪微博(第三个参数为回调地址)
            PlatformConfig.setSinaWeibo("3921700954", "04b48b094faeb16683c32669824ebdad", "http://sns.whalecloud.com");
            //QQ
            PlatformConfig.setQQZone("100424468", "c7394704798a158208a74ab60104f0ba");
            PlatformConfig.setYixin("yxc0614e80c9304c11b0391514d09f13bf");
            PlatformConfig.setTwitter("3aIN7fuF685MuZ7jtXkQxalyi", "MK6FEYG63eWcpDFgRYw4w9puJhzDl0tyuqWjZ3M7XJuuG7mMbO");
            PlatformConfig.setAlipay("2015111700822536");
            PlatformConfig.setLaiwang("laiwangd497e70d4", "d497e70d4c3e4efeab1381476bac4c5e");
            PlatformConfig.setPinterest("1439206");
            PlatformConfig.setKakao("e4f60e065048eb031e235c806b31c70f");
            PlatformConfig.setDing("dingoalmlnohc0wggfedpk");
            PlatformConfig.setVKontakte("5764965", "5My6SNliAaLxEm3Lyd9J");
            PlatformConfig.setDropbox("oz8v5apet3arcdy", "h7p2pjbzkkxt02a");
    
        }
    }
  6. 添加签名文件

    部分平台在申请appkey的时候就需要项目的签名文件,如果没有的话会影响授权。常规项目只要正常申请好签名就可以了,这里讲一下作为测试用例如何添加签名。

    将官方demo中app目录下的debug.keystore复制到自己的练习项目app目录下

    在项目的app.gradle依赖中android条目下添加如下代码:

    buildTypes {
        release {
            // 是否进行混淆
            minifyEnabled false
            // 签名文件
            signingConfig signingConfigs.debug
            // 混淆文件的位置
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
            signingConfig signingConfigs.debug
            proguardFiles 'proguard-rules.pro'
        }
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword "android"
            keyAlias "androiddebugkey"
            keyPassword "android"
        }
    }

开始分享

终于到了分享的步骤,是骡子是马要牵出来溜溜看看能不能走了,先介绍一下友盟分享的两种形式:

平台 授权 可分享内容 用户信息
qq 文本 图片 链接 视频 音乐
qq空间 同qq 文字(说说) 图片(说说) 链接 视频 音乐 同qq
微信 文本 图片 链接 视频 音乐
微信朋友圈 同微信 文本 图片 链接 视频 音乐 (分享链接不显示描述) 同微信
微信收藏 同微信 文本 图片 链接 视频 音乐 文件 同微信
新浪微博 文本 图片 链接 视频 音乐 文件

下面以直接分享一个网站到微信平台为例,看一下具体的代码实现:

  UMWeb web = new UMWeb("https://gank.io/");//创建要分享的Web对象,传入分享的url地址
  web.setTitle("测试分享标题");//设置标题
  web.setThumb(new UMImage(this, R.drawable.thumb));//设置传入显示的缩略图
  web.setDescription("测试分享内容测试分享内容测试分享内容测试分享内容测试分享内容");//设置描述
  new ShareAction(ShareDetailActivity.this)//开启分享
                  .withMedia(web) //填入创建好的分享内容
                  .setPlatform(SHARE_MEDIA.WEIXIN)//选择分享平台
                  .setCallback(shareListener)//设置对分享返回结果的监听
                  .share();//启动分享操作

实现效果如下:

以面板的形式分享这个网站:

  ShareBoardlistener boardListener = new ShareBoardlistener() { //创建面板的监听器
      @Override
      public void onclick(SnsPlatform snsPlatform, SHARE_MEDIA platform) {
          new ShareAction(mActivity)//开启分享
                  .withMedia(web) //填入创建好的分享内容
                  .setPlatform(platform)//填入选择的平台
                  .setCallback(shareListener)//设置对分享返回结果的监听
                  .share();//启动分享操作
      }
  };
  new ShareAction(mActivity)
          .setDisplayList(SHARE_MEDIA.WEIXIN, SHARE_MEDIA.WEIXIN_CIRCLE, SHARE_MEDIA.WEIXIN_FAVORITE,
                  SHARE_MEDIA.SINA, SHARE_MEDIA.QQ, SHARE_MEDIA.QZONE)//设置分享面板显示的平台
          .setShareboardclickCallback(boardListener)//添加之前创建的面板监听器
          .open(config);//开启分享面板 其中可传入能对面板样式进行自定义操作的config对象    
          //比如设置面板在底部还是中部显示、是否有取消按钮、图标形状、字体大小和背景颜色等等

默认居中的面板效果如下:

最后不要忘记在调用分享的Activity中,添加如下代码,关闭监听,防止内存泄露等问题。

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);
  }
  @Override
      protected void onDestroy() {
          super.onDestroy();
          UMShareAPI.get(this).release();
      }

对友盟分享的模块化和代码封装

在前面的内容里,我们完整的体验了友盟社会化分享的准备、集成和使用,虽然看起来比较简单明了,但对于初次接触的人还是比较容易碰到问题的,在项目中多次集成也比较繁琐。所以接下来到了本文的重点内容,对友盟的分享进行模块化,在需要时直接导入模块即可使用,并将主要方法进行封装处理,在开发时提高效率,减少代码量。

下面记录一下封装过程中的思路和过程,以及封装后的使用方法。