引言:最近团队项目要用到qq,微信,微博的分享,要求不用第三方集成框架,所以为了以后的方便,花时间自己集成了一个三大平台最新sdk的分享框架
本项目是自己做的一个简单小项目,有兴趣看看的人如果发现有什么使用问题或者有发现哪里不对的地方希望大家指出,避免我的项目上线后出现一些不必要的bug,感谢
1.在做分享前要现在三大平台注册应用,然后获取三大平台的appid,微博为apikey。
微博注册时有个问题:那就是要线上应用,必须要在应用市场有app,不然不能注册,不知道是我没找到注册方法还是怎么回事
2.下载三大平台最新sdk jar包,android studio开发用户可只下qq的sdkjar包,微信,微博可直接在gradle集成:
微信:compile ‘com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+’
微博:compile ‘com.sina.weibo.sdk:core:2.0.3:openDefaultRelease@aar’
微博集成还要在项目的根目录下添加:
repositories {
jcenter()
maven { url "https://dl.bintray.com/thelasterstar/maven" }
}
allprojects {
repositories {
jcenter()
maven { url "https://dl.bintray.com/thelasterstar/maven" }
}
}
文档地址:
qq:qq文档
微信:微信文档
微博:微博文档
QQ分享主要依赖于Tencent,通过注册的app_id和上下文进行初始化
@Override
public void onCreate(Activity activity, QQ sharForm) {
tencent = Tencent.createInstance(sharForm.getAppKey(), activity);
}
QQ分享传入的参数为Bundle对象,通过查看源码,发现次Bundle并不是用于Intent跳转页面的数据传输,只是纯粹的数据拼装,通过bundle数据
private void b(Activity var1, Bundle var2, IUiListener var3) {
f.c("openSDK_LOG.QQShare", "doShareToQQ() -- start");
StringBuffer var4 = new StringBuffer("mqqapi://share/to_fri?src_type=app&version=1&file_type=news");
String var5 = var2.getString("imageUrl");
String var6 = var2.getString("title");
String var7 = var2.getString("summary");
String var8 = var2.getString("targetUrl");
String var9 = var2.getString("audio_url");
int var10 = var2.getInt("req_type", 1);
int var11 = var2.getInt("cflag", 0);
....
Intent var19 = new Intent("android.intent.action.VIEW");
var19.setData(Uri.parse(var4.toString()));
var19.putExtra("pkg_name", var1.getPackageName());
....
}
Bundle参数含义:
QQShare.SHARE_TO_QQ_KEY_TYPE //分享类型 QQShare.SHARE_TO_QQ_TYPE_DEFAULT 图文分享
QQShare.SHARE_TO_QQ_TYPE_IMAGE 纯图片分享
QQShare.SHARE_TO_QQ_TYPE_AUDIO 音乐分享
QQShare.SHARE_TO_QQ_TITLE //分享的标题
QQShare.SHARE_TO_QQ_TARGET_URL //分享点击后跳转地址
QQShare.SHARE_TO_QQ_SUMMARY //分享摘要
QQShare.SHARE_TO_QQ_IMAGE_URL //分享网络地址
QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL //分享的 本地地址
QQShare.SHARE_TO_QQ_APP_NAME //手Q客户端顶部,替换“返回”按钮文字,如果为空,用返回代替
QQShare.SHARE_TO_QQ_EXT_INT // 分享类型 默认是QQ好友分享
QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN 为QQ控件分享
注意:本地图片地址与网络图片地址必须区分开
QQ分享必须重写 Tencent.onActivityResultData(requestCode, resultCode, data, null); 否则分享没有返回
QQ分享必须执行在主线程,官方写法:
/**
* 分享
* @param bundle 内容
*/
private void shareToMainThread(final Bundle bundle, final ShareListener shareListener) {
ThreadManager.getMainHandler().post(new Runnable() {
@Override
public void run() {
tencent.shareToQQ(activity, bundle, new MyIUiListener(shareListener));
}
});
}
qq分享必须要在manifest文件里面注册QQ自己对的Activity
在本项目中QQ分享只需要传入app_id
ShareConfig.setQQ(“222222”);
再通过单例入口类 ShareApi 进行分享,通过share 方法传入要分享的数据:
图文分享:ShareQQTextImageDao
音乐分享:ShareQQMusicDao
纯图片分享:ShareQQImageDao
ShareApi 具体用发参考后面给出的类文档。
微信分享主要依赖于IWXAPI ,通过微信的App_id和上下文进行初始化:
@Override
public void onCreate(Activity activity,Weixin sharForm){
api = WXAPIFactory.createWXAPI(activity, sharForm.getAppKey());
api.registerApp(sharForm.getAppKey());
}
微信分享通过api.sendReq(req) 方法进行分享,传入SendMessageToWX.Req对象
微信分享分成了很多种,有文字,图片,音乐,视频,web分享等。
同过SendMessageToWX.Req对象的message属性的mediaObject对象属性确定。
WXMediaMessage 对象是SendMessageToWX.Req的message属性
WXMediaMessage 对象的mediaObject 的不同,确定不同的分享类型 WXTextObject 文本分享,
WXImageObject 图片分享,WXMusicObject 音乐分享,WXVideoObject 视频分享
WXWebpageObject 网页分享
注意:微信分享必须在项目包名下面创建wxapi包,并创建WXEntryActivity 来作为微信分享的回调事件处理,否则微信分享将不成功。manifest注册:
在本项目中 微信分享只需要传入app_key ,传入方式:
ShareConfig.setWeiXin(“xxxxxx”);
再通过单例入口类 ShareApi 进行分享,通过share 方法传入要分享的数据:
ShareWXTextDao 文字分享
ShareWXImageDao 图片分享
ShareWXMusicDao 音乐分享
ShareWXVideoDao 视频分享
ShareWXWebDao 网页分享
ShareApi 具体用发参考后面给出的类文档。
注意:在library项目中已经写了WXEntryActivity 类,不需要再在自己的项目包名下面创建了,只需要在自己项目的manifest里面注册library工程的WXEntryActivity ,并指定别名就行了。具体操作:
//指定别名 必须先注册com.dzm.jcenter.share.share.wx.WXEntryActivity
新版本微博分享api主要依赖于WbShareHandler类,初始化方法:
@Override
public void onCreate(Activity activity, WeiBo sharForm) {
shareHandler = new WbShareHandler(activity);
//发送广播
shareHandler.registerApp();
}
在微博分享时需要注意:
需要在最开始时调用WbSdk.install(Context context, AuthInfo info)方法初始化一些内部参数。
官方给出最好在Application或者MainActivity中初始化,AuthInfo 构造函数传入三个参数:
AuthInfo(Context context, String appKey, String redirectUrl, String scope)
第一个:注册的key
第二个:SCOPE 为使用权限
第三个:REDIRECT_URL 为回调页,可写死https://api.weibo.com/oauth2/default.html
微博分享类型:
微博分享有图片,文字,web,和前面三个混合在一起的分享模式:
通过 shareHandler.shareMessage(WeiboMultiMessage message, boolean clientOnly)方法进行分享。
WeiboMultiMessage 里面有三个参数对象,分别对应:图片,文字,web分享。
TextObject 文字分享
ImageObject 图片分型
WebpageObject web 分享
注意:
官方文档给出新版微博分享api要在activity中进行分享才能拿到回调事件
在本项目中微博分享要传入两个或三个参数,及AuthInfo中传入的是三个参数:
ShareConfig.setWeiBo(Constants.APP_KEY,Constants.SCOPE,Constants.REDIRECT_URL);
第一个:注册的key
第二个:SCOPE 为使用权限
第三个:REDIRECT_URL 为回调页,可写死https://api.weibo.com/oauth2/default.html
再通过单例入口类 ShareApi 进行分享,通过share 方法传入要分享的数据:
ShareWbImageDao 图片分享
ShareWbMediaDao web分享
ShareWbTextDao 文本分享
ShareWbMixDao 混合分享
ShareApi 具体用发参考后面给出的类文档。
注意:因为前面提到的微博分享要在activity中进行,所以在进行微博分享时我做了一些调整,在library项目中创建一个透明的activity:WbShareCallbackActivity 当通过ShareApi 的share方法分享微博时拉起这个透明的activity
if(shareType == ShareType.WEIBO){
share.setShareListener(shareListener);
Intent intent = new Intent(context, WbShareCallbackActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable(WbShareCallbackActivity.DZM_DATA,shareDao);
intent.putExtras(bundle);
context.startActivity(intent);
}else{
share.share(shareDao,shareListener);
}
并将分享的数据传到activity再进行分享,这样就可以通用了。这个activity不需要在主工程中注册,项目manifest里面已经注册。
参数初始化,在分享前要将注册的appid传进项目中进行初始化
ShareConfig.setQQ("222222");
ShareConfig.setWeiXin("xxxxxx");
ShareConfig.setWeiBo(Constants.APP_KEY,Constants.SCOPE,Constants.REDIRECT_URL);
单例初始化:
shareApi = ShareApi.getInstance(this);
ShareApi初始化最好放在MainActivity中初始化,不然微博分享会有短暂延迟。
单例传入参数Context 必须是activity,原因是微信的分享传入的必须是activity,否则会报错,具体我也不是很清楚。
在传入appid之后,就可以直接使用分享了,直接调用ShareApi的share方法即可
/**
* 分享
* @param shareDao BaseShareDao
* @param shareListener ShareListener
* @param shareType ShareType 分享类型 QQ WEIXIN WEIBO
*/
public void share(BaseShareDao shareDao, ShareListener shareListener,ShareType shareType){
Share share = shareMap.get(shareType);
if(null != share){
if(shareType == ShareType.WEIBO){
share.setShareListener(shareListener);
Intent intent = new Intent(context, WbShareCallbackActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable(WbShareCallbackActivity.DZM_DATA,shareDao);
intent.putExtras(bundle);
context.startActivity(intent);
}else{
share.share(shareDao,shareListener);
}
}else{
switch (shareType){
case QQ:
Toast.makeText(context,"qq_appid can not null",Toast.LENGTH_SHORT).show();
break;
case WEIXIN:
Toast.makeText(context,"weixin_appid can not null",Toast.LENGTH_SHORT).show();
break;
case WEIBO:
Toast.makeText(context,"weibo_apikey can not null",Toast.LENGTH_SHORT).show();
break;
}
}
}
在分享的activity里面重写onActivityResult,QQ分享需要用到这个
/**
* onActivityResult
* @param requestCode requestCode
* @param resultCode resultCode
* @param data data
*/
public void onActivityResult(int requestCode, int resultCode, Intent data){
for (Map.Entry entry : shareMap.entrySet()){
entry.getValue().onActivityResult(requestCode,resultCode,data);
}
}
1.manifest文件下的
activity-alias
标签:为activity取别名用的
name是别名,targetActivity是要取别名的activity
注意:别名指定必须在主activity初始化之后,否则打出的包是损坏的
2.单例的volatile关键字
private static volatile ShareApi shareApi;
volatile 关键字的作用是禁止指令重排
什么是指令重排?
指令重排: 简单的说,就是计算机为了提高效率,会做一些优化,在不影响最终结果的情况下,可能会对一些语句的执行顺序进行调整。
3.library内部的manifest文件可以注册activity,引用library的工程sdk必须在library的sdk版本之间
取别名的activity不能在library里面注册
第一次写这种小框架,有许多不足之处希望多多包含,代码流程有更好的想法的希望能一起多多交流,一起探讨代码哲理…
项目地址:https://github.com/dengzhi00/Share_Sdk
喝水不忘挖井人
参考文献:http://www.jianshu.com/p/d6f0bac9c4c1
本项目是自己做的一个简单小项目,有兴趣看看的人如果发现有什么使用问题或者有发现哪里不对的地方希望大家指出,避免我的项目上线后出现一些不必要的bug,感谢