第三方分享第一弹----微信分享

第三方分享第一弹----微信分享

大家都知道,分享功能几乎是所有APP都需要的基础功能,为了让大家免于到处去找资料,我这里简单的做了一下总结,也算是自己学习的一个记录。
下面我们先来看下微信的分享功能。

官方资料

首先,想要微信的分享,需要我们去微信公众平台创建我们的应用,这个其实很简单啦,大家按照步骤一步一步来就可以啦,应用审核一般两到三天就可以了,待审核通过以后就可以开始安心的敲代码啦.

微信的分享支持文本,视频,音频,图片,网页甚至小程序,在这里我们来看下官方介绍的方法:

官方文档传送门

首先我们需要依赖微信的第三方库:

  compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:1.1.6'

分享之前需要创建api对象,如下:

IWXAPI api;
// WXAPIFactory工厂,获取IWXAPI实例
api = WXAPIFactory.createWXAPI(context, Constants.WeChat_APPID, false);
// 注册应用
boolean flag = api.registerApp(Constants.WeChat_APPID); // 你申请应用的APPID 

1.文本分享

WXTextObject textObject = new WXTextObject();
textObject.text = "hello";//你要分享出去的文本
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = textObject;
msg.description = "hello";

SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("text");// 唯一标识一个请求
req.message = msg;
// 发送到聊天界面——WXSceneSession
// 发送到朋友圈——WXSceneTimeline
// 添加到微信收藏——WXSceneFavorite
req.scene = SendMessageToWX.Req.WXSceneSession;
api.sendReq(req);  

2.图片分享

   Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.share_pic);

    WXImageObject imageObject = new WXImageObject(bitmap);


    WXMediaMessage msg = new WXMediaMessage();
    msg.mediaObject = imageObject;

    //设置缩略图
    Bitmap bmp = Bitmap.createScaledBitmap(bitmap,80,80,true);
    bitmap.recycle();
    msg.thumbData = BitmapUtils.Bitmap2Bytes(bmp);

    SendMessageToWX.Req req = new SendMessageToWX.Req();
    req.transaction = buildTransaction("text");// 唯一标识一个请求
    req.message = msg;
    req.scene = SendMessageToWX.Req.WXSceneSession;

    api.sendReq(req);

3.音乐分享

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.share_pic);

    WXMusicObject musicObject = new WXMusicObject();
    musicObject.musicUrl = "音乐url";

    WXMediaMessage msg = new WXMediaMessage();
    msg.mediaObject = musicObject;
    msg.title = "音乐标题";
    msg.description = "音乐描述";

    //设置缩略图
    Bitmap bmp = Bitmap.createScaledBitmap(bitmap,80,80,true);
    bitmap.recycle();
    msg.thumbData = BitmapUtils.Bitmap2Bytes(bmp);

    SendMessageToWX.Req req = new SendMessageToWX.Req();
    req.transaction = buildTransaction("music");// 唯一标识一个请求
    req.message = msg;
    req.scene = SendMessageToWX.Req.WXSceneSession;

    api.sendReq(req); 
    

4.视频分享

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.share_pic);

    WXMusicObject musicObject = new WXMusicObject();
    musicObject.musicUrl = "视频url";

    WXMediaMessage msg = new WXMediaMessage();
    msg.mediaObject = musicObject;
    msg.title = "视频标题";
    msg.description = "视频描述";

    //设置缩略图
    Bitmap bmp = Bitmap.createScaledBitmap(bitmap,80,80,true);
    bitmap.recycle();
    msg.thumbData = BitmapUtils.Bitmap2Bytes(bmp);

    SendMessageToWX.Req req = new SendMessageToWX.Req();
    req.transaction = buildTransaction("video");// 唯一标识一个请求
    req.message = msg;
    req.scene = SendMessageToWX.Req.WXSceneSession;

    api.sendReq(req); 
    

5.网页分享

 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.share_pic);

    WXMusicObject musicObject = new WXMusicObject();
    musicObject.musicUrl = "网页url";

    WXMediaMessage msg = new WXMediaMessage();
    msg.mediaObject = musicObject;
    msg.title = "网页标题";
    msg.description = "网页描述";

    //设置缩略图
    Bitmap bmp = Bitmap.createScaledBitmap(bitmap,80,80,true);
    bitmap.recycle();
    msg.thumbData = BitmapUtils.Bitmap2Bytes(bmp);

    SendMessageToWX.Req req = new SendMessageToWX.Req();
    req.transaction = buildTransaction("webpage");// 唯一标识一个请求
    req.message = msg;
    req.scene = SendMessageToWX.Req.WXSceneSession;

    api.sendReq(req);  
    

小程序的我们暂时就不做分享了,但是从上面的官方案例中我们可以看出分享的代码高度一致,所以小编我就顺便优化了一下,代码如下,不喜勿喷:

