Detecting app run on emulator or real device - dart

I need to detect, if an app is running on an iOS or Android emulator to skip an QR code scan method and just return a scanned code.
Q: How do I detect
on which device type - iOS or Android - an app is running and
if an app is running on an emulator?

Just found this plugin, which prints various details:
https://pub.dartlang.org/packages/device_info#-readme-tab-
Output on Android emulator [see last line]:

safe_device: ^1.1.1
import 'package:safe_device/safe_device.dart';
Checks whether device is real or emulator
bool isRealDevice = await SafeDevice.isRealDevice;
(ANDROID ONLY) Check if development Options is enable on device
bool isDevelopmentModeEnable = await SafeDevice.isDevelopmentModeEnable;

Related

Bluetooth scan not work when using flutter in ios

I'm using flutter_blue_plus package which is almost same with flutter_blue. When I test with iphone 13 mini connected with mac book xcode, my app scans bluetooth devices well. But when I extract my app to .ipa and install the app using xcode, my iphone 13 mini(which is not connected to mac book) not scan bluetooth devices anymore. Of course I've checked that I give same permission to the iphone both of the test.
Is there any suggestion for test or anyone experienced same situation?
I'm very beginner of flutter and ios development (I just started it from a month ago), so please give me any advice if you have about this bluetooth problem..
My scan function is in the background mode, and I checked the scanned devices using snack bar. But I think it is not the problem, the app works well when I test with xcode and the iphone is connected to mac.
I added a part of my code for your information.
(My function for BLE Scanning)
Future<void> initialScanning() async {
// ios execute this function with .ipa installed but skips scanning.
final FlutterBluePlus flutterBlue = FlutterBluePlus.instance;
// Start scanning
flutterBlue.startScan(timeout: Duration(seconds: _firstScanDuration));
// Listen to scan results
var subscription = flutterBlue.scanResults.listen((results) async {
// Find the device with the name and Register
for (ScanResult r in results) {
print('${r.device.name} rssi: ${r.rssi}');
if (r.device.name == 'raspberrypi') {
if (!devices.contains(r.device)) {
devices.add(r.device);
print('device added!!!!');
}
}
}
for (BluetoothDevice device in devices) {
if (!registeredDevices.contains(device.id.toString())) {
registeredDevices.add(device.id.toString());
await someBleRegister(device);
}
}
});
// Stop scanning
flutterBlue.stopScan();
}
(onEvent function for flutter_foreground_task)
#override
Future<void> onEvent(DateTime timestamp, SendPort? sendPort) async {
if (_eventCount == 0) {
await initialScanning();
} else {
print('number of devices: ${someBles.length}');
for (SomeBle ble in someRegisteredBles) {
await someBleReadAndWrite(ble);
}
}
I my self found out the answer that flutter_blue_plus.startScan (i.e. BLE scan) is not work well with flutter_foreground_task package in ios.
When I use the startScan in onStart( a override method of flutter_foreground_task package), the BLE scanning was work well with normal development setup with xcode.
But the same code was not work when I made .ipa file and installed to iphone.
It never scans anything and skips the scanning.
But when I moved the BLE scanning codes to the foreground, it worked well both xcode connected and .ipa file installed.
I don't know why.. but, anyway, that is true.
(Edit) flutter_reactive_ble not work too in flutter_foreground_task background mode with .ipa file installed.

iOS Simulator crashes on microphone permission request

My environment:
permission_handler 3.0.0
Flutter v1.2.1
OSX High Sierra 10.13.6
Xcode version 10.1.
My app is crashing when I request the permission for microphone in the iOS simulator.
PermissionStatus mic = await PermissionHandler()
.checkPermissionStatus(PermissionGroup.microphone);
print('microphone permission? ${mic.toString()}');
try {
if (mic != PermissionStatus.granted) {
await PermissionHandler().requestPermissions([PermissionGroup.microphone]);
}
} catch (e) {
print(e);
}
No error is thrown or caught, but in the flutter debug console, I see:
flutter: microphone permission? PermissionStatus.unknown
Lost connection to device.
This means that checkPermissionStatus() returned unknown. But then when I request the permission, the application crashes. I have not been able to try this on a real iPhone. Everything works perfectly on the Android simulator.
I've seen there were some problems in Xcode 10.1 with the microphone:
iOS Simulator would like to access microphone every time
Repeated request for microphone permission on iOS Simulator
What I've tried
Fresh build with flutter clean
Changing the simulator microphone input in Hardware > Audio Input
I could try to upgrade to Xcode 10.2, but I'd need to get mojave first. Trying to avoid that if possible as it might not even fix the issue. I can also try using a real iPhone device instead of the simulator. Would love to get the simulator not crashing, though.
Is anyone able to grant microphone permission in Xcode 10.1/10.2 simulator using permission_handler: 3.0.0? What about another flutter permission plugin?
Please make sure you have added the correct entries to the Info.plist file (for Flutter projects this file is located in the ios/Runner/ folder).
To access the microphone you will need to add the following lines in between the <dict> tags:
<key>NSMicrophoneUsageDescription</key>
<string>this application needs access to the microphone</string>
More information can be found here.
And a complete example of an Info.plist can be found here.

Xamarin.UITests - testing on real device - iOS - app permissions popups issue

I've iOS app that needs some privileges (GPS, Push notifications).
When app starts for a first time iOS asks user if they're ok with granting those permissions to application.
I've written some UITests and want to automate running them on locally connected iPhone.
The problem is that I cannot override permissions questions and my tests fails.
I found out that application deployed by IDE (Xamarin Studio) will ask for permissions, but application deployed via UITests will not.
So I tried with .AppBundle(path_to_app) but it says this is only valid for deploying to Simulator.
SetUp : System.Exception : This app bundle is not valid for running on
a simulator. To fix this issue please ensure that your target device
is a simulator. DTPlatformName is 'iphoneos', not 'iphonesimulator' in
the apps Info.plist.
Like it's trying to deploy iPhone app to Simulator. But Target in Xamarin Studio is set to real device.
I tried to add .DeviceIdentifier. When Used with .InstalledApp it was starting up (still asking for permissions).
But when I used DeviceIdentifier and AppBundle there was the same error as above.
My tests works fine on Test Cloud. They work fine on Simulator.
They work fine when I deploy to device manually, start app and approve permissions then run UI tests.
What I cannot achieve is to make UITests override permissions questions on real device.
Anyone made this work?
Last thing is that I found is in documentation for AppBundle method
"Will force a run on simulator"
https://developer.xamarin.com/api/member/Xamarin.UITest.Configuration.iOSAppConfigurator.AppBundle/p/System.String/
So I may be doomed with the task but maybe someone knows a workaround?
You can dismiss system dialogs with UITest by using InvokeUIA. The test below works by tapping the "OK" button of an iOS system alert:
[Test]
public void AppLaunches ()
{
app.Screenshot ("First screen.");
app.InvokeUia ("uia.query('[:view {:marked \"OK\"}]')");
app.InvokeUia ("uia.tapMark(\"OK\")");
}
A working sample app & UITest is also here:
https://github.com/King-of-Spades/InvokeUia-for-System-Dialogs
Warning about system dialogs in Test Cloud
The reason that you don't see this issue in Test Cloud is because Test Cloud automatically dismisses the system alerts; so usually you don't have to worry about it. However, if your alert launches too soon; so that it appears before the automation has fully started your app, then it will be unable to detect & dismiss the alert and cause your test to fail.
So you want to make sure that when running your app in Test Cloud that the request for permissions are delayed, or you can even deactivate them if they aren't explicitly needed for a particular test. More information is available in this Calabash guide: https://github.com/calabash/calabash-ios/wiki/Managing-Privacy-Alerts%3A--Location-Services%2C-APNS%2C-Contacts
(Even though it's Calabash, you can use the same strategy in UITest; albeit with a C# syntax.)
Update for Xcode 8 / iOS 10
Xcode 8 / iOS 10 removed UIAutomation, so the InvokeUIA workaround will only continue to be possible if you're using Xcode 7 and iOS 7-9. References:
UITest: https://developer.xamarin.com/guides/testcloud/UITest/xcode7/
Calabash: https://developer.xamarin.com/guides/testcloud/calabash/xcode7/#Automation_API
For real devices you dont need any of those.
{
app = ConfigureApp
.iOSAppBundle
.StartApp();
}
this piece of code is good enough, if you are connecting real device to the system, then select that before running.
We use this to execute the UI tests on iPhones:
ConfigureApp.iOS.InstalledApp("com.appcenter.UITestDemo").StartApp();
InstalledApp requires you to build an IPA using the Debug
configuration & a valid provisioning profile, and preinstalling it on
the target device.
https://github.com/microsoft/appcenter-Xamarin.UITest-Demo/blob/main/UITestDemo.UITest/AppInitializer.cs
To confirm system dialogs we use this:
private Query ConfirmLocalNetworkPermissionDialogButton
=> AppInitializer.Platform == Platform.iOS
? new Query(x => x.ClassFull("_UIAlertControllerActionView").Marked("OK"))
: x => x.Class("AppCompatButton").Marked("button1");

How to set desired capabilities for launching ios app on real device with appium ( c#)

Hi I am automating the native ios application on ios . I already automated android native app but for launching the appium server on mac from c# code running on windows I need to know how to setup the Desired capabilities for ios platform.
Please find the below peace of code for c# language:
DesiredCapabilities capabilities = new DesiredCapabilities();
TestCapabilities testCapabilities = new TestCapabilities();
testCapabilities.App = "";
testCapabilities.AutoWebView = true;
testCapabilities.AutomationName = "";
testCapabilities.BrowserName = String.Empty; // Leave empty otherwise you test on browsers
testCapabilities.DeviceName = "Needed if testing on IOS on a specific device. This will be the UDID";
testCapabilities.Platform = TestCapabilities.DevicePlatform.IOS; // Or Android
testCapabilities.PlatformVersion = String.Empty; // Not really needed
testCapabilities.AssignAppiumCapabilities(ref capabilities);
driver = new AppiumDriver(testServerAddress, capabilities, INIT_TIMEOUT_SEC);
driver.Manage().Timeouts().ImplicitlyWait(IMPLICIT_TIMEOUT_SEC);
To run Appium test on iOS simulator/real device, Mac hardware is needed and to run test on real device, team id from apple developer account is also needed. More details here.
Connect the iPhone to MacOS via cable or connect both iPhone and Mac computer to same wireless network (WiFi).
C# code for initialising appium iOS driver to run test on real device:
//Initialise driver options
AppiumOptions capabilities = new AppiumOptions();
//Declare capabilities
capabilities.AddAdditionalCapability(MobileCapabilityType.PlatformName, "iOS");
capabilities.AddAdditionalCapability(MobileCapabilityType.PlatformVersion, "13.2"); //put real device iOS version
capabilities.AddAdditionalCapability(MobileCapabilityType.DeviceName, "iPhone X"; //put real device name
capabilities.AddAdditionalCapability(MobileCapabilityType.AutomationName, "XCUITest");
if (appInstalled)
{
//if app is installed and don't want to re-install, use below capability
capabilities.AddAdditionalCapability(IOSMobileCapabilityType.BundleId, "<app-bundle-id>");
}
else
{
//(re)installs app
capabilities.AddAdditionalCapability(IOSMobileCapabilityType.AppName, "<name-of-test-app>");
capabilities.AddAdditionalCapability(MobileCapabilityType.App, "<absolute-path-to-test-app.app>");
}
capabilities.AddAdditionalCapability(MobileCapabilityType.Udid, "<real-device-Udid>");
capabilities.AddAdditionalCapability("xcodeOrgId", "<team-id>");
capabilities.AddAdditionalCapability("xcodeSigningId","iPhone Developer");
//Initialise iOS driver
var driver = new IOSDriver<IMobileElement<AppiumWebElement>>(capabilities);

Flex: How to Tell if the Current App is Running on a Simulator or a Real Device or Browser

I have a Flex library, that is used in my Flex mobile or web app. If I run the app on iPad Simulator, Capabilities.os gives me Mac OS 10.7.5, so how can I tell (from the Flex library) if the current app is running on a simulator or real device or browser?
The one I'm using is:
public static function isSimulator():Boolean
{
return Capabilities.version.indexOf("IOS") >= 0 && Capabilities.os.indexOf("Mac OS") >= 0;
}
But I am not so confident with this.
See Capabilities#isDebugger. I don't believe you can tell which device is being simulated, but it will tell you if you are in the Debugger or not.

Resources