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