背景
估值APP中报告分享功能,QQ空间、QQ好友、微信、微信朋友圈四个需要支持正常跳转到对应的位置:QQ空间自动跳转到QQ空间的动态输入页面,QQ好友跳转至QQ好友列表,微信朋友圈跳转至微信朋友圈输入页面,微信跳转至微信好友列表,分享内容自动填充为报告完整图片,若用户未下载QQ或微信则点击分享隐藏对应入口。
技术方案选型
- 逐一集成:依次注册第三方社交平台,然后逐一下载对应的sdk和文档,进行集成。这种集成方式需要对接的平台很多,效率不高。而且因为技术含量不高,耗费时间长,所以显得冗余。
- 统一集成:将市场上常见的社交类软件全部做了集成,然后分装在一个sdk中,统一向开发者提供服务。做统一集成这类服务的公司有很多,比如:友盟,MobTech等。
最后选择友盟社会化分享SDK,因为友盟的功能相对更完善。支持国内外30+主流三方平台,国内:微信/QQ/微博/抖音/钉钉/企业微信、支付宝等13个平台。国外:Facebook、Twitter、Instagram等12个平台。分享形式:小程序、链接、文本、图片、视频等。
方案实现
集成友盟SDK需要经过几个步骤:
- 注册友盟账号并登录
- 后台创建应用,选择移动应用,并填写相关信息,获取到AppKey,供在项目中集成使用。
- 下载对应的SDK,并设置成为项目依赖库
- 填写Appkey等信息,在代码中做相应的集成
- 调用库功能API
注册友盟账号
新用户注册后的后台工作台,如下图所示。
添加新应用
首次使用友盟+的用户,需先创建应用获取Appkey。Appkey是应用在友盟+的唯一标识ID。例如注册app,填写相关信息,得到一个Appkey,
集成SDK
具体参考 分享安卓端接入指南
自动集成(gradle在线依赖)
集成SDK有两种方式,既可以通过maven线上接入sdk,也可以手动下载SDK,网络环境允许的情况下,都推荐自动集成。
- 在工程 build.gradle 配置脚本中 buildscript 和 allprojects 段中添加 sdk maven 仓库地址
mavenCentral()
maven {url'https://maven.aliyun.com/nexus/content/groups/public/'}
maven {url 'https://www.idescout.com/maven/repo/'}
- 集成组件化各业务SDK,分享SDK版本:>= v7.1.0,最新版本:版本v7.3.4(2024-6-27),
版本v7.3.3(2023-12-14)
dependencies {
// 友盟基础组件库(所有友盟业务SDK都依赖基础组件库
implementation 'com.umeng.umsdk:common:+'// 必选
implementation 'com.umeng.umsdk:asms:+'// 必选
implementation 'com.umeng.umsdk:link:+'//集成U-Link,可选,如要统计分享回流次数和分享新增用户指标则必选
implementation 'com.umeng.umsdk:share-core:+'//分享核心库,必选
//在线依赖目前支持QQ、微信、新浪微博、支付宝、钉钉、抖音;若需支持其他平台,请选择手动下载SDK
implementation 'com.umeng.umsdk:share-wx:+' //微信完整版
implementation 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.24' //微信官方依赖库
implementation 'com.umeng.umsdk:share-qq:+' //QQ完整版
implementation files('libs/open_sdk_3.5.16.4_r8c01346_lite.jar') //QQ官方依赖库
}
友盟官方提供了gradle在线依赖方式的三合一Demo,开发者可以参考:MultiFunctionAndroidMavenDemo-master
自动集成完成后可以直接跳到添加回调Activity一节
添加回调Activity
微信在包名目录下创建wxapi文件夹,新建一个名为WXEntryActivity
的activity继承WXCallbackActivity
QQ与新浪QQ与新浪不需要添加Activity,但需要在使用QQ分享或者授权的Activity中,添加:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);
}
注意onActivityResult
不可在fragment中实现,如果在fragment中调用登录或分享,需要在fragment依赖的Activity中实现
钉钉与微信相似,钉钉需要在包名目录下创建ddshare文件夹,然后建立一个DDShareActivity的类,DingCallBack
创建第三方平台应用
大部分社交平台进行分享、登录操作首先需要在第三方平台创建应用并提交审核,创建应用后,分享、登录操作时显示的应用icon、名称和对应开放平台设置有关,必须要创建应用的平台为:微信、QQ、新浪、钉钉、企业微信、支付宝、Facebook、Kakao、LinkeIn、Twitter,创建应用方法请参考文档
配置Android Manifest XML
创建完第三方平台应用后,还需要进行一些配置。以下是部分社交平台需要进行的配置
微信
需要在工程AndroidManifest.xml清单文件中增加:
<activity
android:name=".wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
微信分享模块还需要在工程AndroidManifest.xml清单文件中增加provider标签配置
注意:对应authorities属性值请结合您自己包名自行定义,不要直接使用Umeng Demo工程中属性值com.tencent.sample2.fileprovider。
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths "/>
</provider>
重要
provider对应authorities属性值不可以自定义,必须是android:authorities=”${applicationId}.fileprovider”
微信分享模块集成时除了要配置工程AndroidManifest.xml清单文件之外,还需要在res/xml目录(如果没有xml目录,则新建一个)下,添加文件filepaths.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path name="opensdk_root" path=""/>
<external-files-path name="umeng_cache" path="umeng_cache/"/>
</paths>
重要
从Android 11开始,必须要在AndroidManifest.xml清单文件中加入query权限申请,才能检测到手机上安装的三方应用包安装状态,否则会出现“错误码2008:没有安装应用”、“请先安装微信/QQ/微博/企业微信/钉钉/支付宝客户端”等现象。
需要在主工程的AndroidManifest.xml 中增加标签,代码如下:
<manifest package="com.example.app">
...
// 在应用的AndroidManifest.xml添加如下<queries>标签
<queries>
<package android:name="com.tencent.mm" /> // 指定微信包名
<package android:name="com.tencent.mobileqq" /> //指定qq包名
<package android:name="com.sina.weibo" /> //指定微博包名
<package android:name="com.tencent.wework" /> //指定企业微信包名
<package android:name="com.qzone" /> //指定QQ空间包名
<package android:name="com.alibaba.android.rimet" /> // 指定钉钉包名
<package android:name="com.eg.android.AlipayGphone" /> // 指定支付宝包名
<package android:name="com.instagram.android" /> // 指定instagram包名
<package android:name="com.ss.android.ugc.aweme" /> // 指定抖音包名
</queries>
...
</manifest>
分享v7.2.0 SDK中的QQ SDK版本是v3.5.12,需要调用授权api才可以正常使用授权和分享功能
//QQ官方sdk授权
Tencent.setIsPermissionGranted(true);
需要在工程AndroidManifest.xml清单文件中增加以下参数:
请注意将我们的qq appkey替换成您自己的qq appkey。对应authorities属性值请结合您自己包名自行定义,不要直接使用Umeng Demo工程中属性值com.tencent.sample2.fileprovider。
<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" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
分享v7.2.0SDK依赖QQ官方SDKv3.5.12,集成时除了要配置工程AndroidManifest.xml清单文件之外,还需要同时需要在工程res目录下新建filepaths.xml配置。
<!-- QQ 官方分享SDK 共享路径 -->
<root-path name="opensdk_root" path=""/>
<external-files-path name="opensdk_external" path="Images/tmp"/>
QQ官方SDK v3.3.8.lite及以上依赖特定android v4 support包,请将工程中依赖的android-support-v4.jar版本升级到23以上。例如:将其升级到 android-support-v4 23.4.0。
重要
同时集成微信,QQ,新浪微博、钉钉等平台只需配置一组provider,不要重复配置,但是微信、QQ和新浪微博每个平台都需要进行配置filepaths文件
权限添加
在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.INTERNET"/>
纯图分享权限如果需要使用QQ纯图分享或避免其它平台纯图分享的时候图片不被压缩,可以增加以下权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Android6.0权限适配请查看你的build.gradle
文件,如果 targetSdkVersion
小于或等于22,可以忽略这一步,如果大于或等于23,需要做权限的动态申请:
if (Build.VERSION.SDK_INT>=23) {
String[] mPermissionList = newString[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE };
ActivityCompat.requestPermissions(this, mPermissionList, 123);
}
其中123是requestcode,可以根据这个code判断,用户是否同意了授权。如果没有同意,可以根据回调进行相应处理:
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[],int[] grantResults) {}
初始化设置
初始化需要在您的Application中调用我们的初始化接口,这里的appkey请替换成后台应用的appkey:
@Override
public void onCreate(){
super.onCreate();
UMConfigure.init(this, "xxx", "umeng", UMConfigure.DEVICE_TYPE_PHONE, "");
}
更多了解初始化接口可以参照统计SDK文档初始化及通用接口部分内容,init接口调用时机请参考合规指南
接下来需要在Application中设置各个平台的appkey:
重要
设置微信、微博、QQ等平台时,请将友盟Demo包名com.tencent.sample2
更换成您自己的项目包名
// 微信设置
PlatformConfig.setWeixin("wxdc1e388c3822c80b","3baf1193c85774b3fd9d18447d76cab0");
PlatformConfig.setWXFileProvider("com.tencent.sample2.fileprovider");
// QQ设置
PlatformConfig.setQQZone("101830139","5d63ae8858f1caab67715ccd6c18d7a5");
PlatformConfig.setQQFileProvider("com.tencent.sample2.fileprovider");
// 新浪微博设置
PlatformConfig.setSinaWeibo("3921700954","04b48b094faeb16683c32669824ebdad","http://sns.whalecloud.com");
PlatformConfig.setSinaFileProvider("com.tencent.sample2.fileprovider");
//钉钉设置
PlatformConfig.setDing("dingoalmlnohc0wggfedpk");
PlatformConfig.setDingFileProvider("com.tencent.sample2.fileprovider");
//抖音设置
PlatformConfig.setBytedance("awd1cemo6d0l69zp","awd1cemo6d0l69zp","a2dce41fff214270dd4a7f60ac885491",FileProvider);
// 企业微信设置
PlatformConfig.setWXWork("wwac6ffb259ff6f66a","EU1LRsWC5uWn6KUuYOiWUpkoH45eOA0yH-ngL8579zs","1000002","wwauthac6ffb259ff6f66a000002");
PlatformConfig.setWXWorkFileProvider("com.tencent.sample2.fileprovider");
//荣耀设置
PlatformConfig.setHonor("appid", "app_secret");
重要
Android11要调用PlatformConfig.setWXFileProvider、PlatformConfig.setQQFileProvider和PlatformConfig.setDingFileProvider等等,否则分享本地图片到微信、QQ、微博和钉钉等平台会失败
重要
新浪微博必须统一设置为PlatformConfig.setSinaFileProvider(应用包名.fileprovider);
企业微信的参数需要开发者登录企业微信管理后台 work.weixin.qq.com/ 进行查看。填写的四个参数分别为:参数1:id (我的企业 企业ID),参数2:Secret (应用管理->你的应用名 Secret),参数3:AgentId(应用管理->你的应用名 AgentId),参数4:schema (应用管理->企业微信授权登录->Android schema)
签名配置
签名的概念将文件夹中的签名文件放入到工程中,例如我的签名文件是debug.keystore,然后增加签名文件的密码:
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}
然后在buildTypes中将这个signingConfigs配置进去,签名文件如果不加,部分平台的授权会受到影响。
说明
混淆设置
第三方的sdk一般都要加混淆保护,按照说明文档添加即可。请务必在混淆时增加:-keep class com.uc.** {*;}
-dontshrink
-dontoptimize
-dontwarn com.google.android.maps.**
-dontwarn com.squareup.okhttp.**
-dontwarn android.webkit.WebView
-dontwarn com.umeng.**
-dontwarn com.tencent.weibo.sdk.**
-dontwarn com.facebook.**
-keep public class javax.**
-keep public class android.webkit.**
-dontwarn android.support.v4.**
-keep enum com.facebook.**
-keepattributes Exceptions,InnerClasses,Signature
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-keepattributes EnclosingMethod
-keep public interface com.facebook.**
-keep public interface com.tencent.**
-keep public interface com.umeng.socialize.**
-keep public interface com.umeng.socialize.sensor.**
-keep public interface com.umeng.scrshot.**
-keep public class com.umeng.socialize.* {*;}
-keep class com.umeng.commonsdk.statistics.common.MLog {*;}
-keep class com.umeng.commonsdk.UMConfigure {*;}
-keep class com.umeng.** {*;}
-keep class com.umeng.**
-keep class com.facebook.**
-keep class com.facebook.** { *; }
-keep class com.umeng.scrshot.**
-keep public class com.tencent.** {*;}
-keep class com.umeng.socialize.sensor.**
-keep class com.umeng.socialize.handler.**
-keep class com.umeng.socialize.handler.*
-keep class com.umeng.weixin.handler.**
-keep class com.umeng.weixin.handler.*
-keep class com.umeng.qq.handler.**
-keep class com.umeng.qq.handler.*
-keep class UMMoreHandler{*;}
-keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;}
-keep class com.tencent.mm.sdk.** {
*;
}
-keep class com.tencent.mm.opensdk.** {
*;
}
-keep class com.tencent.wxop.** {
*;
}
-keep class com.tencent.mm.sdk.** {
*;
}
-dontwarn twitter4j.**
-keep class twitter4j.** { *; }
-keep class com.tencent.** {*;}
-dontwarn com.tencent.**
-keep class com.kakao.** {*;}
-dontwarn com.kakao.**
-keep public class com.umeng.com.umeng.soexample.R$*{
public static final int *;
}
-keep public class com.linkedin.android.mobilesdk.R$*{
public static final int *;
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class com.tencent.open.TDialog$*
-keep class com.tencent.open.TDialog$* {*;}
-keep class com.tencent.open.PKDialog
-keep class com.tencent.open.PKDialog {*;}
-keep class com.tencent.open.PKDialog$*
-keep class com.tencent.open.PKDialog$* {*;}
-keep class com.umeng.socialize.impl.ImageImpl {*;}
-keep class com.sina.** {*;}
-dontwarn com.sina.**
-keep class com.alipay.share.sdk.** {
*;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keep class com.linkedin.** { *; }
-keep class com.android.dingtalk.share.ddsharemodule.** { *; }
-keepattributes Signature