Files
youle_app_zhuoyitong/ref/DouYinIntentShareUtil.java

1010 lines
40 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.tsgame.tsgame_niuniu.util;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
/**
* 抖音分享工具类 - 无需SDK使用Intent实现
*/
public class DouYinIntentShareUtil {
private static final String TAG = "DouYinIntentShareUtil";
// 抖音可能的包名列表,不同版本或地区的抖音可能使用不同的包名
private static final String DOUYIN_PACKAGE_NAME = "com.ss.android.ugc.aweme";
private static final String DOUYIN_LITE_PACKAGE_NAME = "com.ss.android.ugc.aweme.lite";
private static final String DOUYIN_GLOBAL_PACKAGE_NAME = "com.zhiliaoapp.musically";
// 可能的抖音包名列表
private static final List<String> DOUYIN_PACKAGES = Arrays.asList(
DOUYIN_PACKAGE_NAME, // 主要抖音包名
DOUYIN_LITE_PACKAGE_NAME, // 抖音极速版
DOUYIN_GLOBAL_PACKAGE_NAME // TikTok国际版
);
private static DouYinIntentShareUtil instance;
private final Context mContext;
private DouYinShareCallback mCallback;
// 缓存已安装的抖音包名
private String installedDouYinPackage = null;
private DouYinIntentShareUtil(Context context) {
this.mContext = context.getApplicationContext();
}
public static DouYinIntentShareUtil getInstance(Context context) {
if (instance == null && context != null) {
instance = new DouYinIntentShareUtil(context);
}
return instance;
}
/**
* 设置分享回调
* @param callback 分享回调
*/
public void setShareCallback(DouYinShareCallback callback) {
this.mCallback = callback;
}
/**
* 检查抖音是否已安装
* @return 是否安装
*/
public boolean isDouyinInstalled() {
// 如果之前已找到包名直接返回true
if (installedDouYinPackage != null) {
return true;
}
// 检查所有可能的抖音包名
PackageManager pm = mContext.getPackageManager();
for (String packageName : DOUYIN_PACKAGES) {
try {
pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
// 找到已安装的抖音,缓存包名
installedDouYinPackage = packageName;
Log.d(TAG, "找到已安装的抖音: " + packageName);
return true;
} catch (PackageManager.NameNotFoundException e) {
// 继续检查下一个包名
continue;
}
}
Log.d(TAG, "未找到已安装的抖音应用");
return false;
}
/**
* 获取已安装的抖音包名
* @return 抖音包名,如果未安装则返回默认包名
*/
private String getInstalledDouYinPackage() {
if (installedDouYinPackage != null) {
return installedDouYinPackage;
}
// 如果没有缓存,重新检测
isDouyinInstalled();
return installedDouYinPackage != null ? installedDouYinPackage : DOUYIN_PACKAGE_NAME;
}
/**
* 与isDouyinInstalled方法功能相同保持兼容性
* @return 是否安装抖音
*/
public boolean isDouYinInstalled() {
return isDouyinInstalled();
}
/**
* 通过各种方法尝试启动抖音应用
* @param activity 活动上下文
* @return 是否成功启动
*/
private boolean tryLaunchDouyin(Activity activity) {
try {
String packageName = getInstalledDouYinPackage();
Log.d(TAG, "尝试启动抖音,包名: " + packageName);
// 方法1使用标准启动方式
Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName);
if (launchIntent != null) {
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivity(launchIntent);
Log.d(TAG, "成功使用标准方式启动抖音");
return true;
}
// 方法2使用ACTION_MAIN + CATEGORY_LAUNCHER
try {
Intent mainIntent = new Intent(Intent.ACTION_MAIN);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
mainIntent.setPackage(packageName);
List<android.content.pm.ResolveInfo> resolveInfoList =
activity.getPackageManager().queryIntentActivities(mainIntent, 0);
if (resolveInfoList != null && !resolveInfoList.isEmpty()) {
android.content.pm.ResolveInfo resolveInfo = resolveInfoList.get(0);
String className = resolveInfo.activityInfo.name;
Intent componentIntent = new Intent(Intent.ACTION_MAIN);
componentIntent.addCategory(Intent.CATEGORY_LAUNCHER);
componentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
componentIntent.setComponent(new ComponentName(packageName, className));
activity.startActivity(componentIntent);
Log.d(TAG, "成功使用组件方式启动抖音");
return true;
}
} catch (Exception e) {
Log.e(TAG, "方法2失败: " + e.getMessage());
}
// 尝试所有可能的抖音URI schemes
String[] schemes = {
"snssdk1128://", // 原有scheme
"aweme://", // 原有scheme
"douyin://", // 新增scheme
"douyinlite://", // 抖音极速版scheme
"snssdk1128://feed", // 带路径的scheme
"aweme://feed", // 带路径的scheme
"douyin://feed", // 带路径的scheme
"snssdk1128://home/trending", // 热门页
"douyin://home/trending", // 热门页
"snssdk1128://post", // 发布页
"douyin://post" // 发布页
};
for (String scheme : schemes) {
try {
Intent schemeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(scheme));
schemeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
// 如果设置包名,可以确保只打开抖音应用
schemeIntent.setPackage(packageName);
activity.startActivity(schemeIntent);
Log.d(TAG, "成功使用scheme方式启动抖音: " + scheme);
return true;
} catch (Exception e) {
Log.e(TAG, "scheme方式失败 " + scheme + ": " + e.getMessage());
// 继续尝试下一个scheme
}
}
// 方法4尝试使用系统VIEW处理
try {
Intent viewIntent = new Intent(Intent.ACTION_VIEW);
viewIntent.setData(Uri.parse("https://www.douyin.com"));
viewIntent.setPackage(packageName);
viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(viewIntent);
Log.d(TAG, "成功使用Web链接方式启动抖音");
return true;
} catch (Exception e) {
Log.e(TAG, "Web链接方式失败: " + e.getMessage());
}
Log.e(TAG, "所有启动抖音的方法均失败");
return false;
} catch (Exception e) {
Log.e(TAG, "启动抖音过程中发生异常: " + e.getMessage(), e);
return false;
}
}
/**
* 分享纯文本到抖音
* @param activity 活动
* @param text 要分享的文本
*/
public void shareTextToDouyin(Activity activity, String text) {
if (!isDouyinInstalled()) {
handleNotInstalled(activity);
return;
}
try {
// 使用兼容方式复制到剪贴板
copyToClipboard(activity, text);
// 尝试通过各种方式启动抖音
boolean launched = tryLaunchDouyin(activity);
if (launched) {
Toast.makeText(activity, "已将内容复制到剪贴板,请在抖音中粘贴并分享", Toast.LENGTH_LONG).show();
// 假设分享成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
return;
}
// 如果所有方法都失败了,尝试使用系统分享菜单
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, text);
Intent chooser = Intent.createChooser(shareIntent, "分享到");
activity.startActivity(chooser);
Toast.makeText(activity, "请从分享列表中选择抖音", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
} catch (Exception e) {
Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e);
handleShareException(activity, e);
}
}
/**
* 分享图片到抖音
* @param activity 活动
* @param localImagePath 本地图片路径
*/
public void shareImageToDouyin(Activity activity, String localImagePath) {
if (!isDouyinInstalled()) {
handleNotInstalled(activity);
return;
}
File imageFile = new File(localImagePath);
if (!imageFile.exists()) {
Toast.makeText(activity, "分享图片不存在", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-2, "图片文件不存在");
}
return;
}
try {
String packageName = getInstalledDouYinPackage();
// 创建分享Intent
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setPackage(packageName); // 指定只分享到抖音
shareIntent.setType("image/*");
// 根据Android版本使用不同的Uri方式
Uri imageUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// Android 7.0及以上使用FileProvider
imageUri = FileProviderUtil.getUriForFile(activity, imageFile);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
// Android 7.0以下直接使用文件Uri
imageUri = Uri.fromFile(imageFile);
}
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
try {
activity.startActivity(shareIntent);
Log.d(TAG, "已发送分享图片Intent到抖音");
// 延迟回调成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
} catch (android.content.ActivityNotFoundException e) {
Log.e(TAG, "直接分享到抖音失败,尝试使用选择器: " + e.getMessage());
// 如果直接分享失败,使用选择器
Intent chooserIntent = Intent.createChooser(shareIntent.setPackage(null), "分享到抖音");
activity.startActivity(chooserIntent);
Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show();
// 假设分享成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
}
} catch (Exception e) {
Log.e(TAG, "分享图片到抖音失败: " + e.getMessage(), e);
handleShareException(activity, e);
}
}
/**
* 分享多张图片到抖音
* @param activity 活动
* @param imagePaths 图片路径列表
*/
public void shareImagesToDouyin(Activity activity, ArrayList<String> imagePaths) {
if (!isDouyinInstalled()) {
handleNotInstalled(activity);
return;
}
if (imagePaths == null || imagePaths.isEmpty()) {
Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-1, "分享图片为空");
}
return;
}
try {
ArrayList<Uri> imageUris = new ArrayList<>();
for (String path : imagePaths) {
File file = new File(path);
if (file.exists()) {
// 根据Android版本使用不同的Uri方式
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// Android 7.0及以上使用FileProvider
Uri fileUri = FileProviderUtil.getUriForFile(activity, file);
imageUris.add(fileUri);
} else {
// Android 7.0以下直接使用文件Uri
imageUris.add(Uri.fromFile(file));
}
}
}
if (imageUris.isEmpty()) {
Toast.makeText(activity, "没有有效图片可分享", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-1, "没有有效图片可分享");
}
return;
}
Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
// 获取已安装的抖音包名
String packageName = getInstalledDouYinPackage();
intent.setPackage(packageName);
intent.setType("image/*");
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
try {
startShareActivity(activity, intent);
} catch (Exception e) {
// 如果直接分享失败,使用系统分享选择器
Log.d(TAG, "多图直接分享失败,使用系统分享: " + e.getMessage());
Intent chooser = Intent.createChooser(intent.setPackage(null), "分享到抖音");
activity.startActivity(chooser);
Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
handleShareException(activity, e);
}
}
/**
* 分享Bitmap到抖音
* @param activity 活动
* @param bitmap 位图
*/
public void shareBitmapToDouyin(Activity activity, Bitmap bitmap) {
if (bitmap == null) {
Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-1, "分享图片为空");
}
return;
}
// 直接在此类中实现保存Bitmap到临时文件的功能避免依赖外部工具类
try {
File cacheDir = activity.getExternalCacheDir();
if (cacheDir == null) {
cacheDir = activity.getCacheDir();
}
File imageFile = new File(cacheDir, "douyin_share_" + UUID.randomUUID().toString() + ".jpg");
FileOutputStream fos = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
// 保存成功,分享图片
shareImageToDouyin(activity, imageFile.getAbsolutePath());
} catch (Exception e) {
Toast.makeText(activity, "保存图片失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-2, "保存图片失败: " + e.getMessage());
}
}
}
/**
* 分享视频到抖音
* @param activity 活动
* @param videoPath 视频路径
*/
public void shareVideoToDouyin(Activity activity, String videoPath) {
if (!isDouyinInstalled()) {
handleNotInstalled(activity);
return;
}
File videoFile = new File(videoPath);
if (!videoFile.exists()) {
Toast.makeText(activity, "视频文件不存在", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-2, "视频文件不存在");
}
return;
}
try {
Intent intent = new Intent(Intent.ACTION_SEND);
// 获取已安装的抖音包名
String packageName = getInstalledDouYinPackage();
intent.setPackage(packageName);
intent.setType("video/*");
// 根据Android版本使用不同的Uri方式
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// Android 7.0及以上使用FileProvider
Uri videoUri = FileProviderUtil.getUriForFile(activity, videoFile);
intent.putExtra(Intent.EXTRA_STREAM, videoUri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
// Android 7.0以下直接使用文件Uri
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(videoFile));
}
try {
startShareActivity(activity, intent);
} catch (Exception e) {
// 如果直接分享失败,使用系统分享选择器
Log.d(TAG, "视频直接分享失败,使用系统分享: " + e.getMessage());
Intent chooser = Intent.createChooser(intent.setPackage(null), "分享到抖音");
activity.startActivity(chooser);
Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
handleShareException(activity, e);
}
}
/**
* 分享网页链接到抖音
* 抖音不支持直接分享网页,只能通过文本方式
* @param activity 活动
* @param title 标题
* @param description 描述
* @param webUrl 网页链接
*/
public void shareWebPageToDouyin(Activity activity, String title, String description, String webUrl) {
if (!isDouyinInstalled()) {
handleNotInstalled(activity);
return;
}
// 抖音只能通过文本方式分享网页链接
StringBuilder sb = new StringBuilder();
if (!TextUtils.isEmpty(title)) {
sb.append(title).append("\n\n");
}
if (!TextUtils.isEmpty(description)) {
sb.append(description).append("\n\n");
}
if (!TextUtils.isEmpty(webUrl)) {
sb.append(webUrl);
}
shareTextToDouyin(activity, sb.toString());
}
/**
* 分享网页链接到抖音
* @param activity 活动
* @param url 要分享的网页链接
* @param title 分享标题,可选
* @param description 分享描述,可选
*/
public void shareWebpageToDouyin(Activity activity, String url, String title, String description) {
if (!isDouyinInstalled()) {
handleNotInstalled(activity);
return;
}
if (TextUtils.isEmpty(url)) {
Toast.makeText(activity, "分享链接不能为空", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-1, "分享链接不能为空");
}
return;
}
try {
String packageName = getInstalledDouYinPackage();
// 构建完整分享内容
StringBuilder shareContent = new StringBuilder();
if (!TextUtils.isEmpty(title)) {
shareContent.append(title).append("\n");
}
if (!TextUtils.isEmpty(description)) {
shareContent.append(description).append("\n");
}
shareContent.append(url);
// 复制到剪贴板,便于用户在抖音中粘贴
copyToClipboard(activity, shareContent.toString());
// 方法1: 尝试使用系统分享直接发送到抖音
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setPackage(packageName); // 指定只分享到抖音
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, shareContent.toString());
try {
activity.startActivity(shareIntent);
Log.d(TAG, "已发送网页分享Intent到抖音");
// 延迟回调成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
return;
} catch (android.content.ActivityNotFoundException e) {
Log.e(TAG, "直接分享网页到抖音失败,尝试替代方法: " + e.getMessage());
}
// 方法2: 如果直接分享失败尝试使用VIEW操作打开抖音分享页面
try {
// 抖音支持的分享scheme尝试不同的形式
String[] shareSchemes = {
"snssdk1128://share?content=" + Uri.encode(shareContent.toString()),
"douyin://share?content=" + Uri.encode(shareContent.toString()),
"aweme://share?content=" + Uri.encode(shareContent.toString())
};
for (String scheme : shareSchemes) {
try {
Intent schemeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(scheme));
schemeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
schemeIntent.setPackage(packageName);
activity.startActivity(schemeIntent);
Log.d(TAG, "成功使用scheme方式分享网页到抖音: " + scheme);
// 延迟回调成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
return;
} catch (Exception schemeEx) {
Log.e(TAG, "scheme方式分享失败 " + scheme + ": " + schemeEx.getMessage());
// 继续尝试下一个scheme
}
}
} catch (Exception e) {
Log.e(TAG, "scheme分享过程中出现异常: " + e.getMessage());
}
// 方法3: 如果前两种方法都失败,启动抖音并提示用户手动粘贴分享
boolean launched = tryLaunchDouyin(activity);
if (launched) {
Toast.makeText(activity, "已将链接复制到剪贴板,请在抖音中粘贴并分享", Toast.LENGTH_LONG).show();
// 假设分享成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
return;
}
// 方法4: 如果启动抖音也失败,尝试使用系统分享选择器
Intent chooserIntent = Intent.createChooser(shareIntent.setPackage(null), "分享到");
activity.startActivity(chooserIntent);
Toast.makeText(activity, "请从分享列表中选择抖音", Toast.LENGTH_SHORT).show();
// 假设分享成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
} catch (Exception e) {
Log.e(TAG, "分享网页过程中出现异常: " + e.getMessage(), e);
handleShareException(activity, e);
}
}
/**
* 启动分享Activity - 不再直接调用,使用系统分享菜单代替
*/
private void startShareActivity(Activity activity, Intent intent) {
try {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 创建选择器并提示用户选择抖音
Intent chooser = Intent.createChooser(intent, "分享到抖音");
activity.startActivity(chooser);
Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show();
// 假设分享成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
} catch (Exception e) {
handleShareException(activity, e);
}
}
/**
* 处理未安装抖音的情况
*/
private void handleNotInstalled(Activity activity) {
Toast.makeText(activity, "请先安装抖音客户端", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-1, "未安装抖音客户端");
}
}
/**
* 处理分享异常
*/
private void handleShareException(Activity activity, Exception e) {
Toast.makeText(activity, "分享失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-3, "分享失败: " + e.getMessage());
}
}
/**
* 处理抖音分享结果回调
* @param req 请求对象
* @param resp 响应对象
*/
public void handleShareResult(Object req, Object resp) {
if (resp == null) {
return;
}
try {
// 尝试通过反射获取状态码
int errorCode = -1;
String errorMsg = "未知错误";
try {
// 尝试从响应对象获取状态码和错误信息
Class<?> respClass = resp.getClass();
java.lang.reflect.Field errCodeField = respClass.getDeclaredField("errCode");
java.lang.reflect.Field errStrField = respClass.getDeclaredField("errStr");
errCodeField.setAccessible(true);
errStrField.setAccessible(true);
errorCode = (int) errCodeField.get(resp);
errorMsg = (String) errStrField.get(resp);
} catch (Exception e) {
// 反射失败尝试通过toString()方法解析响应信息
String respStr = resp.toString();
if (respStr.contains("errCode=")) {
try {
int startIndex = respStr.indexOf("errCode=") + 8;
int endIndex = respStr.indexOf(",", startIndex);
if (endIndex < 0) {
endIndex = respStr.indexOf("}", startIndex);
}
if (endIndex > startIndex) {
errorCode = Integer.parseInt(respStr.substring(startIndex, endIndex).trim());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
// 根据错误码处理不同的结果
if (errorCode == 0) {
// 分享成功
if (mCallback != null) {
mCallback.onSuccess();
}
} else if (errorCode == -2) {
// 用户取消
if (mCallback != null) {
mCallback.onCancel();
}
} else {
// 分享失败
if (mCallback != null) {
mCallback.onError(errorCode, errorMsg);
}
}
} catch (Exception e) {
e.printStackTrace();
if (mCallback != null) {
mCallback.onError(-1, "处理分享结果异常: " + e.getMessage());
}
}
}
/**
* 分享内容到抖音私信
* @param activity 活动上下文
* @param content 要分享的内容
* @param mediaUri 要分享的媒体Uri (可为null)
* @param mediaType 媒体类型 ("image"或"video"仅在mediaUri不为null时有效)
* @return 是否成功启动分享
*/
public boolean shareToPrivateMessage(Activity activity, String content, Uri mediaUri, String mediaType) {
if (!isDouyinInstalled()) {
handleNotInstalled(activity);
return false;
}
try {
// 简化处理:将文本复制到剪贴板
if (content != null && !content.isEmpty()) {
copyToClipboard(activity, content);
Toast.makeText(activity, "内容已复制到剪贴板,请在抖音中粘贴发送", Toast.LENGTH_LONG).show();
}
// 直接启动抖音主应用
boolean launched = tryLaunchDouyin(activity);
if (launched) {
// 成功启动,提示用户操作步骤
Toast.makeText(activity, "请点击抖音底部\"消息\"按钮,选择联系人并粘贴内容", Toast.LENGTH_LONG).show();
// 假设操作成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
return true;
} else {
// 启动失败
Toast.makeText(activity, "无法启动抖音,请手动打开抖音进行分享", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-1, "无法启动抖音");
}
return false;
}
} catch (Exception e) {
Log.e(TAG, "分享到抖音私信过程中发生异常: " + e.getMessage(), e);
if (mCallback != null) {
mCallback.onError(-1, "分享失败: " + e.getMessage());
}
return false;
}
}
/**
* 分享内容到抖音群聊
* @param activity 活动上下文
* @param content 要分享的内容
* @param mediaUri 要分享的媒体Uri (可为null)
* @param mediaType 媒体类型 ("image"或"video"仅在mediaUri不为null时有效)
* @return 是否成功启动分享
*/
public boolean shareToGroupChat(Activity activity, String content, Uri mediaUri, String mediaType) {
if (!isDouyinInstalled()) {
handleNotInstalled(activity);
return false;
}
try {
String packageName = getInstalledDouYinPackage();
// 尝试各种可能的群聊URI scheme
String[] groupChatSchemes = {
"snssdk1128://chat_group", // 可能的群聊scheme
"douyin://chat_group", // 可能的群聊scheme
"aweme://chat_group", // 可能的群聊scheme
"snssdk1128://im/group", // 可能的群聊scheme
"douyin://im/group", // 可能的群聊scheme
};
boolean groupPageOpened = false;
for (String scheme : groupChatSchemes) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(scheme));
intent.setPackage(packageName);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivity(intent);
Log.d(TAG, "成功使用scheme打开抖音群聊页面: " + scheme);
groupPageOpened = true;
break;
} catch (Exception e) {
Log.e(TAG, "scheme方式失败 " + scheme + ": " + e.getMessage());
// 继续尝试下一个scheme
}
}
if (!groupPageOpened) {
// 如果无法直接打开群聊页面,尝试打开普通消息页面
boolean messagePageOpened = openDouYinMessagePage(activity);
if (!messagePageOpened) {
// 如果消息页面也打不开,就直接启动抖音
boolean launched = tryLaunchDouyin(activity);
if (launched) {
Toast.makeText(activity, "抖音已启动,请点击底部消息按钮进入并选择群聊", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(activity, "无法启动抖音,请手动操作", Toast.LENGTH_SHORT).show();
return false;
}
} else {
Toast.makeText(activity, "请在消息页面选择或创建群聊进行分享", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(activity, "请选择群聊进行分享", Toast.LENGTH_LONG).show();
}
// 将内容复制到剪贴板以便用户粘贴
if (content != null && !content.isEmpty()) {
copyToClipboard(activity, content);
Toast.makeText(activity, "内容已复制到剪贴板,可在群聊中粘贴", Toast.LENGTH_SHORT).show();
}
// 如果有媒体文件,通过临时文件存储,以便用户手动分享
if (mediaUri != null) {
try {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setPackage(packageName);
if ("image".equals(mediaType)) {
shareIntent.setType("image/*");
} else if ("video".equals(mediaType)) {
shareIntent.setType("video/*");
} else {
shareIntent.setType("*/*");
}
shareIntent.putExtra(Intent.EXTRA_STREAM, mediaUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
// 创建临时分享弹窗,辅助用户操作
Intent chooser = Intent.createChooser(shareIntent, "请选择'抖音'");
activity.startActivity(chooser);
Toast.makeText(activity, "请在弹出窗口中选择抖音,进入群聊后再选择群组", Toast.LENGTH_LONG).show();
} catch (Exception e) {
Log.e(TAG, "准备媒体分享失败: " + e.getMessage());
// 如果媒体分享失败,至少已经将文本内容复制到剪贴板
}
}
// 假设分享过程启动成功
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
}, 1000);
}
return true;
} catch (Exception e) {
Log.e(TAG, "分享到群聊过程中发生异常: " + e.getMessage(), e);
if (mCallback != null) {
mCallback.onError(-1, "分享到群聊失败: " + e.getMessage());
}
return false;
}
}
/**
* 兼容性复制文本到剪贴板
* 支持API 9及以上版本
* @param context 上下文
* @param text 要复制的文本
*/
private void copyToClipboard(Context context, String text) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// API 11及以上使用ClipboardManager
android.content.ClipboardManager clipboardManager =
(android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clipData =
android.content.ClipData.newPlainText("分享内容", text);
clipboardManager.setPrimaryClip(clipData);
} else {
// API 11以下使用旧版的android.text.ClipboardManager
android.text.ClipboardManager clipboardManager =
(android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
clipboardManager.setText(text);
}
Log.d(TAG, "成功复制文本到剪贴板");
} catch (Exception e) {
Log.e(TAG, "复制到剪贴板失败: " + e.getMessage(), e);
}
}
/**
* 打开抖音消息页面
* @param activity 活动
* @return 是否成功打开
*/
private boolean openDouYinMessagePage(Activity activity) {
String packageName = getInstalledDouYinPackage();
// 抖音消息页面的可能URI schemas
String[] messageSchemas = {
"snssdk1128://chat?type=im_friend", // 标准抖音
"douyin://chat?type=im_friend", // 新版抖音
"aweme://chat?type=im_friend", // 旧版抖音
"snssdk1128://im/friend", // 其他可能的schema
"douyin://im/friend", // 其他可能的schema
};
// 尝试打开抖音消息选择页面
for (String schema : messageSchemas) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(schema));
intent.setPackage(packageName);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
Log.d(TAG, "成功使用Schema打开抖音消息页面: " + schema);
return true;
} catch (Exception e) {
Log.e(TAG, "使用Schema " + schema + " 打开抖音消息页面失败: " + e.getMessage());
// 继续尝试下一个schema
}
}
// 如果所有Schema都失败了尝试直接打开具体的消息Activity
try {
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, packageName + ".module.message.ui.MessageListActivity"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
Log.d(TAG, "成功使用组件名称打开抖音消息页面");
return true;
} catch (Exception e) {
Log.e(TAG, "使用组件名称打开抖音消息页面失败: " + e.getMessage());
}
return false;
}
/**
* 抖音分享回调接口
*/
public interface DouYinShareCallback {
void onSuccess();
void onError(int code, String message);
void onCancel();
}
}