第三方分享工具类

以前都是直接集成的友盟的,但后来觉得友盟的分享,有时候要自定义那个分享弹窗有一点麻烦,所以就放弃了。这里,因为业务需要,我只集成了微信,不过QQ、微博其实也差不多,大家可以自行添加。

分享弹窗

1.自定义分享弹窗


/**
 * 分享弹窗
 * <p>
 * 作者:余天然 on 16/8/22 下午1:18
 */
public class ShareDialog extends Dialog {

    private String cover = "";//预览图
    private String target = "";//链接地址
    private String title = "";//标题
    private String desc = "";//描述

    public ShareDialog(Context context) {
        super(context, R.style.BaseDialog);
        Window window = getWindow();
        window.setGravity(Gravity.BOTTOM);
        window.setWindowAnimations(R.style.dialogAnim);
        //默认的Dialog只有5/6左右的宽度,需要改成屏幕宽度
        window.getDecorView().setPadding(0, 0, 0, 0);
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        window.setAttributes(lp);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_share);
        ButterKnife.bind(this);
        ShareHelper.init(getContext());
    }

    public void setData(String cover, String target, String title, String desc) {
        this.cover = cover;
        this.target = target;
        this.title = title;
        this.desc = desc;
    }

    @OnClick({R.id.tv_weixin, R.id.tv_pengyouquan, R.id.tv_cancel})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_weixin:
                dismiss();
                ShareHelper.performWeixin(cover, target, title, desc);
                break;
            case R.id.tv_pengyouquan:
                dismiss();
                ShareHelper.performPengyouQuan(cover, target, title, desc);
                break;
            case R.id.tv_cancel:
                dismiss();
                break;
        }
    }
}

2.依赖的资源


Dialog的Style:

    <!-- 标准的dialog的样式 -->
    <style name="BaseDialog" parent="@android:style/Theme.Dialog">
        <item name="android:windowFrame">@null</item><!-- 窗框 -->
        <item name="android:windowIsFloating">true</item><!-- 窗口浮动 -->
        <item name="android:windowIsTranslucent">@null</item><!-- 窗口半透明 -->
        <item name="android:windowNoTitle">true</item><!-- 窗口没有标题 -->
        <item name="android:windowBackground">@android:color/transparent</item><!-- 背景的颜色 -->
        <item name="android:backgroundDimEnabled">true</item><!--activity变暗-->
        <item name="android:windowContentOverlay">@null</item><!-- 窗口内容覆盖 -->
    </style>

Dialog的Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/tv_weixin"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:drawablePadding="5dp"
            android:drawableTop="@drawable/icon_share_weixin"
            android:gravity="center"
            android:padding="15dp"
            android:text="微信"
            android:textColor="@color/textTitle"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/tv_pengyouquan"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:drawablePadding="5dp"
            android:drawableTop="@drawable/icon_share_friend"
            android:gravity="center"
            android:padding="15dp"
            android:text="朋友圈"
            android:textColor="@color/textTitle"
            android:textSize="16sp"/>


    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/divide_line_height"
        android:background="#ededed"/>

    <TextView
        android:id="@+id/tv_cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="15dp"
        android:text="取消"
        android:textColor="@color/textTitle"
        android:textSize="16sp"/>

</LinearLayout>

Dialog的Anim:

    <!-- 用于弹出底部弹窗的样式 -->
    <style name="dialogAnim" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/bottom_in</item>
        <item name="android:windowExitAnimation">@anim/bottom_out</item>
    </style>

底部进入动画:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:fromYDelta="100%"
        android:toYDelta="0%"
        android:duration="300"
        android:fillAfter="true"/>

</set>

底部退出动画:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fillAfter="true"
        android:fromYDelta="0"
        android:toYDelta="100%"
    />
</set>

3.分享辅助类


/**
 * 分享辅助类
 * <p>
 * 作者:余天然 on 16/8/22 下午1:42
 */
public class ShareHelper {

    public static final String WX_ID = "***";
    public static final String WX_Key = "***";

    public static IWXAPI wxApi;

    public static void init(Context context) {
        wxApi = WXAPIFactory.createWXAPI(context, WX_ID, false);
        wxApi.registerApp(WX_ID);
    }

