基于React Native开发防手机成瘾应用:如何获取运行中社交APP时长?
在React Native中获取Android/iOS平台的社交应用列表及使用时长
Android 平台实现
1. 权限配置
Android 5.0(API 21)及以上必须申请PACKAGE_USAGE_STATS权限,该权限无法通过常规运行时弹窗请求,需引导用户到系统设置手动开启:
- 在
android/app/src/main/AndroidManifest.xml中添加权限声明:<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" /> - RN端实现跳转至权限设置页面的逻辑,需配合原生模块完成:
对应Android原生模块(Kotlin示例):import { Platform, NativeModules } from 'react-native'; const openUsageStatsSettings = () => { if (Platform.OS === 'android') { NativeModules.OpenSettings.openUsageStatsSettings(); } };class OpenSettingsModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { override fun getName() = "OpenSettings" @ReactMethod fun openUsageStatsSettings() { val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) reactContext.startActivity(intent) } }
2. 获取应用使用数据
创建原生模块调用UsageStatsManager获取应用使用统计,通过预设包名列表过滤社交类应用:
- Kotlin原生模块核心代码:
@ReactMethod fun getSocialAppUsage(promise: Promise) { val usageStatsManager = reactContext.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager val endTime = System.currentTimeMillis() val startTime = endTime - 24 * 60 * 60 * 1000 // 统计过去24小时数据 val queryUsageStats = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_DAILY, startTime, endTime ) // 常见社交应用包名列表,可根据需求扩展 val socialPackageNames = listOf( "com.tencent.mm", // 微信 "com.sina.weibo", // 微博 "com.facebook.katana", // Facebook "com.instagram.android" // Instagram ) val result = mutableListOf<HashMap<String, Any>>() queryUsageStats.forEach { stats -> if (socialPackageNames.contains(stats.packageName)) { val appInfo = reactContext.packageManager.getApplicationInfo(stats.packageName, 0) val appName = reactContext.packageManager.getApplicationLabel(appInfo).toString() val usageTime = stats.totalTimeInForeground // 前台使用时长(毫秒) result.add(hashMapOf( "appName" to appName, "packageName" to stats.packageName, "usageTime" to usageTime )) } } promise.resolve(result) } - RN端调用:
import { NativeModules } from 'react-native'; const getSocialAppUsage = async () => { try { const data = await NativeModules.AppUsage.getSocialAppUsage(); console.log(data); return data; } catch (error) { console.error(error); } };
iOS 平台实现
1. 权限配置
iOS 12及以上需使用Screen Time框架,需在Info.plist中添加权限描述:
<key>com.apple.developer.usagedescriptions</key> <string>需要获取应用使用数据以管理社交应用使用时长</string>
2. 获取应用使用数据
受iOS沙盒机制限制,无法直接获取正在运行的第三方应用列表,只能通过Screen Time获取应用使用时长数据,再通过bundle ID过滤社交类应用:
- Swift原生模块核心代码:
import ScreenTime @objc(AppUsageModule) class AppUsageModule: NSObject, RCTBridgeModule { static func moduleName() -> String! { return "AppUsage" } static func requiresMainQueueSetup() -> Bool { return true } @objc func getSocialAppUsage(_ resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { let center = DeviceActivityCenter() let startDate = Date().addingTimeInterval(-24 * 60 * 60) // 统计过去24小时数据 let endDate = Date() let interval = DateInterval(start: startDate, end: endDate) center.requestAuthorization(for: .individual) { status in guard status == .approved else { reject("AUTH_ERROR", "未授权Screen Time权限", nil) return } center.fetchReports(for: interval) { reports, error in guard let reports = reports, error == nil else { reject("FETCH_ERROR", "获取数据失败", error) return } // 常见社交应用bundle ID列表,可根据需求扩展 let socialBundleIDs = [ "com.tencent.xin", // 微信 "com.sina.weibo", // 微博 "com.facebook.Facebook", // Facebook "com.instagram.instagram" // Instagram ] var result = [[String: Any]]() for report in reports { if let bundleID = report.applicationIdentifier, socialBundleIDs.contains(bundleID) { let usageTime = report.totalActivityTime // 使用时长(秒) // 可通过bundleID获取应用名称,需额外处理系统应用名称映射 let appName = bundleID.split(separator: ".").last ?? bundleID result.append([ "appName": appName, "bundleID": bundleID, "usageTime": usageTime * 1000 // 转换为毫秒 ]) } } resolve(result) } } } } - RN端调用逻辑与Android一致,直接调用
NativeModules.AppUsage.getSocialAppUsage()即可。
关键注意事项
- Android:可通过
AppOpsManager提前检查PACKAGE_USAGE_STATS权限是否开启,避免无权限时获取数据失败;社交应用识别也可尝试通过应用category属性动态判断,但兼容性较差,建议优先使用预设包名列表。 - iOS:Screen Time权限需用户主动授权,且只能获取授权后的应用使用数据;无法实时监测应用运行状态,只能通过使用时长数据判断最近活跃的社交应用。
内容的提问来源于stack exchange,提问作者Anojan
相关产品推荐
相关产品推荐

