android判断设备是否为真机

本文提供了一种可靠的检测安卓设备是否为模拟器的方法,并附带了实现代码。通过检查特定的设备标识符来判断,避免非真机用户注册。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

楼主有个应用需要判断设备是否为真机,如果是模拟器就不能让用户注册,开始思路是判断设备有无GPS模块,楼主用夜神模拟器测了下,都不行。

然后在网上找检测设备是否为模拟器,找到解决方法,真的很靠谱,但有些权限没有写上去,所以获取到的都不大行,所以在这总结一下,希望大家少走弯路。

楼主亲测有效


1.获取权限

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
2.判断设备是否为真机


/**
 * 判断当前设备是否是真机。如果返回TRUE,则当前是真机,不是返回FALSE
 *
 * @return
 */
public static boolean isRealMachine() {
   String BOARD =android.os.Build.BOARD;
   String BOOTLOADER =android.os.Build.BOOTLOADER;
   String BRAND =android.os.Build.BRAND;
   String DEVICE =android.os.Build.DEVICE;
   String HARDWARE =android.os.Build.HARDWARE;
   String MODEL =android.os.Build.MODEL;
   String PRODUCT =android.os.Build.PRODUCT;
   if(BOARD== "unknown"|| BOOTLOADER== "unknown"
         ||BRAND =="generic" ||DEVICE =="generic"
         ||MODEL =="sdk" ||PRODUCT =="sdk"
         ||HARDWARE =="goldfish")
   {
      Log.v("Result:","Find Emulator by EmulatorBuild!");
      return true;
   }
   Log.v("Result:","Not Find Emulator by EmulatorBuild!");
   return false;
}


下面贴出楼主找到的资料链接:http://blog.csdn.net/androidstarjack/article/details/53400463   感谢androidstarjack大神!



如有疑问,欢迎留言!

