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 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 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 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 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(); } }