社会化分享

社会化分享,指的是用户通过互联网这个媒介,把文本/图片/多媒体信息分享到该用户的交际圈,从而加快信息传播的行为。对于app来说,网络社区虽多,但用户量足够大的就那几个,所以app的社会化分享功能抓住几个大的圈子就够了,比如说QQ、微信、QQ空间、微信朋友圈、新浪微博、腾讯微博等等。下面是截止到2016年6月6日,根据应用宝官网的统计,主要社交app的下载次数:
QQ : 42亿次下载
微信 : 24亿次下载
QQ空间 : 12亿次下载
新浪微博 : 5.8亿次下载
腾讯微博 : 1.4亿次下载

除了社交app的分享,还有传统的信息传播途径,例如发短信、发邮件等等。另外,出于安全考虑或流量消耗,有的用户不希望直接分享多媒体信息,所以应当允许用户复制文本或链接,由用户自行决定分享形式。

系统自带的分享

APP分享

社会化分享的sdk也不少,只是都比较臃肿,其实我们可以使用android自带的发送功能"android.intent.action.SEND",只要用户手机上安装了对应的app,即可简单并快速地完成分享动作。下面是几个常用分享对象的调用信息:
微信 : 包名为com.tencent.mm,分享页面为com.tencent.mm.ui.tools.ShareImgUI
微信朋友圈 : 包名为com.tencent.mm,分享页面为com.tencent.mm.ui.tools.ShareToTimeLineUI
QQ : 包名为com.tencent.mobileqq,分享页面为com.tencent.mobileqq.activity.JumpActivity
QQ空间 : 包名为com.qzone,分享页面为com.qzone.ui.operation.QZonePublishMoodActivity
新浪微博 : 包名为com.sina.weibo,分享页面为com.sina.weibo.EditActivity
腾讯微博 : 包名为com.tencent.WBlog,分享页面为com.tencent.WBlog.intentproxy.TencentWeiboIntent

传统途径分享

1、短信分享:把分享内容通过短信发送给好友,有关发送短信的说明参见《Android开发笔记(五十五)手机设备基本操作》,下面是短信分享的例子代码:

 private void sendSMS(String message) {Uri smsToUri = Uri.parse("smsto:");Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);intent.putExtra("sms_body", message);mContext.startActivity(intent);mHandler.sendEmptyMessage(0);}

2、邮件分享,把分享内容通过邮件发送给好友,有关发送邮件的说明参见《Android开发笔记(五十五)手机设备基本操作》,下面是邮件分享的例子代码:

 private void sendEmail(String title, String content) {Intent intent = new Intent(Intent.ACTION_SEND);intent.putExtra(Intent.EXTRA_SUBJECT, title);intent.putExtra(Intent.EXTRA_TEXT, content);intent.setType("message/rfc822");mContext.startActivity(Intent.createChooser(intent, "请选择邮件客户端"));mHandler.sendEmptyMessage(0);}

复制到剪贴板

剪贴板复制使用的是剪贴板管理类ClipboardManager,该类用到了系统服务Context.CLIPBOARD_SERVICE,把文本复制到剪贴板有两种方法:
方法一,只能复制文本,编译时提示过时@deprecated,代码如下:

         ClipboardManager cm = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);cm.setText(mUrl);

方法二,可复制文本、图片、URI等等,代码如下:

         ClipboardManager cm = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);ClipData data = ClipData.newPlainText("mUrl", mUrl);cm.setPrimaryClip(data);

下面是启用系统自带分享的效果截图

下面是启用系统自带分享的示例代码

