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