返回

React Native 查看后台应用:全方位指南

javascript

在开发社交类或游戏应用时,有时需要查看用户当前运行的应用列表,以便执行如自动更新在线状态等功能。这篇文章将提供两种实现方法,一种是利用原生模块,另一种是自定义实现。每种方法都会详细介绍步骤、代码示例,并给出常见问题的解答。

使用原生模块

iOS 方法

在 iOS 平台上,可以利用 NSWorkspaceNSRunningApplication 类获取正在运行的应用列表。

步骤:

  1. 创建一个原生模块来访问这些类。
  2. 在 React Native 应用中调用该模块方法以获取应用列表信息。

示例代码

在 iOS 项目中,创建一个新的 Swift 文件,并实现如下功能:

import Foundation
@objc(BackgroundAppsModule)
class BackgroundAppsModule: NSObject {
    @objc func getRunningApplications(_ resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void {
        let workspace = NSWorkspace.shared
        if let apps = workspace.runningApplications {
            var appNames: [String] = []
            for app in apps {
                if !app.isHiddenProcess {
                    appNames.append(app.localizedName ?? "Unknown")
                }
            }
            resolve(appNames)
        } else {
            reject("E_ERROR", "Failed to retrieve running applications.", nil)
        }
    }

    @objc static func requiresMainQueueSetup() -> Bool {
        return true
    }
}

AppDelegate.swift 中注册该模块:

import UIKit
import React

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    let moduleName = "BackgroundAppsModule"
    RCTBridge.setCustomDirectModules([moduleName])
    return true
  }
}

在 JavaScript 中调用模块:

import {NativeModules} from 'react-native';

const getRunningApps = async () => {
  try {
    const apps = await NativeModules.BackgroundAppsModule.getRunningApplications();
    console.log('Running Applications:', apps);
  } catch (error) {
    console.error('Failed to retrieve running applications:', error);
  }
};

getRunningApps();

Android 方法

在 Android 平台上,可通过调用 ActivityManager 类来获取正在运行的应用列表。

步骤:

  1. 创建一个原生模块并实现获取应用列表的功能。
  2. 在 React Native 应用中调用该模块方法以获得应用信息。

示例代码

新建 Java 文件:

package com.yourapp;

import android.app.ActivityManager;
import android.content.Context;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;

public class BackgroundAppsModule extends ReactContextBaseJavaModule {

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

    @Override
    public String getName() {
        return "BackgroundAppsModule";
    }

    @ReactMethod
    public void getRunningApplications(Promise promise) {
        ActivityManager activityManager = (ActivityManager) getReactApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningProcesses = activityManager.getRunningAppProcesses();

        if (runningProcesses != null) {
            ArrayList<String> processNames = new ArrayList<>();
            for (ActivityManager.RunningAppProcessInfo info : runningProcesses) {
                processNames.add(info.processName);
            }
            promise.resolve(processNames);
        } else {
            promise.reject("E_ERROR", "Failed to retrieve running applications.");
        }
    }
}

MainApplication.java 中注册模块:

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {
    // ... 省略其他代码

    @Override
    protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                new ReactModuleRegistryAdapter(this)
                );
    }

    private static class BackgroundAppsPackage implements ReactPackage {
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            return Collections.singletonList(new BackgroundAppsModule(reactContext));
        }
    }
}

在 JavaScript 中调用模块:

import {NativeModules} from 'react-native';

const getRunningApps = async () => {
  try {
    const apps = await NativeModules.BackgroundAppsModule.getRunningApplications();
    console.log('Running Applications:', apps);
  } catch (error) {
    console.error('Failed to retrieve running applications:', error);
  }
};

getRunningApps();

安全建议

在实现这些功能时,确保遵守所在平台的隐私政策和数据使用规则。获取其他应用信息可能需要用户授权,并且要明确告知用户这一行为的目的。

自定义实现

如果原生模块不符合需求,还可以考虑自定义实现方法,如通过网络服务调用第三方API来判断应用是否活跃。这要求服务器端有相应的处理能力,可以更灵活地适应不同的业务场景和安全策略。不过这种方法的开发复杂度较高,适用于对数据准确性和实时性有高要求的应用。

实现思路

  1. 在客户端定期向服务器发送心跳信息。
  2. 服务端记录这些心跳,并据此判断应用是否处于活跃状态。
  3. 客户端通过查询服务端来获取其他应用的状态。

这种方法的实现细节依赖于具体业务需求和服务器架构,因此不提供详细的代码示例。但在设计时应特别注意数据的安全性和隐私保护问题。

以上是两种查看后台应用的方法介绍,根据实际项目的需求选择合适的方式加以实施即可。