import java.io.File;
import java.util.ArrayList;import net.sourceforge.simcpux.R;
import com.example.exmshare.util.Utils;import android.annotation.TargetApi;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;public class ItemSystemAdapter extends BaseAdapter implements OnItemClickListener {private LayoutInflater mInflater;private Context mContext;private Handler mHandler;private String mUrl;private String mTitle;private String mContent;private String mImageUrl;private ArrayList<ShareChanels> mChannelList;private int[] mShareIcons = {R.drawable.share_weixin, R.drawable.share_pengyou, R.drawable.share_qq, R.drawable.share_qzone, R.drawable.share_weibo, R.drawable.share_tweibo, R.drawable.share_sms, R.drawable.share_mail, R.drawable.share_copy};public ItemSystemAdapter(final Context context, Handler handler,String url, String title, String content, final String imageUrl,ArrayList<ShareChanels> channelList) {mInflater = LayoutInflater.from(context);mContext = context;mHandler = handler;mUrl = url;mTitle = title;mContent = content;if (imageUrl!=null && Patterns.WEB_URL.matcher(imageUrl).matches()) {new Thread(new Runnable() {public void run() {try {mImageUrl = Utils.getImagePath(imageUrl, Utils.getFileCache(context));} catch (Exception e) {e.printStackTrace();}}}).start();} else {mImageUrl = imageUrl;}if(channelList == null){mChannelList = new ArrayList<ShareChanels>();mChannelList.add(new ShareChanels("微信好友", 0,"com.tencent.mm.ui.tools.ShareImgUI", "com.tencent.mm"));mChannelList.add(new ShareChanels("微信朋友圈", 1,"com.tencent.mm.ui.tools.ShareToTimeLineUI", "com.tencent.mm"));mChannelList.add(new ShareChanels("QQ好友", 2,"com.tencent.mobileqq.activity.JumpActivity","com.tencent.mobileqq"));mChannelList.add(new ShareChanels("QQ空间", 3,"com.qzone.ui.operation.QZonePublishMoodActivity","com.qzone"));mChannelList.add(new ShareChanels("新浪微博", 4,"com.sina.weibo.EditActivity", "com.sina.weibo"));mChannelList.add(new ShareChanels("腾讯微博", 5,"com.tencent.WBlog.intentproxy.TencentWeiboIntent","com.tencent.WBlog"));mChannelList.add(new ShareChanels("发送短信", 6, "", ""));mChannelList.add(new ShareChanels("发送邮件", 7, "", ""));mChannelList.add(new ShareChanels("复制链接", 8, "", ""));}else{mChannelList = channelList;}}@Overridepublic int getCount() {return mChannelList.size();}@Overridepublic Object getItem(int position) {return mChannelList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {holder = new ViewHolder();convertView = mInflater.inflate(R.layout.item_share_system, null);holder.tv_share_name = (TextView) convertView.findViewById(R.id.tv_share_name);holder.iv_share_icon = (ImageView) convertView.findViewById(R.id.iv_share_icon);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}ShareChanels item = mChannelList.get(position);holder.tv_share_name.setText(item.channelName);holder.iv_share_icon.setImageResource(mShareIcons[item.channelType]);return convertView;}public final class ViewHolder {public TextView tv_share_name;public ImageView iv_share_icon;}public static class ShareChanels {public String channelName;public int channelType;public String activityName;public String packageName;public ShareChanels(String name, int type, String activityName, String packageName) {this.channelName = name;this.channelType = type;this.activityName = activityName;this.packageName = packageName;}}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {ShareChanels item = mChannelList.get(position);mHandler.sendEmptyMessageDelayed(0, 1500);if (item.channelType <= 5) {  //朋友圈仅支持分享图片shareMsg(mContext, mTitle, mContent + mUrl, mImageUrl, item);} else if (item.channelType == 6) {sendSMS(mContent + mUrl);} else if (item.channelType == 7) {sendEmail(mTitle, mContent + mUrl);} else if (item.channelType == 8) {Toast.makeText(mContext, "成功复制链接", Toast.LENGTH_LONG).show();ClipboardManager cm = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);cm.setText(mUrl);
//          ClipData data = ClipData.newPlainText("mUrl", mUrl);
//          cm.setPrimaryClip(data);}}private void sendSMS(String message) {Uri smsToUri = Uri.parse("smsto:");Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);intent.putExtra("sms_body", message);mContext.startActivity(intent);mHandler.sendEmptyMessage(0);}private void sendEmail(String title, String content) {Intent intent = new Intent(Intent.ACTION_SEND);intent.putExtra(Intent.EXTRA_SUBJECT, title);intent.putExtra(Intent.EXTRA_TEXT, content);intent.setType("message/rfc822");mContext.startActivity(Intent.createChooser(intent, "请选择邮件客户端"));mHandler.sendEmptyMessage(0);}@TargetApi(Build.VERSION_CODES.GINGERBREAD)private void shareMsg(Context context, String msgTitle, String msgText,String imgPath, ShareChanels share) {if (!share.packageName.isEmpty() && !Utils.isAvailable(mContext, share.packageName)) {Toast.makeText(mContext, "请先安装" + share.channelName.replace("好友", ""), Toast.LENGTH_SHORT).show();return;}Intent intent = new Intent("android.intent.action.SEND");if ((imgPath == null) || (imgPath.equals(""))) {intent.setType("text/plain");} else {File f = new File(imgPath);if ((f != null) && (f.exists()) && (f.isFile())) {intent.setType("image/png");intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));}}intent.putExtra(Intent.EXTRA_SUBJECT, msgTitle);intent.putExtra(Intent.EXTRA_TEXT, msgText);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if(!share.packageName.isEmpty()) {intent.setComponent(new ComponentName(share.packageName, share.activityName));context.startActivity(intent);} else {context.startActivity(Intent.createChooser(intent, msgTitle));}}}

友盟社会化分享

由于系统自带的分享功能要求用户手机上安装了对应的app,因此限制了该方式的使用范围,因为总不能让用户分享之前先下载几十M的app吧。基于此,社会化分享的sdk虽然臃肿,但也还是有它存在的理由。这其中,友盟sdk是比较常用的社会化分享sdk,它集成了知名的几十种分享渠道,除了之前提到的,还包括易信、人人网、来往、豆瓣。不过,因为不同app对应的开放平台有不同的接入账号,所以多一个分享渠道就多一个麻烦,因此我们平常还是主要分享到QQ、微信、微博等。

友盟的分享动作主要是由ShareAction这个类来完成,下面是该类的常用方法说明:
setPlatform : 设置分享渠道。SHARE_MEDIA.WEIXIN表示微信好友,SHARE_MEDIA.WEIXIN_CIRCLE表示微信朋友圈,SHARE_MEDIA.QQ表示QQ好友,SHARE_MEDIA.QZONE表示QQ空间内,SHARE_MEDIA.SINA表示新浪微博,SHARE_MEDIA.TENCENT表示腾讯微博,SHARE_MEDIA.SMS表示短信,SHARE_MEDIA.EMAIL表示邮件。
setCallback : 设置分享回调监听器。监听器是一个UMShareListener对象,该对象提供了三个回调方法,其中onResult表示分享完成,onError表示分享失败,onCancel表示分享取消。
withTitle : 设置分享标题。
withText : 设置分享内容。
withTargetUrl : 设置目标URL。
withMedia : 设置分享的多媒体内容。多媒体内容主要有四类:UMImage表示图像,UMusic表示音频,UMVideo表示视频,UMEmoji表示表情。
share : 开始分享。

下面是启用友盟社会化分享的效果截图

下面是启用友盟社会化分享的示例代码

import java.io.File;
import java.util.ArrayList;import net.sourceforge.simcpux.R;
import com.example.exmshare.util.Utils;import android.annotation.TargetApi;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;public class ItemSystemAdapter extends BaseAdapter implements OnItemClickListener {private LayoutInflater mInflater;private Context mContext;private Handler mHandler;private String mUrl;private String mTitle;private String mContent;private String mImageUrl;private ArrayList<ShareChanels> mChannelList;private int[] mShareIcons = {R.drawable.share_weixin, R.drawable.share_pengyou, R.drawable.share_qq, R.drawable.share_qzone, R.drawable.share_weibo, R.drawable.share_tweibo, R.drawable.share_sms, R.drawable.share_mail, R.drawable.share_copy};public ItemSystemAdapter(final Context context, Handler handler,String url, String title, String content, final String imageUrl,ArrayList<ShareChanels> channelList) {mInflater = LayoutInflater.from(context);mContext = context;mHandler = handler;mUrl = url;mTitle = title;mContent = content;if (imageUrl!=null && Patterns.WEB_URL.matcher(imageUrl).matches()) {new Thread(new Runnable() {public void run() {try {mImageUrl = Utils.getImagePath(imageUrl, Utils.getFileCache(context));} catch (Exception e) {e.printStackTrace();}}}).start();} else {mImageUrl = imageUrl;}if(channelList == null){mChannelList = new ArrayList<ShareChanels>();mChannelList.add(new ShareChanels("微信好友", 0,"com.tencent.mm.ui.tools.ShareImgUI", "com.tencent.mm"));mChannelList.add(new ShareChanels("微信朋友圈", 1,"com.tencent.mm.ui.tools.ShareToTimeLineUI", "com.tencent.mm"));mChannelList.add(new ShareChanels("QQ好友", 2,"com.tencent.mobileqq.activity.JumpActivity","com.tencent.mobileqq"));mChannelList.add(new ShareChanels("QQ空间", 3,"com.qzone.ui.operation.QZonePublishMoodActivity","com.qzone"));mChannelList.add(new ShareChanels("新浪微博", 4,"com.sina.weibo.EditActivity", "com.sina.weibo"));mChannelList.add(new ShareChanels("腾讯微博", 5,"com.tencent.WBlog.intentproxy.TencentWeiboIntent","com.tencent.WBlog"));mChannelList.add(new ShareChanels("发送短信", 6, "", ""));mChannelList.add(new ShareChanels("发送邮件", 7, "", ""));mChannelList.add(new ShareChanels("复制链接", 8, "", ""));}else{mChannelList = channelList;}}@Overridepublic int getCount() {return mChannelList.size();}@Overridepublic Object getItem(int position) {return mChannelList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {holder = new ViewHolder();convertView = mInflater.inflate(R.layout.item_share_system, null);holder.tv_share_name = (TextView) convertView.findViewById(R.id.tv_share_name);holder.iv_share_icon = (ImageView) convertView.findViewById(R.id.iv_share_icon);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}ShareChanels item = mChannelList.get(position);holder.tv_share_name.setText(item.channelName);holder.iv_share_icon.setImageResource(mShareIcons[item.channelType]);return convertView;}public final class ViewHolder {public TextView tv_share_name;public ImageView iv_share_icon;}public static class ShareChanels {public String channelName;public int channelType;public String activityName;public String packageName;public ShareChanels(String name, int type, String activityName, String packageName) {this.channelName = name;this.channelType = type;this.activityName = activityName;this.packageName = packageName;}}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {ShareChanels item = mChannelList.get(position);mHandler.sendEmptyMessageDelayed(0, 1500);if (item.channelType <= 5) {  //朋友圈仅支持分享图片shareMsg(mContext, mTitle, mContent + mUrl, mImageUrl, item);} else if (item.channelType == 6) {sendSMS(mContent + mUrl);} else if (item.channelType == 7) {sendEmail(mTitle, mContent + mUrl);} else if (item.channelType == 8) {Toast.makeText(mContext, "成功复制链接", Toast.LENGTH_LONG).show();ClipboardManager cm = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);cm.setText(mUrl);
//          ClipData data = ClipData.newPlainText("mUrl", mUrl);
//          cm.setPrimaryClip(data);}}private void sendSMS(String message) {Uri smsToUri = Uri.parse("smsto:");Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);intent.putExtra("sms_body", message);mContext.startActivity(intent);mHandler.sendEmptyMessage(0);}private void sendEmail(String title, String content) {Intent intent = new Intent(Intent.ACTION_SEND);intent.putExtra(Intent.EXTRA_SUBJECT, title);intent.putExtra(Intent.EXTRA_TEXT, content);intent.setType("message/rfc822");mContext.startActivity(Intent.createChooser(intent, "请选择邮件客户端"));mHandler.sendEmptyMessage(0);}@TargetApi(Build.VERSION_CODES.GINGERBREAD)private void shareMsg(Context context, String msgTitle, String msgText,String imgPath, ShareChanels share) {if (!share.packageName.isEmpty() && !Utils.isAvailable(mContext, share.packageName)) {Toast.makeText(mContext, "请先安装" + share.channelName.replace("好友", ""), Toast.LENGTH_SHORT).show();return;}Intent intent = new Intent("android.intent.action.SEND");if ((imgPath == null) || (imgPath.equals(""))) {intent.setType("text/plain");} else {File f = new File(imgPath);if ((f != null) && (f.exists()) && (f.isFile())) {intent.setType("image/png");intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));}}intent.putExtra(Intent.EXTRA_SUBJECT, msgTitle);intent.putExtra(Intent.EXTRA_TEXT, msgText);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if(!share.packageName.isEmpty()) {intent.setComponent(new ComponentName(share.packageName, share.activityName));context.startActivity(intent);} else {context.startActivity(Intent.createChooser(intent, msgTitle));}}}

腾讯平台分享(QQ、微信)

QQ互联平台

在调试社会化分享sdk的时候,因为sdk把各平台的接口调用都封装好了,反而难以跟踪各平台的接口结果,所以有条件的话最好直接调各开放平台。比如,博主在使用友盟sdk分享到腾讯微博时,发现死活分享不了,Toast提示“QQ is not auth”,查看日志提示“umengsocial(29555): QQ没有授权”。这里的帐号设置用的是PlatformConfig的setQQZone方法,如果用setTencentWeibo方法,则日志报错“Caused by: java.lang.ClassCastException: com.umeng.socialize.PlatformConfig$QQZone cannot be cast to com.umeng.socialize.PlatformConfig$TencentWeibo”。

根据友盟提供的sdk指南,登录到管理页面,在友盟后台应用管理->社会化分享->设置,填写应用地址(QQ开放平台上的应用页面URL),提交后会自动生成封装链接。按照页面的说明,还得把该链接填写腾讯微博开放平台对应APP信息页的“应用地址”字段。可是在QQ互联平台上(从腾讯微博开放平台改版而来),应用信息压根就没有“应用地址”字段,根本无法进行设置。

折腾了许久,还是没辙,估计友盟觉得腾讯微博用户少,也就不管它的分享了。得了,还是老老实实使用QQ提供的api来开发好了,一开始用腾讯的sdk来分享给QQ好友与QQ空间都挺顺利,没想到分享到腾讯微博时又卡壳了,总是提示“openid is invalid”。查了老久,才发现QQ平台的文档管理混乱,按照旧的文档说明,是无法在新的sdk上使用微博分享的。QQ平台旧的文档链接是下面这个,里面的说明并不适用于腾讯新的sdk
http://wiki.open.qq.com/wiki/mobile/API%E8%B0%83%E7%94%A8%E8%AF%B4%E6%98%8E#1._SDK_API.E8.B0.83.E7.94.A8.E8.AF.B4.E6.98.8E
QQ平台新的文档说明入口是http://wiki.connect.qq.com/,对应的API调试工具入口是http://connect.qq.com/sdk/webtools/index.html。开发者可在新文档入口处下载demo工程,里面有手机QQ各种分享功能的代码例子。

下面是QQ分享用到的Tencent类的主要方法说明:
createInstance : 根据appid创建一个Tencent实例。
shareToQQ : 分享给QQ好友。该方法需指定分享的参数,以及分享回调监听器IUiListener。
shareToQzone : 分享到QQ空间。该方法需指定分享的参数。
login : QQ账号登录。分享到腾讯微博时需要登录授权,该方法需指定登录回调监听器IUiListener。
setAccessToken : 设置入口令牌。登录成功后设置,即完成授权动作。
setOpenId : 设置开放标识。登录成功后设置,即完成授权动作。
getQQToken : 获取QQ登录授权的令牌。该方法用于生成Weibo实例时的传参,Weibo实例有了这个令牌,才能调用sendText方法去分享文本消息,才能调用sendPicText方法去分享图文消息。

下面是调用QQ分享接口的参数说明:
QQShare.SHARE_TO_QQ_KEY_TYPE : 分享的类型。图文分享(普通分享)填Tencent.SHARE_TO_QQ_TYPE_DEFAULT
QQShare.PARAM_TARGET_URL : 分享消息被点击后的跳转URL。
QQShare.PARAM_TITLE : 分享的标题。
QQShare.PARAM_SUMMARY : 分享的消息摘要。
QQShare.SHARE_TO_QQ_IMAGE_URL : 分享图片的URL或者本地路径。 
QQShare.SHARE_TO_QQ_APP_NAME : 手机QQ顶部,“返回”按钮文字后加上应用名;如果为空,则“返回”按钮保持原样。
QQShare.SHARE_TO_QQ_EXT_INT : 分享的额外选项,两种类型可选(默认是不隐藏分享到QZone按钮且不自动打开分享到QZone的对话框):
--QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN,分享时自动打开分享到QZone的对话框。
--QQShare.SHARE_TO_QQ_FLAG_QZONE_ITEM_HIDE,分享时隐藏分享到QZone按钮

下面是分享到腾讯微博时的QQ登录授权截图,有这个登录授权,才能进行后续的微博分享。

QQ分享完毕,可能收不到回调,这是因为有的手机会自动回收资源,要避免该问题,得重写Activity页面的onActivityResult方法,加入Tencent类的onActivityResultData方法调用,示例代码如下:

 @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {Log.d(TAG, "-->onActivityResult " + requestCode  + " resultCode=" + resultCode);if (requestCode==Constants.REQUEST_LOGIN || requestCode==Constants.REQUEST_APPBAR) {Tencent.onActivityResultData(requestCode,resultCode,data,ItemTencentAdapter.mLoginListener);} else if (requestCode==Constants.REQUEST_QQ_SHARE || requestCode==Constants.REQUEST_QZONE_SHARE) {Tencent.onActivityResultData(requestCode,resultCode,data,ItemTencentAdapter.mShareListener);}super.onActivityResult(requestCode, resultCode, data);}

微信开放平台

弄完了QQ开放平台,只是搞定了QQ好友、QQ空间、腾讯微博这三个渠道的分享,微信好友与微信朋友圈的分享,还得到微信开放平台从头开始。微信开放平台也有提供demo工程,按照上面的例子一步步来,也还好办。下面是我在开发过程中遇到的几个问题:
1、微信开放平台上申请的应用,包名和应用签名要正确设置,不然会导致后面没法正常分享;
2、如果appid用的是已用应用的appid,比如说使用demo工程的appid,那么你的工程的包名要设置为该appid对应的包名;同时,你的工程的签名也得使用该appid对应的签名文件,设置签名文件的方法是:依次选择window->preference->Android->build,设置custom debugger keystore作为你的工程的签名文件(例如demo工程的debugger.keystore)
3、WXEntryActivity.java文件必须放在“包名.wxapi”这个package下面,不然无法正确收到微信分享的返回结果。AndroidManifest.xml里面的WXEntryActivity要设置android:exported="true",否则分享完毕无法回调至该Activity。

微信平台分享主要用到IWXAPI、SendMessageToWX.Req和WXMediaMessage三个类,下面是IWXAPI的常用方法说明:
createWXAPI : 创建一个微信api的实例。当传入的appid为空时,还需调用registerApp方法进行注册;注册完毕,再传入appid,此时获得的实例才可进行后续的分享。
registerApp : 注册指定的appid。
sendReq : 发送分享请求。该方法的参数为SendMessageToWX.Req对象。

下面是SendMessageToWX.Req的常用属性说明:
transaction : 本次请求的流水。用于标识每次请求的唯一性。
scene : 本次请求的场景。SendMessageToWX.Req.WXSceneSession表示分享给微信好友,SendMessageToWX.Req.WXSceneTimeline表示分享到朋友圈。
message : 本次请求的信息。该方法的参数为WXMediaMessage对象。

下面是WXMediaMessage的常用属性说明:
title : 分享的标题。
description : 分享的内容。
mediaObject : 分享的媒体信息。如果是纯文本则使用WXTextObject对象,如果是纯图片则使用WXImageObject对象,如果是图文消息则使用WXWebpageObject对象。
thumbData : 分享的缩略图。

下面是启用腾讯平台分享的效果截图

下面是启用腾讯平台分享的示例代码

import java.util.ArrayList;import org.json.JSONObject;import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;import net.sourceforge.simcpux.R;import com.example.exmshare.util.Utils;
import com.tencent.connect.common.Constants;
import com.tencent.connect.share.QQShare;
import com.tencent.connect.share.QzoneShare;
import com.tencent.mm.sdk.modelmsg.SendMessageToWX;
import com.tencent.mm.sdk.modelmsg.WXImageObject;
import com.tencent.mm.sdk.modelmsg.WXMediaMessage;
import com.tencent.mm.sdk.modelmsg.WXTextObject;
import com.tencent.mm.sdk.modelmsg.WXWebpageObject;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tencent.open.t.Weibo;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import com.umeng.socialize.utils.Log;public class ItemTencentAdapter extends BaseAdapter implements OnItemClickListener {private final static String TAG = "ItemTentcentAdapter";private LayoutInflater mInflater;private static Context mContext;private Handler mHandler;private String mUrl;private String mTitle;private static String mContent;private static String mImageUrl;private ArrayList<ShareChanels> mChannelList;private final String QQ_APPID = "100330589";  //这里替换为开发者在QQ互联平台申请的应用idprivate static Tencent mTencent;private static Weibo mWeibo = null;private final String WX_APPID = "wxd930ea5d5a258f4f";  //这里替换为开发者在微信开放平台申请的应用idprivate IWXAPI mWeixinApi;private int[] mShareIcons = {R.drawable.logo_wechat, R.drawable.logo_wechatcircle, R.drawable.logo_qq, R.drawable.logo_qzone, R.drawable.logo_tencentweibo};public ItemTencentAdapter(final Context context, Handler handler,String url, String title, String content, final String imageUrl, ArrayList<ShareChanels> channelList) {mInflater = LayoutInflater.from(context);mContext = context;mHandler = handler;mUrl = url;mTitle = title;mContent = content;if (imageUrl!=null && Patterns.WEB_URL.matcher(imageUrl).matches()) {new Thread(new Runnable() {public void run() {try {mImageUrl = Utils.getImagePath(imageUrl, Utils.getFileCache(context));} catch (Exception e) {e.printStackTrace();}}}).start();} else {mImageUrl = imageUrl;}if (channelList == null) {mChannelList = new ArrayList<ShareChanels>();mChannelList.add(new ShareChanels("微信好友", 0));mChannelList.add(new ShareChanels("微信朋友圈", 1));mChannelList.add(new ShareChanels("QQ好友", 2));mChannelList.add(new ShareChanels("QQ空间", 3));mChannelList.add(new ShareChanels("腾讯微博", 4));} else {mChannelList = channelList;}// 创建一个QQ实例,用于QQ分享、QQ空间分享、腾讯微博分享mTencent = Tencent.createInstance(QQ_APPID, mContext);// 将该app注册到微信,用于微信分享、微信朋友圈分享mWeixinApi = WXAPIFactory.createWXAPI(mContext, null);mWeixinApi.registerApp(WX_APPID);mWeixinApi = WXAPIFactory.createWXAPI(mContext, WX_APPID);}@Overridepublic int getCount() {return mChannelList.size();}@Overridepublic Object getItem(int position) {return mChannelList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {holder = new ViewHolder();convertView = mInflater.inflate(R.layout.item_share_system, null);holder.tv_share_name = (TextView) convertView.findViewById(R.id.tv_share_name);holder.iv_share_icon = (ImageView) convertView.findViewById(R.id.iv_share_icon);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}ShareChanels item = mChannelList.get(position);holder.tv_share_name.setText(item.channelName);holder.tv_share_name.setPadding(0, 0, 0, 0);holder.iv_share_icon.setImageResource(mShareIcons[item.channelType]);return convertView;}public final class ViewHolder {public TextView tv_share_name;public ImageView iv_share_icon;}public static class ShareChanels {public String channelName;public int channelType;public ShareChanels(String name, int type) {this.channelName = name;this.channelType = type;}}public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {ShareChanels item = mChannelList.get(arg2);mHandler.sendEmptyMessageDelayed(0, 1500);if (item.channelType == 0) {SendMessageToWX.Req req = new SendMessageToWX.Req();// transaction字段用于唯一标识一个请求req.transaction = "wx_share" + System.currentTimeMillis();req.message = getWXMessage();req.scene = SendMessageToWX.Req.WXSceneSession;mWeixinApi.sendReq(req);} else if (item.channelType == 1) {SendMessageToWX.Req req = new SendMessageToWX.Req();req.transaction = "wx_share" + System.currentTimeMillis();req.message = getWXMessage();req.scene = SendMessageToWX.Req.WXSceneTimeline;mWeixinApi.sendReq(req);} else if (item.channelType == 2) {mShareListener = new ShareQQListener(mContext, item.channelName);Bundle params = new Bundle();params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);params.putString(QQShare.SHARE_TO_QQ_TITLE, mTitle);params.putString(QQShare.SHARE_TO_QQ_SUMMARY,  mContent);params.putString(QQShare.SHARE_TO_QQ_TARGET_URL,  mUrl);params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, mImageUrl);params.putString(QQShare.SHARE_TO_QQ_APP_NAME,  mContext.getPackageName());mTencent.shareToQQ((Activity) mContext, params, mShareListener);} else if (item.channelType == 3) {mShareListener = new ShareQQListener(mContext, item.channelName);ArrayList<String> urlList = new ArrayList<String>();urlList.add(mImageUrl);Bundle params = new Bundle();params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT );params.putString(QzoneShare.SHARE_TO_QQ_TITLE, mTitle);params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, mContent);params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, mUrl);params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, urlList);mTencent.shareToQzone((Activity) mContext, params, mShareListener);} else if (item.channelType == 4) {// 腾讯微博分享需要QQ登录授权mTencent.login((Activity) mContext, "all", mLoginListener);}}private int THUMB_SIZE = 150;private WXMediaMessage getWXMessage() {WXMediaMessage msg = new WXMediaMessage();if (!TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mImageUrl)) {// 分享文本消息WXTextObject textObj = new WXTextObject();textObj.text = mContent;msg.mediaObject = textObj;msg.title = mTitle;msg.description = mContent;} else if (TextUtils.isEmpty(mTitle) && !TextUtils.isEmpty(mImageUrl)) {// 分享图片消息
//          WXImageObject imgObj = new WXImageObject();
//          imgObj.setImagePath(mImageUrl);Bitmap bmp = BitmapFactory.decodeFile(mImageUrl);WXImageObject imgObj = new WXImageObject(bmp);msg.mediaObject = imgObj;Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true);msg.thumbData = Utils.bmpToByteArray(thumbBmp, true);  // 设置缩略图} else if (!TextUtils.isEmpty(mTitle) && !TextUtils.isEmpty(mImageUrl)) {// 分享图文消息WXWebpageObject webpage = new WXWebpageObject();webpage.webpageUrl = mUrl;msg.title = mTitle;msg.description = mContent;msg.mediaObject = webpage;Bitmap bmp = BitmapFactory.decodeFile(mImageUrl);Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true);msg.thumbData = Utils.bmpToByteArray(thumbBmp, true);  // 设置缩略图}return msg;}public static final int REQUEST_ADD_PIC_T = 1001;public static IUiListener mLoginListener = new IUiListener() {@Overridepublic void onComplete(Object object) {Log.d(TAG, "登录完成:"+object.toString());try {JSONObject jsonObject = (JSONObject)object;String token = jsonObject.getString(Constants.PARAM_ACCESS_TOKEN);String expires = jsonObject.getString(Constants.PARAM_EXPIRES_IN);String openId = jsonObject.getString(Constants.PARAM_OPEN_ID);if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires)&& !TextUtils.isEmpty(openId)) {mTencent.setAccessToken(token, expires);mTencent.setOpenId(openId);mWeibo = new Weibo(mContext, mTencent.getQQToken());if (mImageUrl==null || mImageUrl.length()<=0) {mWeibo.sendText(mContent, new ShareQQListener(mContext, "微博文字"));} else {mWeibo.sendPicText(mContent, mImageUrl, new ShareQQListener(mContext, "微博图文"));}}} catch (Exception e) {Log.d(TAG, "登录异常:"+e.getMessage());}}@Overridepublic void onError(UiError error) {Log.d(TAG, "登录失败:"+error.errorMessage);}@Overridepublic void onCancel() {Log.d(TAG, "登录取消");}};public static ShareQQListener mShareListener;private static class ShareQQListener implements IUiListener {private Context context;private String channelName;public ShareQQListener(final Context context, final String channelName) {this.context = context;this.channelName = channelName;}@Overridepublic void onComplete(Object object) {Toast.makeText(context, channelName+"分享完成:"+object.toString(), Toast.LENGTH_LONG).show();}@Overridepublic void onError(UiError error) {Toast.makeText(context, channelName+"分享失败:"+error.errorMessage, Toast.LENGTH_LONG).show();}@Overridepublic void onCancel() {Toast.makeText(context, channelName+"分享取消", Toast.LENGTH_LONG).show();}}}

点此查看Android开发笔记的完整目录

Android开发笔记(一百零五)社会化分享SDK相关推荐

  1. Android开发笔记(九十五)自定义Drawable

    Drawable Bitmap是Android对图像的定义描述,而Drawable则是对图像的展现描述,在View视图中显示图像都是通过Drawable来实现的.其中有关Bitmap的介绍参见< ...

  2. Android开发笔记(十五)淡入淡出动画TransitionDrawable

    说到淡入淡出动画,可能大家会想到补间动画里面的AlphaAnimation,不过这个深浅动画只能对透明度做渐变效果,也就是只能对一个图形做深浅的颜色变换.如果我们想要从A图片逐渐变为B图片,也就是要实 ...

  3. Android开发笔记(八十二)SDK版本兼容

    统一主题与风格 Android控件很多属性都有默认值,比如文字默认黑色.编辑框默认透明背景等等,但因为android是开源的,各厂商都会自行修修补补,所以很多时候默认值并不靠谱.举例如下: 1.在某些 ...

  4. Android开发笔记(序)写在前面的目录

    知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入 ...

  5. Android开发笔记(序)

    本开发笔记,借鉴与其他开发者整理的文章范例与心得体会.在这里作为开发过程中的一个总结与笔记式记录. 如有侵犯作者权益,请及时联系告知删除.俗话说:集百家成一言,去粕成金. ************** ...

  6. Android开发笔记(序)写在前面的目录大全

    转自  湖前琴亭 的博客https://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面 ...

  7. Andriod开发之二十:Android开发笔记(序)写在前面的目录

    https://blog.csdn.net/aqi00/article/details/50038385 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教 ...

  8. Android开发笔记(八十六)几个特殊的类

    接口interface interface是一些功能的集合,但它只定义了对象必须实现的成员,而不包含成员的实现代码,成员的具体代码由实现接口的类提供.Android对接口的使用场景主要有三类:事件监听 ...

  9. Android开发笔记(七十七)图片缓存算法

    ImageCache 由于手机流量有限,又要加快app的运行效率,因此好的app都有做图片缓存.图片缓存说起来简单,做起来就用到很多知识点,可算是集Android技术之大全了.只要理解图片缓存的算法, ...

  10. Android开发笔记(十七)GIF动画的实现GifAnimation

    GIF在Windows上是常见的图片格式,主要用来播放短小的动画.但在手机上由于系统资源紧张,所以Android并没有直接支持GIF格式,如果在ImageView中放入一张gif文件,你会发现显示出来 ...

最新文章

  1. 朴素、Select、Poll和Epoll网络编程模型实现和分析——朴素模型
  2. IOS UIWebView引用外部CSS样式(转载)
  3. 互斥事件的概念和公式_IGCSE数学5月大考冲刺A*?必备公式与技巧
  4. 120万人同时在线考试,这么大的流量如何支撑
  5. CVPR2021 Oral《Seeing Out of the Box》北科大中山大学微软提出端到端视觉语言表征预训练方法...
  6. 单位转换html代码,万能在线单位转换器 转换器网
  7. Python的开源人脸识别库:离线识别率高达99.38%
  8. Java:类与对象概念
  9. 网站域名被拦截,网站被流量劫持,服务器攻击,网站被跨区恶意点击,问题的定义与解答
  10. 修改密码 -测试用例设计
  11. 京东云linux查看挂载磁盘,使用S3fs在Linux实例上挂载Bucket
  12. HTML鼠标滚轮事件
  13. mixamo骨骼_mixamo动作库的模型和动作绑定控制器的方法-上集
  14. 微软zone DNS服务器,DNS 策略概述
  15. unix环境高级编程----进程控制fock()函数
  16. 用计算机语言编写累加程序,用汇编语言实现如下程序:进行自然数相加(1+2+3... 汇编语言 编写程序实现自然数1到100的累加。要求用......
  17. python字典打印所有值_python字典的值如何打印
  18. 毕业论文查重怎么才算重复内容?
  19. 小学生C++编程基础 课程7(B)
  20. 低通采样定理 matlab,基于Matlab的低通抽样定理仿真.docx

热门文章

  1. Leetcode每日一题:992.sort-array-by-parity-ii(按奇偶排序数组Ⅱ)
  2. 斯坦福李飞飞CS231n笔记1计算机视觉概述与历史背景
  3. VS2015+OpenGL配置方法
  4. Java实现非对称加密算法-RSA加解密
  5. Go36-3-代码包
  6. vue中定义多重样式
  7. 计算机等级考试三级教材,计算机等级考试三级过关技巧
  8. Eclipse快速创建Bottom Up类型的Web Service服务端
  9. lstm原始论文_命名实体识别NER论文调研
  10. 郑州大学c语言课程设计2000行,C语言课程设计大作业(1).pptx