修改鸿蒙抖音qq

This commit is contained in:
2026-03-15 19:43:46 +08:00
parent f1530a3173
commit a7b7f38d31
11 changed files with 406 additions and 565 deletions

View File

@@ -24,7 +24,7 @@ android {
buildToolsVersion '33.0.0'
defaultConfig {
applicationId "com.jx.jyhd"
applicationId "com.daoqi.lobby"
minSdkVersion 21
targetSdkVersion 32
versionCode= 3

View File

@@ -4,7 +4,7 @@
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.jx.jyhd",
"applicationId": "com.dq.jy",
"variantName": "processReleaseResources",
"elements": [
{

View File

@@ -51,9 +51,9 @@ public class DouYinIntentShareHelper {
douYinIntentShareUtil.setShareCallback(new DouYinIntentShareUtil.DouYinShareCallback() {
@Override
public void onSuccess() {
((Activity) context).runOnUiThread(() ->
Toast.makeText(context, "抖音分享成功", Toast.LENGTH_SHORT).show()
);
// ((Activity) context).runOnUiThread(() ->
// Toast.makeText(context, "抖音分享成功", Toast.LENGTH_SHORT).show()
// );
}
@Override
@@ -201,8 +201,9 @@ public class DouYinIntentShareHelper {
// 如果处理失败,退回到纯文本分享
//douYinIntentShareUtil.shareToPrivateMessage((Activity) context, textContent, null, null);
} else {
// 只分享文本 - 直接使用Intent分享而不是复制粘贴方式
shareWebPageDirectToDouYin((Activity) context, bean.getTitle(), bean.getDescription(), "");
// 只分享文本 - 使用之前统一的弹窗引导方式
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(context);
util.shareWebpageToDouyin((Activity) context, "", bean.getTitle(), bean.getDescription());
}
}
@@ -336,9 +337,9 @@ public class DouYinIntentShareHelper {
douYinIntentShareUtil.setShareCallback(new DouYinIntentShareUtil.DouYinShareCallback() {
@Override
public void onSuccess() {
((Activity) context).runOnUiThread(() ->
Toast.makeText(context, "抖音分享成功", Toast.LENGTH_SHORT).show()
);
// ((Activity) context).runOnUiThread(() ->
// Toast.makeText(context, "抖音分享成功", Toast.LENGTH_SHORT).show()
// );
}
@Override
@@ -357,8 +358,8 @@ public class DouYinIntentShareHelper {
});
// 显示分享提示
Toast.makeText(context, "正在分享到抖音", Toast.LENGTH_SHORT).show(); // 修改:直接调用Intent分享方法而不是复制粘贴方式
shareTextDirectToDouYin((Activity) context, text);
Toast.makeText(context, "正在分享到抖音", Toast.LENGTH_SHORT).show(); // 修改:使用统一的引导弹窗方式
douYinIntentShareUtil.shareTextToDouyin((Activity) context, text);
} catch (Exception e) {
e.printStackTrace();
@@ -417,11 +418,11 @@ public class DouYinIntentShareHelper {
content.append(title).append("\n\n");
}
if (!TextUtils.isEmpty(description)) {
content.append(description).append("\n\n");
content.append(description);
}
if (!TextUtils.isEmpty(webUrl)) {
content.append(webUrl);
} String textContent = content.toString();
// 用户要求不要链接的内容
String textContent = content.toString().trim();
try {
Context mContext = activity.getApplicationContext();
// 设置缩略图 - 使用应用的启动图标 logo6 而不是 ic_launcher
@@ -429,17 +430,19 @@ public class DouYinIntentShareHelper {
mContext.getResources().getIdentifier("logo6", "drawable", mContext.getPackageName()));
Uri imagePath = Base64ImageUtil.saveBitmapToFile(activity, thumbBmp, null);
// 方式1尝试分享图文到私信(图片+文本)
// 方式1尝试分享图文
if (imagePath != null) {
shareImageWithTextDirectToDouYin(activity, textContent, imagePath);
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
util.shareToPrivateMessage(activity, textContent, imagePath, "image");
return;
}
} catch (Exception e) {
e.printStackTrace();
}
// 方式2如果图片处理失败使用纯文本直接分享
shareTextDirectToDouYin(activity, textContent);
// 方式2如果图片处理失败使用弹窗引导分享文本
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
util.shareWebpageToDouyin(activity, webUrl, title, description);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(activity, "网页分享出错: " + e.getMessage(), Toast.LENGTH_SHORT).show();
@@ -497,13 +500,11 @@ public class DouYinIntentShareHelper {
content.append(title).append("\n\n");
}
if (!TextUtils.isEmpty(description)) {
content.append(description).append("\n\n");
}
if (!TextUtils.isEmpty(webUrl)) {
content.append(webUrl);
content.append(description);
}
// 用户要求不要链接的内容
String textContent = content.toString();
String textContent = content.toString().trim();
// 如果提供了预览图,先处理图片再分享
if (!TextUtils.isEmpty(previewImageBase64)) {
@@ -855,216 +856,24 @@ public class DouYinIntentShareHelper {
}
/**
* 直接分享网页到抖音(使用Intent方式不是复制粘贴
*
* @param activity 当前活动
* @param title 网页标题
* @param description 网页描述
* @param webUrl 网页URL
* 第一种方法:直接分享网页到抖音(废弃,接入工具类
*/
public static void shareWebPageDirectToDouYin(Activity activity, String title, String description, String webUrl) {
try {
// 检查抖音是否已安装 - HarmonyOS兼容性修改移除强制检查
// if (!isAppInstalled(activity, "com.ss.android.ugc.aweme")) {
// Toast.makeText(activity, "抖音未安装,无法分享", Toast.LENGTH_SHORT).show();
// return;
// }
// 构建要分享的文本内容
StringBuilder content = new StringBuilder();
if (!TextUtils.isEmpty(title)) {
content.append(title).append("\n\n");
}
if (!TextUtils.isEmpty(description)) {
content.append(description).append("\n\n");
} if (!TextUtils.isEmpty(webUrl)) {
content.append(webUrl);
}
String textContent = content.toString();
// 方法1先尝试直接启动抖音App
if (tryLaunchDouyinDirectly(activity, textContent)) {
return;
}
// 方法2尝试使用多种MIME类型的分享Intent
if (tryMultipleShareIntents(activity, textContent)) {
return;
}
// 方法3最后的备选方案 - 复制到剪贴板并引导用户
fallbackCopyAndLaunch(activity, textContent);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(activity, "网页分享出错: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
util.shareWebpageToDouyin(activity, webUrl, title, description);
} /**
* 直接分享图片和文本到抖音使用Intent方式
* 直接分享图片和文本到抖音
*/
private static void shareImageWithTextDirectToDouYin(Activity activity, String text, Uri imageUri) {
try {
// 图片分享通常有更好的支持,先尝试图片分享
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
shareIntent.putExtra(Intent.EXTRA_TEXT, text);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 检查抖音是否可以处理图片分享
if (isIntentSafe(activity, shareIntent, "com.ss.android.ugc.aweme")) {
shareIntent.setPackage("com.ss.android.ugc.aweme");
// 添加额外参数尝试指定分享类型为私信
shareIntent.putExtra("share_type", "private_message");
shareIntent.putExtra("type", "private");
activity.startActivity(shareIntent);
Toast.makeText(activity, "正在打开抖音图文分享...", Toast.LENGTH_SHORT).show();
return;
}
// 如果直接分享失败,使用系统选择器
Intent chooser = Intent.createChooser(shareIntent.setPackage(null), "分享图文");
activity.startActivity(chooser);
new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> {
Toast.makeText(activity, "请选择抖音进行分享", Toast.LENGTH_LONG).show();
}, 1000);
} catch (Exception e) {
e.printStackTrace();
// 如果图片分享失败,降级为纯文本分享
Toast.makeText(activity, "图片分享失败,尝试文本分享", Toast.LENGTH_SHORT).show();
shareTextDirectToDouYin(activity, text);
}
// 直接接入使用工具类分享图文的方法
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
util.shareToPrivateMessage(activity, text, imageUri, "image");
}/**
* 直接分享纯文本到抖音(使用Intent方式
* 直接分享纯文本到抖音(废弃,接入工具类
*/
private static void shareTextDirectToDouYin(Activity activity, String text) {
try {
// 方法1先尝试直接启动抖音App
if (tryLaunchDouyinDirectly(activity, text)) {
return;
}
// 方法2尝试使用多种MIME类型的分享Intent
if (tryMultipleShareIntents(activity, text)) {
return;
}
// 方法3最后的备选方案 - 复制到剪贴板并引导用户
fallbackCopyAndLaunch(activity, text);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(activity, "文本分享失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
/**
* 方法1尝试直接启动抖音App并复制内容到剪贴板
*/
private static boolean tryLaunchDouyinDirectly(Activity activity, String content) {
try {
// 复制内容到剪贴板
copyTextToClipboard(activity, content);
// 尝试直接启动抖音主页
Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage("com.ss.android.ugc.aweme");
if (launchIntent != null) {
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(launchIntent);
// 提示用户操作
Toast.makeText(activity, "内容已复制到剪贴板,请在抖音中点击\"消息\"→选择联系人→粘贴发送", Toast.LENGTH_LONG).show();
return true;
}
} catch (Exception e) {
Log.e("DouYinShare", "直接启动抖音失败: " + e.getMessage());
}
return false;
}
/**
* 方法2尝试使用多种MIME类型创建分享Intent
*/
private static boolean tryMultipleShareIntents(Activity activity, String content) {
// 尝试的MIME类型列表
String[] mimeTypes = {
"text/plain",
"*/*",
"application/octet-stream"
};
for (String mimeType : mimeTypes) {
try {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType(mimeType);
shareIntent.putExtra(Intent.EXTRA_TEXT, content);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "网页分享");
// 检查是否有抖音可以处理这种Intent
if (isIntentSafe(activity, shareIntent, "com.ss.android.ugc.aweme")) {
shareIntent.setPackage("com.ss.android.ugc.aweme");
activity.startActivity(shareIntent);
Toast.makeText(activity, "正在打开抖音分享...", Toast.LENGTH_SHORT).show();
return true;
}
} catch (Exception e) {
Log.e("DouYinShare", "MIME类型 " + mimeType + " 分享失败: " + e.getMessage());
}
}
// 如果直接分享失败,尝试使用系统分享选择器
try {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, content);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "网页分享");
Intent chooser = Intent.createChooser(shareIntent, "选择分享方式");
activity.startActivity(chooser);
// 提示用户如果看不到抖音选项的解决方案
new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> {
Toast.makeText(activity, "如果没有抖音选项,请选择\"复制\"然后手动打开抖音粘贴", Toast.LENGTH_LONG).show();
}, 1000);
return true;
} catch (Exception e) {
Log.e("DouYinShare", "系统分享选择器失败: " + e.getMessage());
}
return false;
}
/**
* 方法3备选方案 - 复制到剪贴板并引导用户手动操作
*/
private static void fallbackCopyAndLaunch(Activity activity, String content) {
try {
// 复制到剪贴板
copyTextToClipboard(activity, content);
// 尝试启动抖音
try {
Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage("com.ss.android.ugc.aweme");
if (launchIntent != null) {
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(launchIntent);
}
} catch (Exception e) {
Log.e("DouYinShare", "启动抖音失败: " + e.getMessage());
}
// 详细的操作指导
Toast.makeText(activity, "内容已复制!请在抖音中:消息→选择好友→长按输入框→粘贴→发送", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(activity, "分享失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
util.shareTextToDouyin(activity, text);
}
/**

View File

@@ -162,119 +162,43 @@ public class DouYinIntentShareUtil {
* @return 是否成功启动
*/
private boolean tryLaunchDouyin(Activity activity) {
String packageName = "com.ss.android.ugc.aweme";
try {
String packageName = getInstalledDouYinPackage();
Log.d(TAG, "尝试启动抖音,包名: " + packageName);
// 方法0最稳妥的Intent Chooser方式适配鸿蒙卓易通
Intent launchIntent = null;
// 方法1: 尝试获取官方启动Intent
try {
// 如果是单纯想打开抖音我们可以构造一个简单的VIEW Intent或者MAIN Intent
// 但如果是为了分享建议直接调用shareToPrivateMessage等方法
// 这里仅作为启动应用的逻辑
Intent intent = activity.getPackageManager().getLaunchIntentForPackage(packageName);
if (intent == null) {
// 如果获取不到LaunchIntent构建通用启动Intent
intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage(packageName);
}
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); // 卓易通关键flag
activity.startActivity(intent);
return true;
}
launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName);
} catch (Exception e) {
Log.e(TAG, "启动抖音失败: " + e.getMessage());
final String msg = "启动抖音失败: " + e.getMessage();
activity.runOnUiThread(() -> Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show());
// 忽略异常
}
// 方法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, "成功使用标准方式启动抖音");
activity.runOnUiThread(() -> Toast.makeText(activity, "标准方式启动成功", Toast.LENGTH_SHORT).show());
return true;
// 方法2: 如果获取不到尝试构造Intent盲拉
if (launchIntent == null) {
launchIntent = new Intent(Intent.ACTION_MAIN);
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
launchIntent.setPackage(packageName);
}
// 方法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;
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(launchIntent);
return true;
} catch (Exception e) {
Log.e(TAG, "启动抖音过程中发生异常: " + e.getMessage(), e);
return false;
// 方法3: 最后的救命稻草 - 纯净版URL Scheme不设置Package绕过包名拦截
try {
Uri uri = Uri.parse("snssdk1128://");
Intent schemeIntent = new Intent(Intent.ACTION_VIEW, uri);
schemeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(schemeIntent);
return true;
} catch (Exception ex) {
Log.e(TAG, "纯净版Scheme启动抖音失败: " + ex.getMessage());
}
}
return false;
}
/**
@@ -287,70 +211,11 @@ public class DouYinIntentShareUtil {
boolean isPackageDetected = isDouyinInstalled();
try {
// 使用兼容方式复制到剪贴板,作为兜底
try {
copyToClipboard(activity, text);
} catch (Exception e) {
// 忽略
}
String packageName = getInstalledDouYinPackage();
boolean launched = false;
// 复制到剪贴板
copyToClipboard(activity, text);
// 方法1优先尝试系统Intent Chooser这是最可靠的方式
try {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, text);
// 鸿蒙/卓易通关键适配Flags
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
// 抖音在卓易通环境下实际上不支持纯文本直接唤起分享(只能发图片视频)
// 这里使用 setPackage 直接拉起,如果没有效果则会跳转抖音首页
intent.setPackage(packageName);
activity.startActivity(intent);
launched = true;
Log.d(TAG, "成功启动文本分享");
activity.runOnUiThread(() -> Toast.makeText(activity, "成功启动文本分享", Toast.LENGTH_SHORT).show());
} catch (Exception e) {
Log.e(TAG, "启动文本分享失败: " + e.getMessage());
final String msg = "启动文本分享失败: " + e.getMessage();
activity.runOnUiThread(() -> Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show());
}
// 方法2如果分享Intent失败尝试仅启动应用
if (!launched) {
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);
}
// 弹出提示框引导用户
activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, false));
} catch (Exception e) {
Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e);
handleShareException(activity, e);
@@ -424,22 +289,12 @@ public class DouYinIntentShareUtil {
if (!launched) {
try {
Intent cleanIntent = new Intent(Intent.ACTION_SEND);
cleanIntent.setType("image/*");
cleanIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
cleanIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 使用系统Chooser
Intent chooserIntent = Intent.createChooser(cleanIntent, "分享到抖音");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(chooserIntent);
// 废弃系统Chooser改用自定义引导弹窗
activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, false));
launched = true;
Log.d(TAG, "使用System Chooser分享图片");
activity.runOnUiThread(() -> Toast.makeText(activity, "尝试使用System Chooser", Toast.LENGTH_SHORT).show());
} catch (Exception e) {
Log.e(TAG, "Chooser分享失败: " + e.getMessage());
final String failMsg2 = "Chooser失败: " + e.getMessage();
Log.e(TAG, "引导弹窗分享失败: " + e.getMessage());
final String failMsg2 = "引导弹窗失败: " + e.getMessage();
activity.runOnUiThread(() -> Toast.makeText(activity, failMsg2, Toast.LENGTH_SHORT).show());
}
}
@@ -529,8 +384,9 @@ public class DouYinIntentShareUtil {
activity.runOnUiThread(() -> Toast.makeText(activity, "多图直接分享成功", Toast.LENGTH_SHORT).show());
} catch (Exception e) {
Log.d(TAG, "直接分享多图失败: " + e.getMessage());
final String msg = "直接分享多图失败: " + e.getMessage();
activity.runOnUiThread(() -> Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show());
// 直接分享失败,改用自定义引导弹窗
activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, false));
launched = true;
}
} catch (Exception e) {
handleShareException(activity, e);
@@ -633,22 +489,12 @@ public class DouYinIntentShareUtil {
if (!launched) {
try {
Intent cleanIntent = new Intent(Intent.ACTION_SEND);
cleanIntent.setType("video/*");
cleanIntent.putExtra(Intent.EXTRA_STREAM, videoUri);
cleanIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 使用系统Chooser
Intent chooserIntent = Intent.createChooser(cleanIntent, "分享视频到抖音");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(chooserIntent);
// 废弃系统Chooser改用自定义引导弹窗
activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, true));
launched = true;
Log.d(TAG, "使用System Chooser分享视频");
activity.runOnUiThread(() -> Toast.makeText(activity, "尝试使用System Chooser分享视频", Toast.LENGTH_SHORT).show());
} catch (Exception e) {
Log.e(TAG, "Chooser分享视频失败: " + e.getMessage());
final String failMsg2 = "Chooser视频失败: " + e.getMessage();
Log.e(TAG, "引导弹窗分享视频失败: " + e.getMessage());
final String failMsg2 = "引导弹窗视频失败: " + e.getMessage();
activity.runOnUiThread(() -> Toast.makeText(activity, failMsg2, Toast.LENGTH_SHORT).show());
}
}
@@ -686,13 +532,12 @@ public class DouYinIntentShareUtil {
sb.append(title).append("\n\n");
}
if (!TextUtils.isEmpty(description)) {
sb.append(description).append("\n\n");
}
if (!TextUtils.isEmpty(webUrl)) {
sb.append(webUrl);
sb.append(description);
}
// 用户要求不需要分享链接因此这里不再追加webUrl的内容
shareTextToDouyin(activity, sb.toString());
shareTextToDouyin(activity, sb.toString().trim());
}
/**
@@ -703,117 +548,23 @@ public class DouYinIntentShareUtil {
* @param description 分享描述,可选
*/
public void shareWebpageToDouyin(Activity activity, String url, String title, String description) {
// Strict check removed
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(description);
}
shareContent.append(url);
// 用户要求不需要链接分享的内容也不需要复制链接因此不再追加url的内容
// 复制到剪贴板,便于用户在抖音中粘贴
copyToClipboard(activity, shareContent.toString());
copyToClipboard(activity, shareContent.toString().trim());
// 方法1: 尝试使用系统分享直接发送到抖音
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, shareContent.toString());
ComponentName comp = resolveShareComponent(activity, shareIntent, packageName);
if (comp != null) {
shareIntent.setComponent(comp);
} else {
shareIntent.setPackage(packageName);
}
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);
}
// 弹出提示框引导用户
activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, true));
} catch (Exception e) {
Log.e(TAG, "分享网页过程中出现异常: " + e.getMessage(), e);
@@ -828,12 +579,8 @@ public class DouYinIntentShareUtil {
*/
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();
// 废弃系统Chooser统一使用引导弹窗
activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, false));
// 假设分享成功
if (mCallback != null) {
@@ -1077,11 +824,11 @@ public class DouYinIntentShareUtil {
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
// 创建临时分享弹窗,辅助用户操作
Intent chooser = Intent.createChooser(shareIntent, "请选择'抖音'");
activity.startActivity(chooser);
Toast.makeText(activity, "请在弹出窗口中选择抖音,进入群聊后再选择群组", Toast.LENGTH_LONG).show();
// 废弃系统Chooser改用自定义引导弹窗
activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, "video".equals(mediaType)));
// 已在向导弹窗中引导用户
// Toast.makeText(activity, "请在弹出窗口中选择抖音,进入群聊后再选择群组", Toast.LENGTH_LONG).show();
} catch (Exception e) {
Log.e(TAG, "准备媒体分享失败: " + e.getMessage());
// 如果媒体分享失败,至少已经将文本内容复制到剪贴板
@@ -1178,6 +925,139 @@ public class DouYinIntentShareUtil {
return false;
}
/**
* 显示抖音媒体(图片/视频)分享引导弹窗
*/
private void showDouYinMediaGuideDialog(final Activity activity, boolean isVideo) {
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(activity);
builder.setTitle("分享准备完成");
builder.setCancelable(false);
// 构建自定义视图
android.widget.LinearLayout layout = new android.widget.LinearLayout(activity);
layout.setOrientation(android.widget.LinearLayout.VERTICAL);
int padding = dp2px(activity, 20);
layout.setPadding(padding, padding, padding, padding);
layout.setGravity(android.view.Gravity.CENTER_HORIZONTAL);
// 状态提示
android.widget.TextView statusTv = new android.widget.TextView(activity);
// 这里只是引导发送意图,默认文件其实就在本地,所以提示"准备就绪"或"已保存"
statusTv.setText(isVideo ? "✅ 视频分享准备就绪" : "✅ 图片分享准备就绪");
statusTv.setTextColor(android.graphics.Color.parseColor("#4CAF50"));
statusTv.setTextSize(16);
statusTv.setTypeface(null, android.graphics.Typeface.BOLD);
statusTv.setGravity(android.view.Gravity.CENTER);
layout.addView(statusTv);
// 间隔
android.view.View space = new android.view.View(activity);
layout.addView(space, new android.widget.LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, dp2px(activity, 15)));
// 步骤文本
android.widget.TextView stepTv = new android.widget.TextView(activity);
stepTv.setText("分享到好友或群聊步骤:\n\n" +
"1. 点击下方按钮打开抖音\n" +
"2. 找到好友或群聊进入聊天界面\n" +
"3. 点击输入框旁的「+」号 ->「相册」\n" +
"4. 选择第一张" + (isVideo ? "视频" : "图片") + "发送即可");
stepTv.setTextColor(android.graphics.Color.DKGRAY);
stepTv.setTextSize(14);
// 行间距
stepTv.setLineSpacing(dp2px(activity, 4), 1.0f);
layout.addView(stepTv);
builder.setView(layout);
// 按钮
builder.setPositiveButton("立即打开抖音", (dialog, which) -> {
boolean launched = tryLaunchDouyin(activity);
if (!launched) {
Toast.makeText(activity, "无法自动打开抖音,请手动打开应用进行分享", Toast.LENGTH_SHORT).show();
}
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> mCallback.onSuccess(), 1000);
}
});
builder.setNegativeButton("稍后分享", (dialog, which) -> {
if (mCallback != null) {
mCallback.onCancel();
}
});
builder.show();
}
/**
* 显示抖音文本分享引导弹窗
*/
private void showDouYinTextGuideDialog(final Activity activity, boolean isWebpage) {
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(activity);
builder.setTitle("分享准备完成");
builder.setCancelable(false);
// 构建自定义视图
android.widget.LinearLayout layout = new android.widget.LinearLayout(activity);
layout.setOrientation(android.widget.LinearLayout.VERTICAL);
int padding = dp2px(activity, 20);
layout.setPadding(padding, padding, padding, padding);
layout.setGravity(android.view.Gravity.CENTER_HORIZONTAL);
// 状态提示
android.widget.TextView statusTv = new android.widget.TextView(activity);
statusTv.setText(isWebpage ? "✅ 链接已复制到剪贴板" : "✅ 文本已复制到剪贴板");
statusTv.setTextColor(android.graphics.Color.parseColor("#4CAF50"));
statusTv.setTextSize(16);
statusTv.setTypeface(null, android.graphics.Typeface.BOLD);
statusTv.setGravity(android.view.Gravity.CENTER);
layout.addView(statusTv);
// 间隔
android.view.View space = new android.view.View(activity);
layout.addView(space, new android.widget.LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, dp2px(activity, 15)));
// 步骤文本
android.widget.TextView stepTv = new android.widget.TextView(activity);
stepTv.setText("分享到好友或群聊步骤:\n\n" +
"1. 点击下方按钮打开抖音\n" +
"2. 找到好友或群聊进入聊天界面\n" +
"3. 在底部输入框长按选择「粘贴」\n" +
"4. 点击发送即可完成分享");
stepTv.setTextColor(android.graphics.Color.DKGRAY);
stepTv.setTextSize(14);
// 行间距
stepTv.setLineSpacing(dp2px(activity, 4), 1.0f);
layout.addView(stepTv);
builder.setView(layout);
// 按钮
builder.setPositiveButton("立即打开抖音", (dialog, which) -> {
boolean launched = tryLaunchDouyin(activity);
if (!launched) {
Toast.makeText(activity, "无法自动打开抖音,请手动打开应用进行粘贴分享", Toast.LENGTH_SHORT).show();
}
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> mCallback.onSuccess(), 1000);
}
});
builder.setNegativeButton("稍后分享", (dialog, which) -> {
if (mCallback != null) {
mCallback.onCancel();
}
});
builder.show();
}
private static int dp2px(Context context, float dp) {
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
/**
* 抖音分享回调接口
*/

View File

@@ -717,35 +717,56 @@ public class QQIntentShareUtil {
* 所以我们通过原生的 intent 送入 createChooser然后利用 EXTRA_EXCLUDE_COMPONENTS 排除抖音。
*/
private Intent createTargetedChooserIntent(Activity activity, Intent targetIntent, CharSequence title) {
// 重要:确保本体 intent 不要携带 package 限制,否则在卓易通系统的 chooser 会失效静默
String packageName = getInstalledQQPackage();
// 清理现场:如果带有被隐式拦截的 package 再去查询,查出来的结果是空的。
targetIntent.setPackage(null);
targetIntent.setComponent(null);
PackageManager pm = activity.getPackageManager();
try {
// 第一步:全局海选。不再限定包名,直接拿最原始的 intent 去查手机里【所有的】分享接收器。
// 这样能避开卓易通对 setPackage 隐式意图的严格 API 拦截。
List<android.content.pm.ResolveInfo> resInfo = pm.queryIntentActivities(targetIntent, PackageManager.MATCH_DEFAULT_ONLY);
ComponentName selectedComponent = null;
if (resInfo != null && !resInfo.isEmpty()) {
// 遍历系统诚实返回的列表,自己把 QQ 挑出来
for (android.content.pm.ResolveInfo info : resInfo) {
if (info.activityInfo != null && packageName.equals(info.activityInfo.packageName)) {
// 抓到了!系统真正在当前操作(文字/图片分享)下分配的 QQ 接收组件名!
selectedComponent = new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
break;
}
}
}
if (selectedComponent != null) {
// 找到完美的对应组件,走显式跳转,直接砸过去!不经过 Chooser绝对没有抖音。
targetIntent.setComponent(selectedComponent);
return targetIntent;
}
} catch (Exception e) {
Log.e(TAG, "动态查找QQ专属分享组件失败", e);
}
// 第二步 兜底防奔溃:
// 如果上面的海选连 QQ 都查不到(或者某些变态系统彻底封禁了 queryIntentActivities 接口),
// 如果我们这时候再去硬写 setComponent(JumpActivity),就会报您刚才看到的:
// "Unable to find explicit activity class..." 的致命奔溃错误。
// 所以,到了这一步,宁可向系统低头唤出 Chooser也绝不能让应用闪退奔溃。
Intent chooser = Intent.createChooser(targetIntent, title);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
try {
// 找出抖音可能接收分享的所有组件
Intent queryIntent = new Intent(targetIntent.getAction());
queryIntent.setType(targetIntent.getType());
queryIntent.setPackage("com.ss.android.ugc.aweme");
List<android.content.pm.ResolveInfo> resInfo = activity.getPackageManager().queryIntentActivities(queryIntent, 0);
List<ComponentName> excludedComponents = new ArrayList<>();
if (resInfo != null && !resInfo.isEmpty()) {
for (android.content.pm.ResolveInfo info : resInfo) {
excludedComponents.add(new ComponentName(info.activityInfo.packageName, info.activityInfo.name));
}
} else {
// 兜底硬编码过滤最常见的涉事抖音组件
excludedComponents.add(new ComponentName("com.ss.android.ugc.aweme", "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"));
}
chooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponents.toArray(new ComponentName[0]));
} catch (Exception e) {
Log.e(TAG, "设置排他组件失败", e);
}
}
try {
// 尽最后的人事,附上黑名单作为尝试屏蔽
ComponentName[] excludes = new ComponentName[] {
new ComponentName("com.ss.android.ugc.aweme", "com.ss.android.ugc.aweme.share.SystemShareActivity"),
new ComponentName("com.ss.android.ugc.aweme", "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"),
new ComponentName("com.ss.android.ugc.aweme", "com.ss.android.ugc.aweme.shortvideo.ui.VideoRecordNewActivity")
};
chooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludes);
} catch (Exception e) {}
return chooser;
}