经过优化封装后

public class WeChatShare {
  // 第三方APP和微信通信的openApi接口
  private static IWXAPI iwxapi;
  private static Context mContext;
  private int share_to = WxShareTo.share_session;
  private int share_type = -1;
  private String url = "";
  private String title = "";
  private String description = "";
  private String shareText = "";
  private Bitmap imageBitmap = null;
  private String miniProgramId = "";
  private String miniProgramPath = "";

  public static WeChatShare regToWx(Context context) {
    mContext = context;
    // WXAPIFactory工厂,获取IWXAPI实例
    iwxapi = WXAPIFactory.createWXAPI(context, Constants.WeChat_APPID, false);
    // 注册应用
    boolean flag = iwxapi.registerApp(Constants.WeChat_APPID);
    Toast.makeText(context, "flag:" + flag, Toast.LENGTH_SHORT).show();
    return new WeChatShare();
  }

  public WeChatShare setWhere(@WxShareTo int shareTo) {
    share_to = shareTo;
    return this;
  }

  /**
   * 分享的类型
   *
   * @param type
   *
   * @return
   */
  public WeChatShare setType(@WxShareType int type) {
    share_type = type;
    return this;
  }

  /**
   * 分享的Url
   *
   * @param url
   *
   * @return
   */
  public WeChatShare addUrl(String url) {
    this.url = url;
    return this;
  }

  /**
   * 分享的标题
   *
   * @param title
   *
   * @return
   */
  public WeChatShare addTitle(String title) {
    this.title = title;
    return this;
  }

  /**
   * 描述
   *
   * @param description
   *
   * @return
   */
  public WeChatShare addDescription(String description) {
    this.description = description;
    return this;
  }

  /**
   * 分享的图片url
   *
   * @param imageUrl
   *
   * @return
   */
  public WeChatShare addImage(String imageUrl) {
    if (TextUtils.isEmpty(imageUrl)) {
      throw new NullPointerException("imageUrl is empty.");
    }
    addImage(BitmapUtils.getBitmap(imageUrl));
    return this;
  }

  /**
   * 分享的图片资源ID
   *
   * @param imageResource
   *
   * @return
   */
  public WeChatShare addImage(int imageResource) {
    addImage(BitmapFactory.decodeResource(mContext.getResources(), imageResource));
    return this;
  }

  /**
   * 分享的图片bitmap
   *
   * @param imageBitmap
   *
   * @return
   */
  public WeChatShare addImage(Bitmap imageBitmap) {
    this.imageBitmap = imageBitmap;
    return this;
  }

  /**
   * 分享的wenbennr
   *
   * @param shareText
   *
   * @return
   */
  public WeChatShare addShareText(String shareText) {
    this.shareText = shareText;
    return this;
  }

  /**
   * 分享小程序的原始Id
   *
   * @param miniProgramId
   *
   * @return
   */
  public WeChatShare addMiniProgramId(String miniProgramId) {
    this.miniProgramId = miniProgramId;
    return this;
  }

  /**
   * 分享小程序的path
   *
   * @param miniProgramPath
   *
   * @return
   */
  public WeChatShare addMiniProgramPath(String miniProgramPath) {
    this.miniProgramPath = miniProgramPath;
    return this;
  }

  public void share() {
    WXMediaMessage msg = new WXMediaMessage();
    if (share_type < 0) {
      throw new NullPointerException("you should set share type first.");
    }
    // 标题
    if (!TextUtils.isEmpty(title)) {
      msg.title = title;
    }

    // 描述
    if (!TextUtils.isEmpty(description)) {
      msg.description = description;
    }

    String transaction = "";
    switch (share_type) {
      case WxShareType.type_text:
        // 分享文本
        transaction = "text";
        msg.description = shareText;
        WXTextObject textObject = new WXTextObject();
        textObject.text = shareText;
        msg.mediaObject = textObject;
        break;
      case WxShareType.type_image:
        // 分享图片
        transaction = "img";
        if (null == imageBitmap) {
          throw new NullPointerException("bitmap is null.");
        }
        msg.mediaObject = new WXImageObject(imageBitmap);
        break;
      case WxShareType.type_video:
        // 分享视频
        transaction = "video";
        WXVideoObject videoObject;
        videoObject = new WXVideoObject();
        videoObject.videoUrl = url;
        msg.mediaObject = videoObject;
        break;
      case WxShareType.type_music:
        // 分享音频
        transaction = "music";
        WXMusicObject musicObject = new WXMusicObject();
        musicObject.musicUrl = url;
        msg.mediaObject = musicObject;
        break;
      case WxShareType.type_webPage:
        // 分享网页
        transaction = "webpage";
        WXWebpageObject webpageObject = new WXWebpageObject();
        webpageObject.webpageUrl = url;
        msg.mediaObject = webpageObject;
        break;
      case WxShareType.type_miniProgram:
        /**
         * 注: 要求发起分享的App与小程序属于同一微信开放平台帐号。
         * 小程序的原始ID获取方法:登录小程序后台-设置-基本设置-帐号信息
         */
        // 分享小程序
        if (TextUtils.isEmpty(miniProgramId)) {
          throw new NullPointerException("miniProgramId is empty.");
        }
        if (TextUtils.isEmpty(miniProgramPath)) {
          throw new NullPointerException("miniProgramPath is empty.");
        }
        if (TextUtils.isEmpty(url)) {
          throw new NullPointerException("the url for lower WeChat to open is empty.");
        }
        transaction = "webpage";
        WXMiniProgramObject miniProgramObject = new WXMiniProgramObject();
        miniProgramObject.webpageUrl = url;// 低版本微信将打开的url
        miniProgramObject.userName = miniProgramId; // 跳转的小程序的原始ID
        miniProgramObject.path = miniProgramPath; // 小程序的path
        msg.mediaObject = miniProgramObject;
        break;
    }

    // 缩略图
    if (null != imageBitmap) {
      Bitmap bmp = Bitmap.createScaledBitmap(imageBitmap, 80, 80, true);
      imageBitmap.recycle();
      msg.thumbData = BitmapUtils.Bitmap2Bytes(bmp);
    }
    sendMsg(msg, transaction);
  }

