我们首先要去友盟官网注册账号并登录,然后在首页顶部导航产品栏下选择社会化分享,然后点击立即使用进入友盟分析后台,点击右上角第一个应用列表图标 即可进入我创建的应用列表,如果还没有创建过应用或者想创建新的应用都可以切换到管理页面在右上角点击添加新应用进行创建,填写应用的基本信息提交之后就可以获得AppKey了。
申请QQ, QQ空间,微信,朋友圈,新浪微博需要的appkey, appid, appsecret等:
qq开发账号:http://open.qq.com/
微信开发账号:https://open.weixin.qq.com/
微博开发账号:http://open.weibo.com/
各平台appKey获取方法:http://bbs.mob.com/thread-275-1-1.html
下载地址:http://dev.umeng.com/social/android/sdk-download
根据自己的项目需要选择对应的平台
下载后解压出来如下图,有三个文件夹:
1、导入jar文件,资源文件,以及so文件
将三个文件夹下所有的jar和资源文件放入项目中,此处注意在thirdparties文件夹下除了有jar文件还有.so文件,那么.so文件我们要如何添加到项目中呢?有如下两种方式:
方式一:在项目的main目录下创建jniLibs目录,并将所有的.so文件全部放在该目录下,因为Android Studio 默认的so文件路径是app/src/main/jniLibs/armeabi,有时还需要添加armeabi-v7a,x86文件夹,视平台酌情增删,如下图:
方式二:当然这个so文件的默认目录是可以改变的的,比如在gradle脚本里配置sourceSets如下:
android {
compileSdkVersion 27
defaultConfig {
// ...
}
buildTypes {
// ...
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
这样配置的话,so文件位置就和jar文件目录一致都在项目的libs目录下,如下图,但本人还是推荐使用as默认的文件目录结构。
2、添加回调Activity
2.1,微信回调
在包名目录下创建wxapi文件夹,新建一个名为WXEntryActivity的activity继承WXCallbackActivity,如下图:
2.2,QQ与新浪微博的回调:
QQ与新浪不需要添加Activity,但需要在使用QQ分享或者授权的Activity中添加如下代码:
(注意onActivityResult不可在fragment中实现,如果在fragment中调用登录或分享,需要在fragment依赖的Activity中实现)
// 很重要:在包含分享或者登录的页面要重写这个方法,否则分享等过程不会走相应的回调方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);
}
注意:实际项目中发现,QQ分享成功和取消时没有走相应的回调方法,原因可能有以下两种:
1,很可能是没有重写onActivityResult方法
2,是你的分享代码代码写在了Fragment中,QQ分享成功后并不走Fragment的onActivityResult()方法,需要把分享的方法写在Activity中,并在onActivityResult方法中添加回调监听,然后在Fragment中调用Activity中的分享方法即可。
3、配置清单文件AndroidManifest
3.1,添加权限
<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" />
3.2,SDK中需要的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>
<!-- qq精简版 -->
<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" />
<!-- 这里的scheme是qq分享要用的,100424468为自己申请的appid,真实项目中需要替换 -->
<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" />
<!-- 分享编辑页,只有豆瓣,人人,腾讯微博,领英,twitter需要 -->
<activity
android:name="com.umeng.socialize.editorpage.ShareActivity"
android:excludeFromRecents="true"
android:theme="@android:style/Theme.NoTitleBar" />
3.3,添加友盟appkey(appkey可以在清单文件中配置,也可以不配置,如果不在清单文件中配置,则需要在application的子类中指明,具体再往下看)
<!-- 友盟Appkey-->
<meta-data
android:name="UMENG_APPKEY"
android:value="第一步申请的友盟AppKey" />
<!--渠道配置 -->
<meta-data
android:name="UMENG_CHANNEL"
android:value="要符合友盟平台渠道号命名规则" />
4、在MyApplication中进行初始化设置,如下:
@Override
public void onCreate() {
super.onCreate();
// 参数1:上下文对象,必须的参数不能为空
// 参数2:AppKey,非必须参数
// 参数3:Channel渠道号,非必须参数
// 参数4:设备类型,必须参数,传参数为UMConfigure.DEVICE_TYPE_PHONE则表示手机;传参数为UMConfigure.DEVICE_TYPE_BOX则表示盒子;默认为手机。
// 参数5:Push推送业务的secret,需要集成Push功能时必须传入Push的secret,否则传空。
// 如果在清单文件中通过标签已经配置过appkey和channel,那么对应的参数2和参数3可以传空,否则必须传入值。
UMConfigure.init(this,"5b9c7e8da40fa340e80006f8"
,"umeng",UMConfigure.DEVICE_TYPE_PHONE,"");
// UMConfigure.init(this,"","",UMConfigure.DEVICE_TYPE_PHONE,""); // 清单文件中均已配置
{
// 微信
PlatformConfig.setWeixin("wxdc1e388c3822c80b", "3baf1193c85774b3fd9d18447d76cab0");
// 微博(第三个参数为回调地址)
PlatformConfig.setSinaWeibo("3921700954", "04b48b094faeb16683c32669824ebdad","http://sns.whalecloud.com");
// QQ
PlatformConfig.setQQZone("100424468", "c7394704798a158208a74ab60104f0ba");
}
}
新浪微博回调地址redirect_url(授权回调页)的设置格式:
首先注册成为新浪微博开放平台开发者,并填写基本信息,进行邮箱确认。之后创建应用新浪app,就会获得app key , app secret.
回调地址格式:http://open.weibo.com/apps/appKey/privilege/oauth
例如:appKey=3564760100
redirect_url=http://open.weibo.com/apps/3564760100/privilege/oauth
5、签名的配置
5.1,为什么要配置签名?
我们在测试Android应用的时候,可以指定build的类型是debug,Android Studio的debug包和release包是有区分的,但很多第三方都要有正式签名才能测试,而系统debug包的默认签名是无法进行测试的。
例如如果我们做微信分享功能,因为微信分享是需要正式的签名的,你们是不是每一次都需要自己打包获取到具有正式签名的apk后才能测试微信分享功能?打包那个速度估计各位都有深切体会,喝杯茶的时间估计快有了!
所以问题的症结就在于:如何打包都有正式签名的测试包和发布包,而且不需要修改代码,即就是如何debug运行具有release签名的apk,请看下面完整教程。
5.2,Android Studio 下debug情况下如何直接使用release的签名,完整过程如下:
首先我们需要使用Android studio来生成.jks(Java Key Store)后缀的签名文件,具体如何生成不会的同学请参考博客https://www.jianshu.com/p/4da94c5757f7,里面有详细步骤,假如我们生成的签名文件存放路径为:E:/key/demo/test.jks。
在app的build.gradle文件中这样配置:
android {
//这里signingConfigs需要添加到最前边,后边的才能收到
signingConfigs {
release {
keyAlias 'yangzhe'
keyPassword '123456'
storePassword '123456'
storeFile file('E:/key/demo/test.jks')
}
}
// ...
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable true //是否支持调试,release下该值默认为false,此处我们设置为true
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable true //是否支持调试,debug下该值默认为true,此处我们可以不设置
signingConfig signingConfigs.release
}
}
// ....
}
6.1,主界面布局文件activity_umlogin_and_share.layout代码:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_gravity="center"
android:text="第三方分享"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="qq"
android:text="QQ"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="weiXin"
android:text="微信"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="weixinCircle"
android:text="朋友圈"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="sina"
android:text="新浪"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="Qzone"
android:text="QQ空间"/>
<TextView
android:layout_marginTop="50dp"
android:layout_gravity="center"
android:text="第三方登录"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="qqLogin"
android:text="QQ登录"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="weiXinLogin"
android:text="微信登录"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="sinaLogin"
android:text="新浪登录"/>
</LinearLayout>
</ScrollView>
5.2,UMLoginAndShareActivity的完整代码:
public class UMLoginAndShareActivity extends AppCompatActivity {
private String TAG = this.getClass().getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_umlogin_and_share);
}
public void qq(View view) {
// 弹出dialog方式
ShareUtils.shareWebWithDialog(this, Defaultcontent.url, Defaultcontent.title
, Defaultcontent.text, Defaultcontent.imageurl, R.mipmap.icon_logo_share
);
}
public void weiXin(View view) {
// 直接分享的方式
ShareUtils.shareWeb(this, Defaultcontent.url, Defaultcontent.title
, Defaultcontent.text, Defaultcontent.imageurl, R.mipmap.icon_logo_share, SHARE_MEDIA.WEIXIN
);
}
public void weixinCircle(View view) {
ShareUtils.shareWeb(this, Defaultcontent.url, Defaultcontent.title
, Defaultcontent.text, Defaultcontent.imageurl, R.mipmap.icon_logo_share, SHARE_MEDIA.WEIXIN_CIRCLE
);
}
public void sina(View view) {
ShareUtils.shareWeb(this, Defaultcontent.url, Defaultcontent.title
, Defaultcontent.text, Defaultcontent.imageurl, R.mipmap.icon_logo_share, SHARE_MEDIA.SINA
);
}
public void Qzone(View view) {
ShareUtils.shareWeb(this, Defaultcontent.url, Defaultcontent.title
, Defaultcontent.text, Defaultcontent.imageurl, R.mipmap.icon_logo_share, SHARE_MEDIA.QZONE
);
}
// 登录
public void qqLogin(View view) {
authorization(SHARE_MEDIA.QQ);
}
public void weiXinLogin(View view) {
authorization(SHARE_MEDIA.WEIXIN);
}
public void sinaLogin(View view) {
authorization(SHARE_MEDIA.SINA);
}
//授权
private void authorization(SHARE_MEDIA share_media) {
UMShareAPI.get(this).getPlatformInfo(this, share_media, new UMAuthListener() {
@Override
public void onStart(SHARE_MEDIA share_media) {
Log.d(TAG, "onStart " + "授权开始");
}
@Override
public void onComplete(SHARE_MEDIA share_media, int i, Map<String, String> map) {
Log.d(TAG, "onComplete " + "授权完成");
String uid = map.get("uid");
String openid = map.get("openid");//微博没有
String unionid = map.get("unionid");//微博没有
String access_token = map.get("access_token");
String refresh_token = map.get("refresh_token");//微信,qq,微博都没有获取到
String expires_in = map.get("expires_in");
String name = map.get("name"); // 昵称
String gender = map.get("gender"); // 性别
String iconurl = map.get("iconurl"); // 头像地址
Toast.makeText(getApplicationContext(), "name=" + name + ",gender=" + gender, Toast.LENGTH_SHORT).show();
//拿到信息去请求自己项目的登录接口,同时将share_media通过Intent传过去,用于在注销登录时删除授权.
}
@Override
public void onError(SHARE_MEDIA share_media, int i, Throwable throwable) {
Log.d(TAG, "onError " + "授权失败");
}
@Override
public void onCancel(SHARE_MEDIA share_media, int i) {
Log.d(TAG, "onCancel " + "授权取消");
}
});
}
@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();
}
}
5.3,分享功能封装的工具类,支持弹出面板和不弹出面板两种方式,以及对弹出面板根据自己的app风格做样式调整,代码如下:
public class ShareUtils {
/**
* 不带分享面板
*/
public static void shareWeb(final Activity activity, String WebUrl, String title, String description, String imageUrl, int imageID, SHARE_MEDIA platform) {
UMWeb web = new UMWeb(WebUrl);//连接地址
web.setTitle(title);//标题
web.setDescription(description);//描述
if (TextUtils.isEmpty(imageUrl)) {
web.setThumb(new UMImage(activity, imageID)); //本地缩略图
} else {
web.setThumb(new UMImage(activity, imageUrl)); //网络缩略图
}
new ShareAction(activity)
.setPlatform(platform)
.withMedia(web)
.setCallback(new UMShareListener() {
@Override
public void onStart(SHARE_MEDIA share_media) {
// 可以显示一个进度提示请稍后,然后在成功调起或者取消等时dismiss掉
}
@Override
public void onResult(final SHARE_MEDIA share_media) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (share_media.name().equals("WEIXIN_FAVORITE")) {
Toast.makeText(activity, share_media + " 收藏成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(activity, share_media + " 分享成功", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onError(final SHARE_MEDIA share_media, final Throwable throwable) {
if (throwable != null) {
Log.d("throw", "throw:" + throwable.getMessage());
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, share_media + " 分享失败", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onCancel(final SHARE_MEDIA share_media) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, share_media + " 分享取消", Toast.LENGTH_SHORT).show();
}
});
}
})
.share();
//新浪微博中图文+链接
/*new ShareAction(activity)
.setPlatform(platform)
.withText(description + " " + WebUrl)
.withMedia(new UMImage(activity,imageID))
.share();*/
}
// 带分享面板,并且支持自定义面板属性,如标题,颜色,位置等
public static void shareWebWithDialog(final Activity activity, String WebUrl, String title, String description, String imageUrl, int imageID) {
UMWeb web = new UMWeb(WebUrl);//连接地址
web.setTitle(title);//标题
web.setDescription(description);//描述
if (TextUtils.isEmpty(imageUrl)) {
web.setThumb(new UMImage(activity, imageID)); //本地缩略图
} else {
web.setThumb(new UMImage(activity, imageUrl)); //网络缩略图
}
ShareAction shareAction = new ShareAction(activity)
// .setPlatform(platform)
.withMedia(web)
.setDisplayList(SHARE_MEDIA.SINA,SHARE_MEDIA.QQ,SHARE_MEDIA.WEIXIN,SHARE_MEDIA.WEIXIN_CIRCLE,SHARE_MEDIA.QZONE)
.setCallback(new UMShareListener() {
@Override
public void onStart(SHARE_MEDIA share_media) {
}
@Override
public void onResult(final SHARE_MEDIA share_media) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (share_media.name().equals("WEIXIN_FAVORITE")) {
Toast.makeText(activity, share_media + " 收藏成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(activity, share_media + " 分享成功", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onError(final SHARE_MEDIA share_media, final Throwable throwable) {
if (throwable != null) {
Log.d("throw", "throw:" + throwable.getMessage());
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, share_media + " 分享失败", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onCancel(final SHARE_MEDIA share_media) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, share_media + " 分享取消", Toast.LENGTH_SHORT).show();
}
});
}
});
// 根据自己app的风格设置分享面板的各个属性,具体见官方文档:https://developer.umeng.com/docs/66632/detail/66639#h3-u5220u9664u6388u6743
ShareBoardConfig config = new ShareBoardConfig();//新建ShareBoardConfig
config.setShareboardPostion(ShareBoardConfig.SHAREBOARD_POSITION_CENTER);//设置位置,位置只有两种中间和底部HAREBOARD_POSITION_BOTTOM
config.setMenuItemBackgroundShape(ShareBoardConfig.BG_SHAPE_CIRCULAR);
config.setTitleText("客官,请选择您要分享到的平台");
config.setCancelButtonVisibility(false);
shareAction.open(config);//传入分享面板中
//新浪微博中图文+链接
/*new ShareAction(activity)
.setPlatform(platform)
.withText(description + " " + WebUrl)
.withMedia(new UMImage(activity,imageID))
.share();*/
}
}
5.4,分享内容模拟类,代码如下:
public class Defaultcontent {
public static String url = "https://mobile.umeng.com/";
public static String text = "友盟微社区sdk,多终端一社区,为您的app添加社区就是这么简单";
public static String title = "友盟微社区";
public static String imageurl = "http://dev.umeng.com/images/tab2_1.png";
public static String videourl = "http://video.sina.com.cn/p/sports/cba/v/2013-10-22/144463050817.html";
public static String musicurl = "http://music.huoxing.com/upload/20130330/1364651263157_1085.mp3";
}
**
**
/*
带平台跳转
Intent intent = new Intent(MainActivity.this,HomeActivity.class);
intent.putExtra(“platform”,share_media);
startActivity(intent);
finish();
-------------------------------------------------------------------
然后在另一个activity中:
SHARE_MEDIA share_media= (SHARE_MEDIA) intent.getSerializableExtra("platform");
UMShareAPI.get(this).deleteOauth(this, share_media, new UMAuthListener() {
@Override
public void onStart(SHARE_MEDIA share_media) {
}
@Override
public void onComplete(SHARE_MEDIA share_media, int i, Map map) {
// 退出成功
}
@Override
public void onError(SHARE_MEDIA share_media, int i, Throwable throwable) {
}
@Override
public void onCancel(SHARE_MEDIA share_media, int i) {
}
});
*/