1010 lines
40 KiB
Java
1010 lines
40 KiB
Java
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();
|
||
}
|
||
}
|