  /**
   * 调起微信分享
   *
   * @param mediaMessage
   */
  private void sendMsg(WXMediaMessage mediaMessage, String transaction) {
    if (!AppUtils.getInstance(mContext).isAppAvilible(AppUtils.WX_PKGNAME)) {
      Toast.makeText(mContext, "您还未安装微信客户端,请先安装.", Toast.LENGTH_SHORT).show();
      return;
    }
    if (TextUtils.isEmpty(transaction)) {
      throw new NullPointerException("you should set share type first.");
    }
    // 构造Req
    SendMessageToWX.Req req = new SendMessageToWX.Req();
    req.transaction = buildTransaction(transaction);
    req.message = mediaMessage;
    req.scene = share_to;
    iwxapi.sendReq(req);
  }

  private String buildTransaction(String type) {
    return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
  }
}

分享位置的参数值:

@IntDef ({ share_session, share_timeline, share_favorite })// 枚举数据
@Retention (RetentionPolicy.SOURCE) //告诉编译器在生成.class文件时不保留枚举注解数据
public @interface WxShareTo {
  // 发送到聊天界面——WXSceneSession
  int share_session = SendMessageToWX.Req.WXSceneSession;
  // 发送到朋友圈——WXSceneTimeline
  int share_favorite = SendMessageToWX.Req.WXSceneFavorite;
  // 添加到微信收藏——WXSceneFavorite
  int share_timeline = SendMessageToWX.Req.WXSceneTimeline;
}

分享类型的参数值:

@IntDef ({ type_text, type_image, type_video, type_music, type_webPage, type_miniProgram })//枚举类型
@Retention (RetentionPolicy.SOURCE) //告诉编译器在生成.class文件时不保留枚举注解数据
public @interface WxShareType {

  int type_text = 0;
  int type_image = 1;
  int type_video = 2;
  int type_music = 3;
  int type_webPage = 4;
  int type_miniProgram = 5;
}

相关工具类:

AppUtils.class

public class AppUtils {
  public static AppUtils instance;
  public static Context mContext;
  public static final String QQ_PKGNAME = "com.tencent.mobileqq";
  public static final String WX_PKGNAME = "com.tencent.mm";

  public static AppUtils getInstance(Context context) {
    mContext = context;
    if (null == instance) {
      synchronized (AppUtils.class) {
        if (null == instance) {
          instance = new AppUtils();
        }
      }
    }
    return instance;
  }

  public boolean isAppAvilible(String pkgName) {
    final PackageManager packageManager = mContext.getPackageManager();// 获取packagemanager
    List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// 获取所有已安装程序的包信息
    if (pinfo != null) {
      for (int i = 0; i < pinfo.size(); i++) {
        String pn = pinfo.get(i).packageName;
        if (pn.equals("com.tencent.mm")) {
          return true;
        }
      }
    }

    return false;
  }
}

BitmapUtils.class

public class BitmapUtils {

  /**
   * 将图片内容解析成字节数组
   *
   * @param inStream
   *
   * @return byte[]
   *
   * @throws Exception
   */
  public static byte[] readStream(InputStream inStream) throws Exception {
    byte[] buffer = new byte[1024];
    int len = -1;
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    while ((len = inStream.read(buffer)) != -1) {
      outStream.write(buffer, 0, len);
    }
    byte[] data = outStream.toByteArray();
    outStream.close();
    inStream.close();
    return data;
  }