<think>根据用户的问题,用户希望了解在Flutter中如何判断运行环境是模拟器还是真实设备。在Flutter中,我们可以通过平台通道(Platform Channel)调用原生代码(Android和iOS)来获取设备信息,进而判断是否为模拟器。 对于Android平台,我们可以通过检查设备特征(如硬件名称、品牌等)来判断是否为模拟器。常见的模拟器特征包括硬件名称中包含"goldfish"或"ranchu",品牌为"generic"等。 对于iOS平台,模拟器通常具有特定的标识符,如"i386"或"x86_64"(表示Intel模拟器)或"arm64"(表示Apple Silicon模拟器),而真实设备通常是ARM架构(如"armv7"、"arm64"等)。 我们可以通过创建一个Flutter插件或直接在Dart代码中通过平台通道调用原生代码来实现。以下是一个简单的实现方案: 1. 在Dart层面,我们使用`MethodChannel`来调用原生方法。 2. 在Android原生代码中,我们编写一个方法检测模拟器。 3. 在iOS原生代码中,同样编写一个方法检测模拟器。 下面是一个示例代码: ### Dart代码 (lib/main.dart) ```dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Device Check')), body: Center( child: FutureBuilder<bool>( future: isSimulator(), builder: (context, snapshot) { if (snapshot.hasData) { return Text('Is Simulator: ${snapshot.data}'); } else { return CircularProgressIndicator(); } }, ), ), ), ); } Future<bool> isSimulator() async { const platform = MethodChannel('device_info'); try { final bool result = await platform.invokeMethod('isSimulator'); return result; } on PlatformException catch (e) { print("Failed to get device info: '${e.message}'."); return false; } } } ``` ### Android原生代码 (android/app/src/main/kotlin/.../MainActivity.kt) 在Android的MainActivity中,我们添加一个方法`isSimulator`来检测模拟器: ```kotlin package com.example.myapp // 替换为你的包名 import androidx.annotation.NonNull import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity: FlutterActivity() { private val CHANNEL = "device_info" override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "isSimulator") { result.success(isEmulator()) } else { result.notImplemented() } } } private fun isEmulator(): Boolean { return (android.os.Build.FINGERPRINT.startsWith("generic") || android.os.Build.FINGERPRINT.startsWith("unknown") || android.os.Build.MODEL.contains("google_sdk") || android.os.Build.MODEL.contains("Emulator") || android.os.Build.MODEL.contains("Android SDK built for x86") || android.os.Build.MANUFACTURER.contains("Genymotion") || android.os.Build.BRAND.startsWith("generic") && android.os.Build.DEVICE.startsWith("generic") || "google_sdk" == android.os.Build.PRODUCT) } } ``` ### iOS原生代码 (ios/Runner/AppDelegate.swift) 在iOS的AppDelegate中,我们添加一个方法`isSimulator`来检测模拟器: ```swift import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let deviceInfoChannel = FlutterMethodChannel(name: "device_info", binaryMessenger: controller.binaryMessenger) deviceInfoChannel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in guard call.method == "isSimulator" else { result(FlutterMethodNotImplemented) return } self?.isSimulator(result: result) }) GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func isSimulator(result: FlutterResult) { #if targetEnvironment(simulator) result(true) #else result(false) #endif } } ``` ### 说明 1. 在Android中,我们通过检查一些特定的构建属性来判断设备是否为模拟器。这些属性在模拟器上通常具有特定的值(如`generic`、`google_sdk`等)。 2. 在iOS中,我们使用编译宏`#if targetEnvironment(simulator)`来检查当前运行环境是否为模拟器。如果是模拟器,返回`true`,否则返回`false`。 这样,当我们在Flutter应用中调用`isSimulator`方法时,就会根据当前平台返回相应的结果。 ### 注意事项 - 上述代码只是一个基本示例,实际使用中可能需要根据不同的模拟器或设备进行更多的测试和调整。 - 在Android上,由于设备种类繁多,可能需要根据实际情况调整判断逻辑。 ### 相关问题 1. 在Flutter中如何获取设备信息(如设备型号、操作系统版本等)? 2. 如何创建一个Flutter插件来封装平台特定的功能? 3. 在Flutter中如何处理平台通道(Platform Channel)的异常?</think>在Flutter中判断运行环境是模拟器还是真实设备,需要通过平台通道(Platform Channel)调用原生代码实现。以下是具体实现方案: ### 解决方案(Dart代码) ```dart import 'package:flutter/services.dart'; Future<bool> isSimulator() async { const platform = MethodChannel('device_info'); try { final bool result = await platform.invokeMethod('isSimulator'); return result; } on PlatformException catch (e) { print("获取设备信息失败: ${e.message}"); return false; } } // 使用示例 void checkDevice() async { if (await isSimulator()) { print("当前运行在模拟器"); } else { print("当前运行在真实设备"); } } ``` ### 平台原生代码实现 #### 1. **Android原生代码** (Kotlin) 在 `MainActivity.kt` 中添加: ```kotlin import android.os.Build import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "device_info" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "isSimulator") { result.success(isEmulator()) } else { result.notImplemented() } } } private fun isEmulator(): Boolean { return (Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown") || Build.MODEL.contains("google_sdk") || Build.MODEL.contains("Emulator") || Build.MODEL.contains("Android SDK built for x86") || Build.MANUFACTURER.contains("Genymotion") || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) || "google_sdk" == Build.PRODUCT) } } ``` #### 2. **iOS原生代码** (Swift) 在 `AppDelegate.swift` 中添加: ```swift import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: "device_info", binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) in if call.method == "isSimulator" { result(self?.isSimulator()) } else { result(FlutterMethodNotImplemented) } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func isSimulator() -> Bool { #if targetEnvironment(simulator) return true #else return false #endif } } ``` ### 实现原理 1. **Android检测逻辑**: - 通过检查 `Build` 类的特定字段(如 `FINGERPRINT`, `MODEL`, `PRODUCT` 等) - 模拟器通常包含关键词:`generic`, `Emulator`, `google_sdk`, `Android SDK built for x86` 2. **iOS检测逻辑**: - 使用Swift编译宏 `#if targetEnvironment(simulator)` - 该宏仅在Xcode模拟器环境下生效 3. **跨平台通信**: - 通过 `MethodChannel` 实现Dart与原生代码双向通信 - 统一返回布尔值标识设备类型 ### 注意事项 1. Android真机可能返回假阳性(某些定制ROM可能包含模拟器关键词) 2. iOS模拟器检测100%准确,无需额外配置 3. 需要分别在Android/iOS目录实现原生代码(路径:`android/app/.../MainActivity.kt` 和 `ios/Runner/AppDelegate.swift`) ### 相关引用 Flutter平台通道的官方实现可参考文档:[Writing custom platform-specific code](https://docs.flutter.dev/platform-integration/platform-channels)[^1] --- ### 相关问题 1. 如何在Flutter中获取设备的其他硬件信息(如CPU架构、内存大小)? 2. Flutter如何实现只在真机环境下调用特定功能(如摄像头、GPS)? 3. 在混合开发中,Flutter与原生平台通信还有哪些常用方式?
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值