修改鸿蒙抖音qq
This commit is contained in:
@@ -24,7 +24,7 @@ android {
|
|||||||
buildToolsVersion '33.0.0'
|
buildToolsVersion '33.0.0'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.jx.jyhd"
|
applicationId "com.daoqi.lobby"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 32
|
targetSdkVersion 32
|
||||||
versionCode= 3
|
versionCode= 3
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"type": "APK",
|
"type": "APK",
|
||||||
"kind": "Directory"
|
"kind": "Directory"
|
||||||
},
|
},
|
||||||
"applicationId": "com.jx.jyhd",
|
"applicationId": "com.dq.jy",
|
||||||
"variantName": "processReleaseResources",
|
"variantName": "processReleaseResources",
|
||||||
"elements": [
|
"elements": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,9 +51,9 @@ public class DouYinIntentShareHelper {
|
|||||||
douYinIntentShareUtil.setShareCallback(new DouYinIntentShareUtil.DouYinShareCallback() {
|
douYinIntentShareUtil.setShareCallback(new DouYinIntentShareUtil.DouYinShareCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess() {
|
public void onSuccess() {
|
||||||
((Activity) context).runOnUiThread(() ->
|
// ((Activity) context).runOnUiThread(() ->
|
||||||
Toast.makeText(context, "抖音分享成功", Toast.LENGTH_SHORT).show()
|
// Toast.makeText(context, "抖音分享成功", Toast.LENGTH_SHORT).show()
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -201,8 +201,9 @@ public class DouYinIntentShareHelper {
|
|||||||
// 如果处理失败,退回到纯文本分享
|
// 如果处理失败,退回到纯文本分享
|
||||||
//douYinIntentShareUtil.shareToPrivateMessage((Activity) context, textContent, null, null);
|
//douYinIntentShareUtil.shareToPrivateMessage((Activity) context, textContent, null, null);
|
||||||
} else {
|
} 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() {
|
douYinIntentShareUtil.setShareCallback(new DouYinIntentShareUtil.DouYinShareCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess() {
|
public void onSuccess() {
|
||||||
((Activity) context).runOnUiThread(() ->
|
// ((Activity) context).runOnUiThread(() ->
|
||||||
Toast.makeText(context, "抖音分享成功", Toast.LENGTH_SHORT).show()
|
// Toast.makeText(context, "抖音分享成功", Toast.LENGTH_SHORT).show()
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -357,8 +358,8 @@ public class DouYinIntentShareHelper {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 显示分享提示
|
// 显示分享提示
|
||||||
Toast.makeText(context, "正在分享到抖音", Toast.LENGTH_SHORT).show(); // 修改:直接调用Intent分享方法,而不是复制粘贴方式
|
Toast.makeText(context, "正在分享到抖音", Toast.LENGTH_SHORT).show(); // 修改:使用统一的引导弹窗方式
|
||||||
shareTextDirectToDouYin((Activity) context, text);
|
douYinIntentShareUtil.shareTextToDouyin((Activity) context, text);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -417,11 +418,11 @@ public class DouYinIntentShareHelper {
|
|||||||
content.append(title).append("\n\n");
|
content.append(title).append("\n\n");
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(description)) {
|
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 {
|
try {
|
||||||
Context mContext = activity.getApplicationContext();
|
Context mContext = activity.getApplicationContext();
|
||||||
// 设置缩略图 - 使用应用的启动图标 logo6 而不是 ic_launcher
|
// 设置缩略图 - 使用应用的启动图标 logo6 而不是 ic_launcher
|
||||||
@@ -429,17 +430,19 @@ public class DouYinIntentShareHelper {
|
|||||||
mContext.getResources().getIdentifier("logo6", "drawable", mContext.getPackageName()));
|
mContext.getResources().getIdentifier("logo6", "drawable", mContext.getPackageName()));
|
||||||
Uri imagePath = Base64ImageUtil.saveBitmapToFile(activity, thumbBmp, null);
|
Uri imagePath = Base64ImageUtil.saveBitmapToFile(activity, thumbBmp, null);
|
||||||
|
|
||||||
// 方式1:尝试分享图文到私信(图片+文本)
|
// 方式1:尝试分享图文
|
||||||
if (imagePath != null) {
|
if (imagePath != null) {
|
||||||
shareImageWithTextDirectToDouYin(activity, textContent, imagePath);
|
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
|
||||||
|
util.shareToPrivateMessage(activity, textContent, imagePath, "image");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 方式2:如果图片处理失败,使用纯文本直接分享
|
// 方式2:如果图片处理失败,使用弹窗引导分享文本
|
||||||
shareTextDirectToDouYin(activity, textContent);
|
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
|
||||||
|
util.shareWebpageToDouyin(activity, webUrl, title, description);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Toast.makeText(activity, "网页分享出错: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, "网页分享出错: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
@@ -497,13 +500,11 @@ public class DouYinIntentShareHelper {
|
|||||||
content.append(title).append("\n\n");
|
content.append(title).append("\n\n");
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(description)) {
|
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();
|
||||||
|
|
||||||
// 如果提供了预览图,先处理图片再分享
|
// 如果提供了预览图,先处理图片再分享
|
||||||
if (!TextUtils.isEmpty(previewImageBase64)) {
|
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) {
|
public static void shareWebPageDirectToDouYin(Activity activity, String title, String description, String webUrl) {
|
||||||
try {
|
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
|
||||||
// 检查抖音是否已安装 - HarmonyOS兼容性修改:移除强制检查
|
util.shareWebpageToDouyin(activity, webUrl, title, description);
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
} /**
|
} /**
|
||||||
* 直接分享图片和文本到抖音(使用Intent方式)
|
* 直接分享图片和文本到抖音
|
||||||
*/
|
*/
|
||||||
private static void shareImageWithTextDirectToDouYin(Activity activity, String text, Uri imageUri) {
|
private static void shareImageWithTextDirectToDouYin(Activity activity, String text, Uri imageUri) {
|
||||||
try {
|
// 直接接入使用工具类分享图文的方法
|
||||||
// 图片分享通常有更好的支持,先尝试图片分享
|
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
|
||||||
Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
util.shareToPrivateMessage(activity, text, imageUri, "image");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}/**
|
}/**
|
||||||
* 直接分享纯文本到抖音(使用Intent方式)
|
* 直接分享纯文本到抖音(废弃,接入工具类)
|
||||||
*/
|
*/
|
||||||
private static void shareTextDirectToDouYin(Activity activity, String text) {
|
private static void shareTextDirectToDouYin(Activity activity, String text) {
|
||||||
try {
|
DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity);
|
||||||
// 方法1:先尝试直接启动抖音App
|
util.shareTextToDouyin(activity, text);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -162,119 +162,43 @@ public class DouYinIntentShareUtil {
|
|||||||
* @return 是否成功启动
|
* @return 是否成功启动
|
||||||
*/
|
*/
|
||||||
private boolean tryLaunchDouyin(Activity activity) {
|
private boolean tryLaunchDouyin(Activity activity) {
|
||||||
|
String packageName = "com.ss.android.ugc.aweme";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String packageName = getInstalledDouYinPackage();
|
Intent launchIntent = null;
|
||||||
Log.d(TAG, "尝试启动抖音,包名: " + packageName);
|
|
||||||
|
|
||||||
// 方法0:最稳妥的Intent Chooser方式(适配鸿蒙卓易通)
|
// 方法1: 尝试获取官方启动Intent
|
||||||
try {
|
try {
|
||||||
// 如果是单纯想打开抖音,我们可以构造一个简单的VIEW Intent或者MAIN Intent
|
launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName);
|
||||||
// 但如果是为了分享,建议直接调用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;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "启动抖音失败: " + e.getMessage());
|
// 忽略异常
|
||||||
final String msg = "启动抖音失败: " + e.getMessage();
|
|
||||||
activity.runOnUiThread(() -> Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 方法1:使用标准启动方式 (旧逻辑保留)
|
// 方法2: 如果获取不到,尝试构造Intent盲拉
|
||||||
Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName);
|
if (launchIntent == null) {
|
||||||
if (launchIntent != null) {
|
launchIntent = new Intent(Intent.ACTION_MAIN);
|
||||||
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
activity.startActivity(launchIntent);
|
launchIntent.setPackage(packageName);
|
||||||
Log.d(TAG, "成功使用标准方式启动抖音");
|
|
||||||
activity.runOnUiThread(() -> Toast.makeText(activity, "标准方式启动成功", Toast.LENGTH_SHORT).show());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 方法2:使用ACTION_MAIN + CATEGORY_LAUNCHER
|
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
try {
|
activity.startActivity(launchIntent);
|
||||||
Intent mainIntent = new Intent(Intent.ACTION_MAIN);
|
return true;
|
||||||
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) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "启动抖音过程中发生异常: " + e.getMessage(), e);
|
// 方法3: 最后的救命稻草 - 纯净版URL Scheme(不设置Package,绕过包名拦截)
|
||||||
return false;
|
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();
|
boolean isPackageDetected = isDouyinInstalled();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 使用兼容方式复制到剪贴板,作为兜底
|
// 复制到剪贴板
|
||||||
try {
|
copyToClipboard(activity, text);
|
||||||
copyToClipboard(activity, text);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 忽略
|
|
||||||
}
|
|
||||||
|
|
||||||
String packageName = getInstalledDouYinPackage();
|
// 弹出提示框引导用户
|
||||||
boolean launched = false;
|
activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, false));
|
||||||
|
|
||||||
// 方法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);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e);
|
Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e);
|
||||||
handleShareException(activity, e);
|
handleShareException(activity, e);
|
||||||
@@ -424,22 +289,12 @@ public class DouYinIntentShareUtil {
|
|||||||
|
|
||||||
if (!launched) {
|
if (!launched) {
|
||||||
try {
|
try {
|
||||||
Intent cleanIntent = new Intent(Intent.ACTION_SEND);
|
// 废弃系统Chooser,改用自定义引导弹窗
|
||||||
cleanIntent.setType("image/*");
|
activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, false));
|
||||||
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);
|
|
||||||
launched = true;
|
launched = true;
|
||||||
Log.d(TAG, "使用System Chooser分享图片");
|
|
||||||
activity.runOnUiThread(() -> Toast.makeText(activity, "尝试使用System Chooser", Toast.LENGTH_SHORT).show());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Chooser分享失败: " + e.getMessage());
|
Log.e(TAG, "引导弹窗分享失败: " + e.getMessage());
|
||||||
final String failMsg2 = "Chooser失败: " + e.getMessage();
|
final String failMsg2 = "引导弹窗失败: " + e.getMessage();
|
||||||
activity.runOnUiThread(() -> Toast.makeText(activity, failMsg2, Toast.LENGTH_SHORT).show());
|
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());
|
activity.runOnUiThread(() -> Toast.makeText(activity, "多图直接分享成功", Toast.LENGTH_SHORT).show());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d(TAG, "直接分享多图失败: " + e.getMessage());
|
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) {
|
} catch (Exception e) {
|
||||||
handleShareException(activity, e);
|
handleShareException(activity, e);
|
||||||
@@ -633,22 +489,12 @@ public class DouYinIntentShareUtil {
|
|||||||
|
|
||||||
if (!launched) {
|
if (!launched) {
|
||||||
try {
|
try {
|
||||||
Intent cleanIntent = new Intent(Intent.ACTION_SEND);
|
// 废弃系统Chooser,改用自定义引导弹窗
|
||||||
cleanIntent.setType("video/*");
|
activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, true));
|
||||||
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);
|
|
||||||
launched = true;
|
launched = true;
|
||||||
Log.d(TAG, "使用System Chooser分享视频");
|
|
||||||
activity.runOnUiThread(() -> Toast.makeText(activity, "尝试使用System Chooser分享视频", Toast.LENGTH_SHORT).show());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Chooser分享视频失败: " + e.getMessage());
|
Log.e(TAG, "引导弹窗分享视频失败: " + e.getMessage());
|
||||||
final String failMsg2 = "Chooser视频失败: " + e.getMessage();
|
final String failMsg2 = "引导弹窗视频失败: " + e.getMessage();
|
||||||
activity.runOnUiThread(() -> Toast.makeText(activity, failMsg2, Toast.LENGTH_SHORT).show());
|
activity.runOnUiThread(() -> Toast.makeText(activity, failMsg2, Toast.LENGTH_SHORT).show());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -686,13 +532,12 @@ public class DouYinIntentShareUtil {
|
|||||||
sb.append(title).append("\n\n");
|
sb.append(title).append("\n\n");
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(description)) {
|
if (!TextUtils.isEmpty(description)) {
|
||||||
sb.append(description).append("\n\n");
|
sb.append(description);
|
||||||
}
|
|
||||||
if (!TextUtils.isEmpty(webUrl)) {
|
|
||||||
sb.append(webUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shareTextToDouyin(activity, sb.toString());
|
// 用户要求不需要分享链接,因此这里不再追加webUrl的内容
|
||||||
|
|
||||||
|
shareTextToDouyin(activity, sb.toString().trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -703,117 +548,23 @@ public class DouYinIntentShareUtil {
|
|||||||
* @param description 分享描述,可选
|
* @param description 分享描述,可选
|
||||||
*/
|
*/
|
||||||
public void shareWebpageToDouyin(Activity activity, String url, String title, String 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 {
|
try {
|
||||||
String packageName = getInstalledDouYinPackage();
|
|
||||||
|
|
||||||
// 构建完整分享内容
|
// 构建完整分享内容
|
||||||
StringBuilder shareContent = new StringBuilder();
|
StringBuilder shareContent = new StringBuilder();
|
||||||
if (!TextUtils.isEmpty(title)) {
|
if (!TextUtils.isEmpty(title)) {
|
||||||
shareContent.append(title).append("\n");
|
shareContent.append(title).append("\n");
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(description)) {
|
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);
|
activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, true));
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "分享网页过程中出现异常: " + e.getMessage(), e);
|
Log.e(TAG, "分享网页过程中出现异常: " + e.getMessage(), e);
|
||||||
@@ -828,12 +579,8 @@ public class DouYinIntentShareUtil {
|
|||||||
*/
|
*/
|
||||||
private void startShareActivity(Activity activity, Intent intent) {
|
private void startShareActivity(Activity activity, Intent intent) {
|
||||||
try {
|
try {
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
// 废弃系统Chooser,统一使用引导弹窗
|
||||||
|
activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, false));
|
||||||
// 创建选择器并提示用户选择抖音
|
|
||||||
Intent chooser = Intent.createChooser(intent, "分享到抖音");
|
|
||||||
activity.startActivity(chooser);
|
|
||||||
Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show();
|
|
||||||
|
|
||||||
// 假设分享成功
|
// 假设分享成功
|
||||||
if (mCallback != null) {
|
if (mCallback != null) {
|
||||||
@@ -1077,11 +824,11 @@ public class DouYinIntentShareUtil {
|
|||||||
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建临时分享弹窗,辅助用户操作
|
// 废弃系统Chooser,改用自定义引导弹窗
|
||||||
Intent chooser = Intent.createChooser(shareIntent, "请选择'抖音'");
|
activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, "video".equals(mediaType)));
|
||||||
activity.startActivity(chooser);
|
|
||||||
|
|
||||||
Toast.makeText(activity, "请在弹出窗口中选择抖音,进入群聊后再选择群组", Toast.LENGTH_LONG).show();
|
// 已在向导弹窗中引导用户
|
||||||
|
// Toast.makeText(activity, "请在弹出窗口中选择抖音,进入群聊后再选择群组", Toast.LENGTH_LONG).show();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "准备媒体分享失败: " + e.getMessage());
|
Log.e(TAG, "准备媒体分享失败: " + e.getMessage());
|
||||||
// 如果媒体分享失败,至少已经将文本内容复制到剪贴板
|
// 如果媒体分享失败,至少已经将文本内容复制到剪贴板
|
||||||
@@ -1178,6 +925,139 @@ public class DouYinIntentShareUtil {
|
|||||||
|
|
||||||
return false;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抖音分享回调接口
|
* 抖音分享回调接口
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -717,35 +717,56 @@ public class QQIntentShareUtil {
|
|||||||
* 所以我们通过原生的 intent 送入 createChooser,然后利用 EXTRA_EXCLUDE_COMPONENTS 排除抖音。
|
* 所以我们通过原生的 intent 送入 createChooser,然后利用 EXTRA_EXCLUDE_COMPONENTS 排除抖音。
|
||||||
*/
|
*/
|
||||||
private Intent createTargetedChooserIntent(Activity activity, Intent targetIntent, CharSequence title) {
|
private Intent createTargetedChooserIntent(Activity activity, Intent targetIntent, CharSequence title) {
|
||||||
// 重要:确保本体 intent 不要携带 package 限制,否则在卓易通系统的 chooser 会失效静默
|
String packageName = getInstalledQQPackage();
|
||||||
|
|
||||||
|
// 清理现场:如果带有被隐式拦截的 package 再去查询,查出来的结果是空的。
|
||||||
targetIntent.setPackage(null);
|
targetIntent.setPackage(null);
|
||||||
targetIntent.setComponent(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);
|
Intent chooser = Intent.createChooser(targetIntent, title);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
try {
|
||||||
try {
|
// 尽最后的人事,附上黑名单作为尝试屏蔽
|
||||||
// 找出抖音可能接收分享的所有组件
|
ComponentName[] excludes = new ComponentName[] {
|
||||||
Intent queryIntent = new Intent(targetIntent.getAction());
|
new ComponentName("com.ss.android.ugc.aweme", "com.ss.android.ugc.aweme.share.SystemShareActivity"),
|
||||||
queryIntent.setType(targetIntent.getType());
|
new ComponentName("com.ss.android.ugc.aweme", "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"),
|
||||||
queryIntent.setPackage("com.ss.android.ugc.aweme");
|
new ComponentName("com.ss.android.ugc.aweme", "com.ss.android.ugc.aweme.shortvideo.ui.VideoRecordNewActivity")
|
||||||
List<android.content.pm.ResolveInfo> resInfo = activity.getPackageManager().queryIntentActivities(queryIntent, 0);
|
};
|
||||||
|
chooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludes);
|
||||||
List<ComponentName> excludedComponents = new ArrayList<>();
|
} catch (Exception e) {}
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return chooser;
|
return chooser;
|
||||||
}
|
}
|
||||||
|
|||||||
30
keystore/daoqi_game_1.txt
Normal file
30
keystore/daoqi_game_1.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
密钥库类型: PKCS12
|
||||||
|
密钥库提供方: SunJSSE
|
||||||
|
|
||||||
|
您的密钥库包含 1 个条目
|
||||||
|
|
||||||
|
别名: gamehall
|
||||||
|
创建日期: 2026-3-5
|
||||||
|
条目类型: PrivateKeyEntry
|
||||||
|
证书链长度: 1
|
||||||
|
证书[1]:
|
||||||
|
所有者: L=CN, O=daoqi, OU=daoqi, CN=daoqi
|
||||||
|
发布者: L=CN, O=daoqi, OU=daoqi, CN=daoqi
|
||||||
|
序列号: 1
|
||||||
|
生效时间: Thu Mar 05 08:16:17 CST 2026, 失效时间: Mon Feb 27 08:16:17 CST 2051
|
||||||
|
证书指纹:
|
||||||
|
SHA1: 67:D1:7E:0E:E9:E7:C0:D0:93:AA:92:45:90:4C:33:16:C8:DB:7D:DB
|
||||||
|
SHA256: 49:8F:C8:CC:AB:BB:38:A1:C5:29:FB:52:D9:00:D7:9E:B8:F9:9E:75:C3:DB:08:27:BD:09:D5:53:75:82:F0:2F
|
||||||
|
签名算法名称: SHA256withRSA
|
||||||
|
主体公共密钥算法: 2048 位 RSA 密钥
|
||||||
|
版本: 1
|
||||||
|
|
||||||
|
|
||||||
|
*******************************************
|
||||||
|
*******************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
微信开放平台应用签名:
|
||||||
|
d9e138b6f20acfa14ae73113c7e44727
|
||||||
BIN
keystore/daoqi_game_2.keystore
Normal file
BIN
keystore/daoqi_game_2.keystore
Normal file
Binary file not shown.
30
keystore/daoqi_game_2.txt
Normal file
30
keystore/daoqi_game_2.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
密钥库类型: PKCS12
|
||||||
|
密钥库提供方: SunJSSE
|
||||||
|
|
||||||
|
您的密钥库包含 1 个条目
|
||||||
|
|
||||||
|
别名: gamehall
|
||||||
|
创建日期: 2026-3-14
|
||||||
|
条目类型: PrivateKeyEntry
|
||||||
|
证书链长度: 1
|
||||||
|
证书[1]:
|
||||||
|
所有者: O=daoqi, OU=daoqi, CN=daoqi
|
||||||
|
发布者: O=daoqi, OU=daoqi, CN=daoqi
|
||||||
|
序列号: 1
|
||||||
|
生效时间: Sat Mar 14 17:14:24 CST 2026, 失效时间: Wed Mar 08 17:14:24 CST 2051
|
||||||
|
证书指纹:
|
||||||
|
SHA1: 2F:76:97:3D:DC:E5:EA:56:7A:2B:53:E6:24:EF:74:CF:12:DF:A6:09
|
||||||
|
SHA256: B8:73:5A:3E:90:57:49:95:F7:B8:BB:0F:05:E7:76:7C:27:96:F8:5E:6F:66:96:4E:F0:0F:69:B1:E9:22:28:2F
|
||||||
|
签名算法名称: SHA256withRSA
|
||||||
|
主体公共密钥算法: 2048 位 RSA 密钥
|
||||||
|
版本: 1
|
||||||
|
|
||||||
|
|
||||||
|
*******************************************
|
||||||
|
*******************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
微信开放平台应用签名:
|
||||||
|
6f0e6ad5c028c9824eeb55c222c0f1af
|
||||||
BIN
keystore/daoqi_game_3.keystore
Normal file
BIN
keystore/daoqi_game_3.keystore
Normal file
Binary file not shown.
30
keystore/daoqi_game_3.txt
Normal file
30
keystore/daoqi_game_3.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
密钥库类型: PKCS12
|
||||||
|
密钥库提供方: SunJSSE
|
||||||
|
|
||||||
|
您的密钥库包含 1 个条目
|
||||||
|
|
||||||
|
别名: gamehall
|
||||||
|
创建日期: 2026-3-15
|
||||||
|
条目类型: PrivateKeyEntry
|
||||||
|
证书链长度: 1
|
||||||
|
证书[1]:
|
||||||
|
所有者: O=daoqi, OU=daoqi, CN=daoqi
|
||||||
|
发布者: O=daoqi, OU=daoqi, CN=daoqi
|
||||||
|
序列号: 1
|
||||||
|
生效时间: Sun Mar 15 17:42:36 CST 2026, 失效时间: Thu Mar 09 17:42:36 CST 2051
|
||||||
|
证书指纹:
|
||||||
|
SHA1: 44:8D:D5:4D:F3:D2:EA:F0:92:06:2D:69:9A:6C:8B:C3:EB:E5:70:CD
|
||||||
|
SHA256: 16:2B:EE:3F:3E:8A:64:A4:20:6E:4C:96:31:0F:21:D1:57:FC:FC:7E:3B:0A:AD:A3:34:0D:6F:AC:7E:99:0A:FB
|
||||||
|
签名算法名称: SHA256withRSA
|
||||||
|
主体公共密钥算法: 2048 位 RSA 密钥
|
||||||
|
版本: 1
|
||||||
|
|
||||||
|
|
||||||
|
*******************************************
|
||||||
|
*******************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
微信开放平台应用签名:
|
||||||
|
03f192808871ad51dbbf7b6e94c2d885
|
||||||
41
keystore/gamehall.txt
Normal file
41
keystore/gamehall.txt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
密钥库类型: JKS
|
||||||
|
密钥库提供方: SUN
|
||||||
|
|
||||||
|
您的密钥库包含 1 个条目
|
||||||
|
|
||||||
|
别名: gamehall
|
||||||
|
创建日期: 2017-3-8
|
||||||
|
条目类型: PrivateKeyEntry
|
||||||
|
证书链长度: 1
|
||||||
|
证书[1]:
|
||||||
|
所有者: CN=友乐互动游戏, OU=游戏部, O=天盛网络, L=南昌, ST=江西, C=CN
|
||||||
|
发布者: CN=友乐互动游戏, OU=游戏部, O=天盛网络, L=南昌, ST=江西, C=CN
|
||||||
|
序列号: 72f9b86c
|
||||||
|
生效时间: Wed Mar 08 09:55:16 CST 2017, 失效时间: Sun Mar 02 09:55:16 CST 2042
|
||||||
|
证书指纹:
|
||||||
|
SHA1: 08:CA:91:93:45:D3:C0:B4:76:73:E1:E6:7A:3D:74:C9:3E:B7:A7:11
|
||||||
|
SHA256: 95:36:ED:0E:52:38:92:AF:F9:F1:07:B6:4D:7B:07:F9:93:92:1E:EB:E2:33:FE:FE:D8:21:2A:CE:C2:57:F6:72
|
||||||
|
签名算法名称: SHA256withRSA
|
||||||
|
主体公共密钥算法: 2048 位 RSA 密钥
|
||||||
|
版本: 3
|
||||||
|
|
||||||
|
扩展:
|
||||||
|
|
||||||
|
#1: ObjectId: 2.5.29.14 Criticality=false
|
||||||
|
SubjectKeyIdentifier [
|
||||||
|
KeyIdentifier [
|
||||||
|
0000: 58 9C EB 3D 84 A1 10 15 B4 2C 20 A6 2E 42 AC B9 X..=....., ..B..
|
||||||
|
0010: 7A B8 66 E2 z.f.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*******************************************
|
||||||
|
*******************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
微信开放平台应用签名:
|
||||||
|
52f8eed9c81dbaf314561e1809c916f5
|
||||||
Reference in New Issue
Block a user