318 lines
6.9 KiB
JavaScript
318 lines
6.9 KiB
JavaScript
// utils/chrome-browser.js
|
||
|
||
/**
|
||
* 谷歌浏览器处理工具类
|
||
* 功能:
|
||
* 1. 检查是否安装谷歌浏览器
|
||
* 2. 预下载APK文件
|
||
* 3. 安装并打开链接
|
||
*/
|
||
import {
|
||
isAndroid,
|
||
checkChromeInstalled,
|
||
moveChromeApkToDevice
|
||
} from './fileUtils'
|
||
class ChromeBrowser {
|
||
// 存储检查结果
|
||
static hasChrome = null;
|
||
static apkDownloaded = false;
|
||
static apkPath = null;
|
||
|
||
|
||
/**
|
||
* 打开URL,自动处理浏览器
|
||
* @param {string} url - 要打开的URL
|
||
* @returns {Promise<boolean>} 是否成功处理
|
||
*/
|
||
static async openUrl(url) {
|
||
if (!url) {
|
||
console.error('ChromeBrowser: URL为空');
|
||
return false;
|
||
}
|
||
return new Promise((resolve, reject) => {
|
||
plus.runtime.openURL(url, async (err) => {
|
||
// 如果进入了 error 回调,说明无法通过 Chrome 打开
|
||
if (err) {
|
||
console.log('检测失败,Chrome 可能未安装:', err);
|
||
try {
|
||
// 调用 installAndOpen 方法
|
||
const result = await this.installAndOpen(url);
|
||
resolve(result);
|
||
} catch (error) {
|
||
console.error('installAndOpen 失败:', error);
|
||
resolve(false);
|
||
}
|
||
} else {
|
||
// 成功打开,没有错误
|
||
resolve(true);
|
||
}
|
||
}, "com.android.chrome");
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 使用谷歌浏览器打开URL
|
||
* @param {string} url
|
||
*/
|
||
static openWithChrome(url) {
|
||
// #ifdef APP-PLUS
|
||
plus.runtime.openURL(url, {
|
||
pname: 'Chrome'
|
||
});
|
||
// #endif
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 安装谷歌浏览器并打开URL
|
||
* @param {string} url
|
||
* @returns {Promise<boolean>}
|
||
*/
|
||
static async installAndOpen(url) {
|
||
// #ifdef APP-PLUS
|
||
try {
|
||
// 显示安装确认对话框
|
||
const confirm = await this.showInstallConfirm();
|
||
if (!confirm) {
|
||
// 用户取消,使用默认浏览器
|
||
plus.runtime.openURL(url);
|
||
return false;
|
||
}
|
||
|
||
// 安装APK
|
||
const installed = await this.initWorkflow();
|
||
|
||
if (installed) {
|
||
// 安装成功,更新状态
|
||
this.hasChrome = true;
|
||
uni.setStorageSync('has_chrome_browser', true);
|
||
|
||
// 使用新安装的浏览器打开
|
||
setTimeout(() => {
|
||
this.openWithChrome(url);
|
||
}, 1000);
|
||
|
||
return true;
|
||
} else {
|
||
// 安装失败,使用默认浏览器
|
||
plus.runtime.openURL(url);
|
||
return false;
|
||
}
|
||
} catch (error) {
|
||
console.error('ChromeBrowser: 安装流程失败:', error);
|
||
plus.runtime.openURL(url);
|
||
return false;
|
||
}
|
||
// #endif
|
||
|
||
// return false;
|
||
}
|
||
|
||
/**
|
||
* 显示安装确认对话框
|
||
* @returns {Promise<boolean>}
|
||
*/
|
||
static showInstallConfirm() {
|
||
return new Promise((resolve) => {
|
||
uni.showModal({
|
||
title: '安装谷歌浏览器',
|
||
content: '检测到您未安装谷歌浏览器\n\n建议安装谷歌浏览器以获得最佳体验\n是否现在安装?',
|
||
confirmText: '立即安装',
|
||
cancelText: '使用其他浏览器',
|
||
success: (res) => {
|
||
resolve(res.confirm);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
static async initWorkflow() {
|
||
return new Promise(async (resolve) => {
|
||
try {
|
||
// 动态申请存储权限 (针对 Android)
|
||
const hasPermission = await this.requestAndroidPermission(
|
||
'android.permission.WRITE_EXTERNAL_STORAGE')
|
||
if (!hasPermission) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '请授予存储权限以保存安装包',
|
||
showCancel: false
|
||
})
|
||
return
|
||
}
|
||
|
||
// 执行移动逻辑
|
||
uni.showLoading({
|
||
title: '正在准备资源...'
|
||
})
|
||
const result = await moveChromeApkToDevice()
|
||
uni.hideLoading()
|
||
|
||
uni.showModal({
|
||
title: '就绪',
|
||
content: `安装包已保存至:Downloads/${result.name}`,
|
||
confirmText: '去安装',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
this.installApk(result.fullPath, resolve);
|
||
} else {
|
||
resolve(false);
|
||
}
|
||
}
|
||
})
|
||
} catch (e) {
|
||
uni.hideLoading()
|
||
console.error('流程失败:', e)
|
||
uni.showToast({
|
||
title: '操作失败: ' + e,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
});
|
||
}
|
||
|
||
// 动态权限申请核心代码
|
||
static requestAndroidPermission(permissionID) {
|
||
return new Promise((resolve) => {
|
||
plus.android.requestPermissions(
|
||
[permissionID],
|
||
(resultObj) => {
|
||
if (resultObj.granted.length > 0) {
|
||
resolve(true)
|
||
} else {
|
||
resolve(false)
|
||
}
|
||
},
|
||
(error) => {
|
||
console.error('权限请求错误:', error)
|
||
resolve(false)
|
||
}
|
||
)
|
||
})
|
||
}
|
||
|
||
|
||
/**
|
||
* 实时下载并安装
|
||
* @param {Function} resolve
|
||
*/
|
||
static downloadAndInstall(resolve) {
|
||
uni.showLoading({
|
||
title: '正在下载...\n约十分钟',
|
||
mask: true
|
||
});
|
||
|
||
const downloadUrl =
|
||
'https://database.yuxindazhineng.com/user-file//690c72a6b8ffa329af2d5607/avatar/com.android.chrome.apk';
|
||
const fileName = `_downloads/chrome_${Date.now()}.apk`;
|
||
|
||
const dtask = plus.downloader.createDownload(
|
||
downloadUrl, {
|
||
filename: fileName
|
||
},
|
||
(d, status) => {
|
||
uni.hideLoading();
|
||
|
||
if (status === 200) {
|
||
console.log('ChromeBrowser: 下载成功,开始安装');
|
||
this.installApk(d.filename, resolve);
|
||
} else {
|
||
console.error('ChromeBrowser: 下载失败,状态码:', status);
|
||
this.showDownloadError();
|
||
resolve(false);
|
||
}
|
||
}
|
||
);
|
||
|
||
dtask.start();
|
||
}
|
||
|
||
/**
|
||
* 安装APK文件
|
||
* @param {string} filePath
|
||
* @param {Function} resolve
|
||
*/
|
||
static installApk(filePath, resolve) {
|
||
uni.showLoading({
|
||
title: '准备中...',
|
||
mask: true
|
||
});
|
||
|
||
plus.runtime.install(
|
||
filePath, {
|
||
force: false
|
||
},
|
||
() => {
|
||
uni.hideLoading();
|
||
console.log('ChromeBrowser: 安装成功');
|
||
uni.showToast({
|
||
title: '准备完成',
|
||
icon: 'success',
|
||
duration: 1500
|
||
});
|
||
resolve(true);
|
||
},
|
||
(error) => {
|
||
uni.hideLoading();
|
||
console.error('ChromeBrowser: 安装失败:', error);
|
||
uni.removeStorageSync('chrome_apk_path');
|
||
this.showInstallError(filePath);
|
||
resolve(false);
|
||
}
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 显示下载错误提示
|
||
*/
|
||
static showDownloadError() {
|
||
uni.showModal({
|
||
title: '下载失败',
|
||
content: '无法下载谷歌浏览器\n请检查网络连接后重试',
|
||
showCancel: false
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 显示安装错误提示
|
||
* @param {string} filePath
|
||
*/
|
||
static showInstallError(filePath) {
|
||
uni.showModal({
|
||
title: '安装失败',
|
||
content: '自动安装失败\n请在文件管理中手动安装\n或退出应用后台重新进入下载',
|
||
confirmText: '查看文件',
|
||
success: (res) => {
|
||
if (res.confirm && filePath) {
|
||
// 尝试打开文件
|
||
plus.runtime.openFile(filePath);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 强制重新检查浏览器状态
|
||
* @returns {Promise<boolean>}
|
||
*/
|
||
static async forceCheck() {
|
||
console.log('ChromeBrowser: 强制重新检查');
|
||
this.hasChrome = null;
|
||
return await this.init();
|
||
}
|
||
|
||
/**
|
||
* 获取当前状态信息
|
||
*/
|
||
static getStatus() {
|
||
return {
|
||
hasChrome: this.hasChrome,
|
||
apkDownloaded: this.apkDownloaded,
|
||
apkPath: this.apkPath,
|
||
cachedHasChrome: uni.getStorageSync('has_chrome_browser'),
|
||
cachedApkPath: uni.getStorageSync('chrome_apk_path')
|
||
};
|
||
}
|
||
}
|
||
|
||
export default ChromeBrowser; |