微信朋友圈视频分享Android

app中有个这样的需求,把app生成好的视频,直接分享到微信朋友圈。目前暂时没有这样的第三方Sdk可以直接使用。所以一切得自己想办法

方案思路

微信在发朋友圈时,会在tencent/misromsg/weixin/文件夹下生成wx_camera_当前时间.mp4 而我们的目标就是直接替换掉他生成的文件把我们的小视频,狸猫换太子。这样最后发出来的小视频就变成我们自己的小视频了下面贴一下代码

同理这样的方法还可以用于,陌陌

用到的主要的ShareService

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;

import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.wanyueliang.avm.R;
import com.wanyueliang.avm.config.AppConfig;
import com.wanyueliang.avm.utils.file.ClearUtils;
import com.wanyueliang.avm.utils.global.AppGlobal;
import com.wanyueliang.avm.utils.global.FileWatcherUtil;
import com.wanyueliang.avm.utils.message.ToastAlone;

public class ShareService extends Service {

    private Context mContext = null;
    private PendingIntent pintent;
    private String message;
    private FileWatcherUtil fileWatcherUtil;

    public ShareService() {

    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, final int startId) {
        mContext = getApplicationContext();

        if (AppConfig.needRestartShare) {
            AppConfig.needRestartShare = false;
            try {
                ClearUtils.repairVideoCache(mContext, new ClearUtils.ClearCallBack() {
                    public void clearCallBack(boolean result, String message) {
                        String formPath = intent.getStringExtra("formPath");
                        String imagePath = intent.getStringExtra("imagePath");
                        final int shareType = intent.getIntExtra("shareType", 0);

                        serviceMessage(shareType);// 判断发送类型

                        useStartForGround(intent, startId);// 设置前台服务

                        fileWatcherUtil = FileWatcherUtil.getInstance();
                        fileWatcherUtil.setData(mContext, shareType, imagePath, formPath, new FileWatcherUtil.FileWatcherListener() {
                            @Override
                            public void preparedListener() {
                                ShareType(shareType, mContext);
                                AppGlobal.SHOW_SHARE_TOAST = true;
                                fileWatcherUtil.startWatching();
                            }

                            @Override
                            public void successListener() {
                                resultToast(0);
                                fileWatcherUtil.stopWatching();
                                stopSelf();

                            }

                            @Override
                            public void errorListener(int errorType) {

                                resultToast(errorType);
                                fileWatcherUtil.stopWatching();
                                stopSelf();

                            }
                        });

                    }
                });

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return START_NOT_STICKY;
    }

    private static boolean ShareType(int shareType, Context mContext) {

        boolean haveAPP = false;

        switch (shareType) {
            case AppConfig.DIRECT_SHARE_WEIXIN_CIRCLE:

                haveAPP = openWeiXin(mContext);

                break;
            case AppConfig.DIRECT_SHARE_MOMO:

                haveAPP = openMOMO(mContext);

                break;
            case AppConfig.DIRECT_SHARE_ALIPAY_CIRCLE:
                haveAPP = openZhifubao(mContext);

                break;

        }

        return haveAPP;
    }

    private static boolean openZhifubao(Context mContext) {

        boolean openWXApp = false;
        try {
            mContext.startActivity(mContext.getPackageManager().getLaunchIntentForPackage("com.eg.android.AlipayGphone"));
            openWXApp = true;
        } catch (Exception e) {
            e.printStackTrace();
            openWXApp = false;

        }
        return openWXApp;
    }

    private static boolean openMOMO(Context mContext) {

        boolean openWXApp = false;
        try {
            mContext.startActivity(mContext.getPackageManager().getLaunchIntentForPackage("com.immomo.momo"));
            openWXApp = true;
        } catch (Exception e) {
            e.printStackTrace();
            openWXApp = false;

        }
        return openWXApp;
    }

    /* 打开微信 */
    private static boolean openWeiXin(Context mContext) {

        IWXAPI iwxapi = WXAPIFactory.createWXAPI(mContext, "");

        return iwxapi.openWXApp();
    }

    private void useStartForGround(Intent intent, int startId) {


        pintent = PendingIntent.getService(this, 0, intent, 0);

        Notification.Builder builder = setLatestEventInfo(this, getString(R.string.sharing), message, pintent);
        builder.setWhen(System.currentTimeMillis());
        builder.setSmallIcon(R.mipmap.applogo);

        builder.setTicker(getString(R.string.sharing));

        Notification notification = builder.getNotification();

        // 让该service前台运行,避免手机休眠时系统自动杀掉该服务
        // 如果 id 为 0 ,那么状态栏的 notification 将不会显示。
        startForeground(startId, notification);

    }

    public Notification.Builder setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
        Notification.Builder builder = new Notification.Builder(context);


        // now apply the latestEventInfo fields
        if (contentTitle != null) {
            builder.setContentTitle(contentTitle);
        }
        if (contentText != null) {
            builder.setContentText(contentText);
        }
        builder.setContentIntent(contentIntent);

        return builder;


    }

    private void serviceMessage(int shareType) {
        switch (shareType) {
            case AppConfig.DIRECT_SHARE_WEIXIN_CIRCLE:

                message = String.format(getString(R.string.share_to_app), getString(R.string.wechat));

                break;
            case AppConfig.DIRECT_SHARE_MOMO:

                message = String.format(getString(R.string.share_to_app), getString(R.string.momo));

                break;

            case AppConfig.DIRECT_SHARE_ALL_K:

                message = String.format(getString(R.string.share_to_app), getString(R.string.all_k));

                break;
            case AppConfig.DIRECT_SHARE_ALIPAY_CIRCLE:

                message = String.format(getString(R.string.share_to_app), getString(R.string.alipay));

                break;

            default:
                message = String.format(getString(R.string.share_to_app), getString(R.string.default_app));

                break;

        }
    }

    @Override
    public void onDestroy() {
        stopForeground(true);
        super.onDestroy();
    }

    /**
     * @param errorMessage
     */
    private void resultToast(int errorMessage) {

        String tostMessage = null;

        switch (errorMessage) {
            case FileWatcherUtil.SUCCESS:// 操作成功
                tostMessage = getString(R.string.send_circle_action_success);
                break;
            case FileWatcherUtil.ERROR_NO_ACCOUNT:// 未找到账号
                tostMessage = getString(R.string.send_circle_failed_notfound_account);
                break;
            case FileWatcherUtil.ERROR_NO_FILE:// 文件不存在
                tostMessage = getString(R.string.send_circle_failed_notfound_file);
                break;
            case FileWatcherUtil.ERROR_COPY_FAIL:// 操作失败
                tostMessage = getString(R.string.send_circle_action_failed);
                break;
            default:
                tostMessage = getString(R.string.send_circle_failed);
                break;
        }

        AppGlobal.sendExceptionLogRequest(mContext, "[Send Circle NG]" + tostMessage);

        ToastAlone.showToast(mContext, tostMessage);

    }
}

接下来就是用到的两个工具类

import android.content.Context;
import android.os.Handler;

import java.io.File;
import java.io.FileFilter;

public class ClearUtils {