  /**
   * 将字节数组转换为ImageView可调用的Bitmap对象
   *
   * @param bytes
   * @param opts
   *
   * @return Bitmap
   */
  public static Bitmap getPicFromBytes(byte[] bytes, BitmapFactory.Options opts) {
    if (bytes != null) {
      if (opts != null) {
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opts);
      } else {
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
      }
    }
    return null;
  }

  /**
   * 图片缩放
   *
   * @param bitmap 对象
   * @param w 要缩放的宽度
   * @param h 要缩放的高度
   *
   * @return newBmp 新 Bitmap对象
   */
  public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Matrix matrix = new Matrix();
    float scaleWidth = ((float) w / width);
    float scaleHeight = ((float) h / height);
    matrix.postScale(scaleWidth, scaleHeight);
    Bitmap newBmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    return newBmp;
  }

  /**
   * 把Bitmap转Byte
   */
  public static byte[] Bitmap2Bytes(Bitmap bm) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
    return baos.toByteArray();
  }

  /**
   * 把字节数组保存为一个文件
   */
  public static File getFileFromBytes(byte[] b, String outputFile) {
    BufferedOutputStream stream = null;
    File file = null;
    try {
      file = new File(outputFile);
      FileOutputStream fstream = new FileOutputStream(file);
      stream = new BufferedOutputStream(fstream);
      stream.write(b);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (stream != null) {
        try {
          stream.close();
        } catch (IOException e1) {
          e1.printStackTrace();
        }
      }
    }
    return file;
  }

  public static Bitmap getBitmap(String url) {
    Bitmap bm = null;
    try {
      URL iconUrl = new URL(url);
      URLConnection conn = iconUrl.openConnection();
      HttpURLConnection http = (HttpURLConnection) conn;

      int length = http.getContentLength();

      conn.connect();
      // 获得图像的字符流
      InputStream is = conn.getInputStream();
      BufferedInputStream bis = new BufferedInputStream(is, length);
      bm = BitmapFactory.decodeStream(bis);
      bis.close();
      is.close();// 关闭流
    } catch (Exception e) {
      e.printStackTrace();
    }
    return bm;
  }
}  

使用起来也很简单,如果你看过gilde或者picasso的源码,那么,一眼就能看出来该怎么使用了,在此,仅做一个文本分享的示例:

WeChatShare.regToWx(this)// 注册APP到微信
            .setWhere(WxShareTo.share_session)// 设置分享到哪边
            .setType(WxShareType.type_text) // 设置分享的类型
            .addShareText("你好") // 文本分享添加要分享的文本
            .share(); // 发起分享请求

当然有分享就该有回调,这里需要注意的是,微信规定了回调类的格式,首先你需要在包名文件夹下新建wxapi 文件夹,然后在创建 WXEntryActivity 类集成自Activity并实现微信的IWXAPIEventHandler接口,然后就可以在onReqonResq中得到回调内容,如下:

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
  public static final String TAG = WXEntryActivity.class.getSimpleName().trim();
  private IWXAPI api;

  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TextView currrentTextView = new TextView(this);
    setContentView(currrentTextView);
    api = WXAPIFactory.createWXAPI(this, Constants.WeChat_APPID, false);
    api.handleIntent(getIntent(), this);
  }

  @Override protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    api.handleIntent(intent, this);
  }

  @Override public void onReq(BaseReq baseReq) {
    Log.i(TAG, "onReq: ");
  }

  @Override public void onResp(BaseResp resp) {
    int errorCode = resp.errCode;
    Log.i(TAG, "onResp: " + errorCode);
    switch (errorCode) {
      case BaseResp.ErrCode.ERR_OK:
        //用户同意
        //String code = ((SendAuth.Resp) resp).code;
        Log.i(TAG, "ERR_OK: ");
        break;
      case BaseResp.ErrCode.ERR_AUTH_DENIED:
        //用户拒绝
        Log.i(TAG, "ERR_AUTH_DENIED: ");
        break;
      case BaseResp.ErrCode.ERR_USER_CANCEL:
        //用户取消
        Log.i(TAG, "ERR_USER_CANCEL: ");
        break;
      default:
        break;
    }
  }
}

自此,微信分享介绍完毕,不足之处,欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,613评论 4 59
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一种新的协议。它实...
    香橙柚子阅读 22,958评论 8 183
  • 原文 子曰:“不患人之不己知,患不知人也。” 译文 孔子说:“不怕别人不了解自己,只怕自己不了解别人。” 学习心得...
    幻玥阅读 3,237评论 1 4
  • 习惯形成:信号 反应程序 奖励机制 信念 拖延症是当今社会中互联网知识复杂情况而慢慢养成的习惯之一。 拖延症是怎么...
    塞弗特Mr王阅读 222评论 0 0