You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Native Android中获取其他应用的使用信息

在React Native Android中获取其他应用使用时长的实现方案

1. 权限配置

首先需要在Android项目的AndroidManifest.xml中添加系统保护权限:

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />

注意:该权限无法通过React Native的PermissionsAndroid请求弹窗获取,必须引导用户手动进入系统设置的**「有权查看使用情况的应用」**页面开启权限。

2. 编写Android原生模块

React Native没有内置获取其他应用使用时长的API,需要自定义原生模块调用Android的UsageStatsManager:

步骤2.1 创建原生模块类

在android/app/src/main/java/com/[你的项目包名]/下创建AppUsageModule.java:

package com.yourprojectname;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.Promise;
import android.app.AppOpsManager;
import android.content.Context;
import android.os.Process;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AppUsageModule extends ReactContextBaseJavaModule {

    public AppUsageModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        // 模块名称,React Native端将通过这个名称调用
        return "AppUsageModule";
    }

    // 检查是否拥有使用情况统计权限
    private boolean hasUsageStatsPermission() {
        AppOpsManager appOps = (AppOpsManager) getReactApplicationContext().getSystemService(Context.APP_OPS_SERVICE);
        int mode = appOps.checkOpNoThrow(
                AppOpsManager.OPSTR_GET_USAGE_STATS,
                Process.myUid(),
                getReactApplicationContext().getPackageName()
        );
        return mode == AppOpsManager.MODE_ALLOWED;
    }

    @ReactMethod
    public void getAppUsageToday(ReadableArray packageNames, Promise promise) {
        // 先检查权限
        if (!hasUsageStatsPermission()) {
            promise.reject("PERMISSION_DENIED", "需要开启使用情况访问权限");
            return;
        }

        UsageStatsManager usageStatsManager = (UsageStatsManager) getReactApplicationContext()
                .getSystemService(Context.USAGE_STATS_SERVICE);
        long endTime = System.currentTimeMillis();
        long startTime = endTime - 24 * 60 * 60 * 1000; // 今日0点到当前时间的时间范围

        // 查询今日的应用使用统计数据
        List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(
                UsageStatsManager.INTERVAL_DAILY,
                startTime,
                endTime
        );

        Map<String, Double> resultMap = new HashMap<>();

        // 遍历目标包名,计算每个应用的总前台时长
        for (int i = 0; i < packageNames.size(); i++) {
            String packageName = packageNames.getString(i);
            long totalForegroundTime = 0;

            for (UsageStats stats : usageStatsList) {
                if (stats.getPackageName().equals(packageName)) {
                    totalForegroundTime += stats.getTotalTimeInForeground();
                }
            }

            // 转换为小时(保留两位小数),也可以根据需求转为分钟
            double hours = totalForegroundTime / (1000.0 * 60 * 60);
            resultMap.put(packageName, hours);
        }

        promise.resolve(resultMap);
    }
}

步骤2.2 注册原生模块

创建AppUsagePackage.java来注册模块:

package com.yourprojectname;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class AppUsagePackage implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new AppUsageModule(reactContext));
        return modules;
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

步骤2.3 在MainApplication中添加包

修改MainApplication.java的getPackages方法,添加自定义包:

@Override
protected List<ReactPackage> getPackages() {
    @SuppressWarnings("UnnecessaryLocalVariable")
    List<ReactPackage> packages = new PackageList(this).getPackages();
    // 添加自定义模块包
    packages.add(new AppUsagePackage());
    return packages;
}

3. React Native端调用

在React Native组件中调用原生模块,并处理权限和结果:

import { NativeModules, Alert, Linking, Platform } from 'react-native';

// 导入自定义原生模块
const AppUsageModule = NativeModules.AppUsageModule;

// 获取指定应用今日使用时长的方法
const getAppUsageData = async () => {
    // 仅在Android平台执行
    if (Platform.OS !== 'android') return;

    try {
        // 传入目标应用的包名列表
        const usageData = await AppUsageModule.getAppUsageToday([
            'com.whatsapp',        // WhatsApp
            'com.instagram.android',// Instagram
            'com.google.android.gm' // Gmail(示例邮箱应用)
        ]);

        // 格式化数据为易读格式
        const formattedData = Object.entries(usageData).map(([packageName, hours]) => {
            let durationText;
            if (hours >= 1) {
                durationText = `${hours.toFixed(1)}小时`;
            } else {
                const minutes = Math.round(hours * 60);
                durationText = `${minutes}分钟`;
            }

            return {
                appName: getAppDisplayName(packageName),
                duration: durationText
            };
        });

        // 输出或展示结果
        console.log('应用使用时长:', formattedData);
        // 这里可以将formattedData渲染到UI上

    } catch (error) {
        // 处理权限缺失的情况
        if (error.code === 'PERMISSION_DENIED') {
            Alert.alert(
                '权限提示',
                '需要开启「有权查看使用情况的应用」权限才能获取应用使用时长',
                [
                    { text: '取消', style: 'cancel' },
                    { text: '去设置', onPress: () => Linking.openSettings() }
                ]
            );
        } else {
            console.error('获取应用使用时长失败:', error);
        }
    }
};

// 根据包名映射应用名称
const getAppDisplayName = (packageName) => {
    switch(packageName) {
        case 'com.whatsapp':
            return 'WhatsApp';
        case 'com.instagram.android':
            return 'Instagram';
        case 'com.google.android.gm':
            return 'Gmail';
        default:
            return packageName;
    }
};

// 调用方法示例
// getAppUsageData();

4. 关键注意事项

  • Android版本限制:UsageStatsManager仅支持Android 5.0(API 21)及以上版本,低于该版本无法实现此功能。
  • 权限特殊性:必须引导用户手动开启权限,无法通过常规权限请求流程自动获取。
  • 包名准确性:目标应用的包名必须准确,不同应用的包名可能不同(例如国内邮箱应用需自行查找对应包名)。
  • 数据精度:返回的时长是应用在前台的累计时间,与系统设置中显示的统计数据可能存在细微差异,取决于系统的统计逻辑。

内容的提问来源于stack exchange,提问作者Sayali Sonawane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 08:25:25