    private static String TAG = "ClearUtils";
    private static Handler handler = new Handler();
    private static String resultMessage;
    private static ClearCallBack resultClearCallBack;

    private static String searchPath;// 查找的路径

    private static boolean needClear;// 是否需要清理
    private static int fileCount = 0;// 计数
    private static int needClearCount = 500;// 超过该数量就清理一次
    private static int clearDay = 7;// 清除超过该天数的文件

    private static FileFilter fileFilter = new FileFilter() {
        @Override
        public boolean accept(File pathname) {

            if (pathname.canRead() && pathname.canWrite() && !pathname.isHidden()) {

                return true;
            }

            return false;
        }
    };

    // 清理视频缓存
    public static void repairVideoCache(final Context context, final ClearCallBack clearCallBack) {
        resultClearCallBack = clearCallBack;
        resultMessage = null;

        needClear = false;
        fileCount = 0;

        Runnable runnable = new Runnable() {
            @Override
            public void run() {

                String SdcardPath = null;// SD0

                String SdcardPath2 = null;// SD1

                StorageList storageList = new StorageList(context);

                String path[] = storageList.getVolumePaths();

                if (path != null && path.length > 0) {

                    if (path.length == 1) {
                        SdcardPath = path[0];

                    } else if (path.length >= 2) {
                        SdcardPath = path[0];
                        SdcardPath2 = path[1];

                    }
                }

                String weiXinPath = "/tencent" + "/MicroMsg";

                searchPath = SdcardPath + weiXinPath;

                serachAccount(searchPath);

                if (SdcardPath2 != null) {
                    searchPath = SdcardPath2 + weiXinPath;

                    serachAccount(searchPath);
                }

                handler.removeCallbacksAndMessages(null);

                if (resultMessage == null) {
                    // String Message = mContext.getString(R.string.repaired);//清理完成
                    setCallBackMessage(true, "");
                }
            }
        };

        handler.postDelayed(runnable, 5);

    }

    private static void serachAccount(String searchPath) {

        File file = new File(searchPath);
        if (file.exists()) {

            File[] files = file.listFiles(fileFilter);

            if (files != null && files.length > 0) {

                for (File accountFile : files) {

                    if (accountFile.getName().length() > 16 && file.isDirectory()) {

                        repailTypeOne(accountFile);

                    }
                }
            }

            needClear = false;
            fileCount = 0;

        } else {
            // String Message = mContext.getString(R.string.repair_fail) + file.getAbsolutePath();////清理完成

            // setCallBackMessage(false, "");

        }

    }

    private static void setCallBackMessage(boolean result, String message) {
        if (resultMessage == null) {
            resultMessage = message;
            if (resultClearCallBack != null) {
                resultClearCallBack.clearCallBack(result, resultMessage);
                handler.removeCallbacksAndMessages(null);
            }

        }

    }