    /**
     * 分享到微信
     */
    public static void performWeixin(String cover, String target, String title, String desc) {
        if (checkWeixinApp()) return;
        if (checkShareFiled(cover, target, title, desc)) return;
        buildShareRequest(cover, target, title, desc)
                .map(new Func1<SendMessageToWX.Req, SendMessageToWX.Req>() {
                    @Override
                    public SendMessageToWX.Req call(SendMessageToWX.Req req) {
                        req.scene = SendMessageToWX.Req.WXSceneSession;
                        return req;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<SendMessageToWX.Req>() {
                    @Override
                    public void call(SendMessageToWX.Req req) {
                        wxApi.sendReq(req);
                    }
                });
    }

    /**
     * 分享到朋友圈
     */
    public static void performPengyouQuan(String cover, String target, String title, String desc) {
        if (checkWeixinApp()) return;
        if (checkShareFiled(cover, target, title, desc)) return;
        buildShareRequest(cover, target, title, desc)
                .map(new Func1<SendMessageToWX.Req, SendMessageToWX.Req>() {
                    @Override
                    public SendMessageToWX.Req call(SendMessageToWX.Req req) {
                        req.scene = SendMessageToWX.Req.WXSceneTimeline;
                        return req;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<SendMessageToWX.Req>() {
                    @Override
                    public void call(SendMessageToWX.Req req) {
                        wxApi.sendReq(req);
                    }
                });
    }

    /**
     * 检查分享的字段
     *
     * @param cover
     * @param target
     * @param title
     * @param desc
     * @return
     */
    private static boolean checkShareFiled(String cover, String target, String title, String desc) {
        if (TextUtils.isEmpty(cover)) {
            ToastUtil.showToastSafe("预览图不能为空!");
            return true;
        }
        if (TextUtils.isEmpty(target)) {
            ToastUtil.showToastSafe("链接地址不能为空!");
            return true;
        }
        if (TextUtils.isEmpty(title)) {
            ToastUtil.showToastSafe("分享标题不能为空");
            return true;
        }
        if (TextUtils.isEmpty(desc)) {
            ToastUtil.showToastSafe("分享描述不能为空");
            return true;
        }
        return false;
    }

    /**
     * 检查微信App
     *
     * @return
     */
    private static boolean checkWeixinApp() {
        if (!wxApi.isWXAppInstalled()) {
            ToastUtil.showToastSafe("没有安装微信客户端");
            return true;
        }
        if (!wxApi.isWXAppSupportAPI()) {
            ToastUtil.showToastSafe("当前微信版本过低");
            return true;
        }
        return false;
    }


    /**
     * 获取分享的请求体
     *
     * @param cover  预览图
     * @param target 链接地址
     * @param title  标题
     * @param desc   描述
     */
    public static Observable<SendMessageToWX.Req> buildShareRequest(String cover, String target, String title, String desc) {
        return Observable.create(subscriber -> {
            try {
                LogUtil.print("cover=" + cover + "\ttarget=" + target + "\ttitle=" + title + "\tdesc=" + desc);

                WXWebpageObject webObj = new WXWebpageObject();
                webObj.webpageUrl = target;

                WXMediaMessage msg = new WXMediaMessage(webObj);
                msg.title = title;
                msg.description = desc;
                Bitmap bmp = loadBitmap(cover);
                msg.thumbData = getBitmapBytes(bmp);
                bmp.recycle();

                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("webpage");
                req.message = msg;
                subscriber.onNext(req);
                subscriber.onCompleted();
            } catch (Exception e) {
                subscriber.onError(e);
            }
        });
    }


    /**
     * 根据图片的url路径获得Bitmap对象
     *
     * @param url
     * @return
     */
    public static Bitmap loadBitmap(String url) {
        URL fileUrl = null;
        Bitmap bitmap = null;
        try {
            fileUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) fileUrl.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    /**
     * Bitmap -> byte[]
     *
     * @param sourceBitmap
     * @return
     */
    public static byte[] getBitmapBytes(Bitmap sourceBitmap) {
        Bitmap bitmap = Bitmap.createScaledBitmap(sourceBitmap, DensityUtil.dp2px(80), DensityUtil.dp2px(60), true);
        byte[] bytes = compressBitmap(bitmap, 30);
        sourceBitmap.recycle();
        bitmap.recycle();
        return bytes;
    }

    /**
     * 压缩图片到指定大小
     *
     * @param image
     * @param maxSize
     * @return
     */
    public static byte[] compressBitmap(Bitmap image, int maxSize) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.PNG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > maxSize) { // 循环判断如果压缩后图片是否大于maxSize kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
        }
        return baos.toByteArray();
    }

    /**
     * 创建事务描述
     *
     * @param type
     * @return
     */
    public static String buildTransaction(final String type) {
        return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
    }

}

4.微信回调类:

/**
 * 作者:余天然 on 16/8/22 下午4:16
 */
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ShareHelper.wxApi.handleIntent(getIntent(), this);
    }

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

    @Override
    public void onReq(BaseReq req) {

    }


    @Override
    public void onResp(BaseResp resp) {
        if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
            finish();
            ToastUtil.showToastSafe("分享成功");
        } else if (resp.errCode == BaseResp.ErrCode.ERR_USER_CANCEL) {
            finish();
            ToastUtil.showToastSafe("取消成功");
        } else {
            finish();
            ToastUtil.showToastSafe("分享失败");
        }
        EventBus.getDefault().post(new HideShare());
    }
}

5.调用方法:


这里的ivShare是一个分享的按钮。

        ivShare.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                shareDialog = new ShareDialog(getActivity());
                shareDialog.show();
                shareDialog.setData(cover, target, title, desc);
            }
        });
2016-10-29 13:4820