    private static void repailTypeOne(File accountFile) {
        String videoPath = accountFile.getAbsolutePath() + "/video";

        File videoPathDir = new File(videoPath);

        if (videoPathDir.exists()) {

            File[] filesVideo = videoPathDir.listFiles(fileFilter);

            if (filesVideo != null && filesVideo.length > 0) {

                for (File deleteVideo : filesVideo) {

                    if (needClear) {
                        deleteAllFilesOfDir(deleteVideo);

                    } else {
                        fileCount++;// 统计视频数量
                        if (fileCount > needClearCount) {
                            needClear = true;
                            serachAccount(searchPath);
                        }

                    }

                }
            }

        }
    }

    private static void deleteAllFilesOfDir(File path) {
        if (!path.exists())
            return;
        if (path.isFile()) {

            if (checkTime(path)) {

                path.delete();
            }
            return;
        }
        File[] files = path.listFiles(fileFilter);
        for (int i = 0; i < files.length; i++) {
            deleteAllFilesOfDir(files[i]);
        }
        path.delete();
    }

    // 当视频总的数量大于500的时候清理最近十五天的视频
    private static boolean checkTime(File path) {

        long subTime = (System.currentTimeMillis() - path.lastModified()) / (3600L * 1000L);

        if (subTime > 24 * clearDay) {
            return true;
        } else {
            return false;
        }
    }

    public interface ClearCallBack {
        void clearCallBack(boolean result, String message);
    }
}

最后一个

import android.content.Context;

import com.wanyueliang.avm.config.AppConfig;

public class FileWatcherUtil {

    private String TAG = "FileWatcherUtil";
    private static FileWatcherUtil fileWatcherUtil;

    private WatcherActionListener watcherActionListener;

    public static final int SUCCESS = 0;
    public static final int ERROR_NO_ACCOUNT = -1;
    public static final int ERROR_NO_FILE = -2;
    public static final int ERROR_COPY_FAIL = -3;

    private FileWatcherUtil() {

    }

    public static FileWatcherUtil getInstance() {
        if (fileWatcherUtil == null) {
            synchronized (FileWatcherUtil.class) {
                fileWatcherUtil = new FileWatcherUtil();
            }
        }
        return fileWatcherUtil;
    }

    public void setData(Context mContext, int shareType, String myCover, String myVideo, FileWatcherListener fileWatcherListener) {
        stopWatching();
        if (shareType == AppConfig.DIRECT_SHARE_WEIXIN_CIRCLE) {
            watcherActionListener = WeChatUtils.getInstance(mContext);
            watcherActionListener.setData(myCover, myVideo, fileWatcherListener);
        }
        if (shareType == AppConfig.DIRECT_SHARE_MOMO) {
            watcherActionListener = MoMoUtils.getInstance(mContext);
            watcherActionListener.setData(myCover, myVideo, fileWatcherListener);
        }
        if (shareType == AppConfig.DIRECT_SHARE_ALIPAY_CIRCLE) {
            watcherActionListener = AliPayUtils.getInstance(mContext);
            watcherActionListener.setData(myCover, myVideo, fileWatcherListener);
        }

    }

    public void startWatching() {
        if (watcherActionListener != null) {
            watcherActionListener.startWatching();
        }
    }

    public void stopWatching() {
        if (watcherActionListener != null) {
            watcherActionListener.stopWatching();
        }
    }

    public interface WatcherActionListener {

        void setData(String myCover, String myVideo, FileWatcherListener fileWatcherListener);

        void stopWatching();

        void startWatching();

    }

    public interface FileWatcherListener {

        void preparedListener();

        void successListener();

        void errorListener(int errorType);

    }

}

代码贴完了最后怎么用呢?ez

finalString localCoverFilePath = tempFile.getAbsolutePath() + AppConfig.FILE_SUFFIX_PNG;

Glide.with(mContext).load(tempFile.getAbsolutePath()).into(newCropSimpleTarget() {

@Override

protected voidonCompressFinish(GlideDrawable resource) {

EventBus.getDefault().post(newShareFilmEvent(WXCirclePlatform.PLATFORM_ID));

Bitmap bitmap = BitmapUtils.drawableToBitmap(resource);

BitmapUtils.compressImage(bitmap,localCoverFilePath,100);

Intentintent =newIntent(mContext,ShareService.class);

mContext.stopService(intent);

intent.putExtra("formPath",tempFile.getAbsolutePath());

intent.putExtra("imagePath",localCoverFilePath);

intent.putExtra("shareType",0);// 0:微信 1:陌陌 2:全民K歌 3:支付宝

AppConfig.needRestartShare=true;

mContext.startService(intent);

}

});

这里是以微信朋友圈为实例,当然其他的app也是可以通过这种方法实现发布你想要发的小视频,只要你找到Api

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

推荐阅读更多精彩内容