Giter VIP home page Giter VIP logo

nativescript-dna-deviceinfo's Introduction

NativeScript DNA Device Info

nativescript-dna-deviceinfo

NativeScript plugin to acquire device info.

The plugin offers cross-platform utility APIs to retrieve or query device-related information. The utility APIs are available for iOS and Android platforms.

Kindly visit the typescript demo or js demo repository for practical implementation guidance and hints.

The Changelogs section is located towards the end of the document.

I welcome an appreciation email with suggestions and feedback. It will encourage me to provide new APIs and support. My email-id is Deepak Arora. Enjoy and I will be looking forward to your valuable feedback.

Installation

From the command prompt, go to your app's root folder and execute:

tns plugin add nativescript-dna-deviceinfo

This command automatically installs the necessary files, as well as stores nativescript-dna-deviceinfo as a dependency in your project's package.json file.

Import / require

Various device-related APIs are accessible from the DeviceInfo class. To import the class, use one of the following forms:

TypeScript:

import { DeviceInfo } from "nativescript-dna-deviceinfo";

JavaScript:

const nativescript_dna_deviceinfo = require("nativescript-dna-deviceinfo");
const DeviceInfo = nativescript_dna_deviceinfo.DeviceInfo;

APIs

Below is the list of APIs with their supported platforms.

Kindly visit typescript demo or js demo repository for practical implementation guidance and hints.

API Return Type iOS Android
totalMemory number + +
freeMemory number + +
totalStorageSpace number + +
freeStorageSpace number + +
deviceId string + +
deviceName string + +
deviceLocale string + +
deviceCountry string + +
timezone string + +
userAgent Promise + +
appName string + +
appVersion string + +
bundleId string + +
bundleNumber string + -
systemManufacturer string + +
batteryLevel number + +
cellularServiceProviders Carrier[] + +
externalStoragePaths string[] - +
storageVolumes StorageVolume[] - +
wifiSSID string + +
displayMetrics DisplayMetrics + +
wifiIpv4Address string + +
cellularIpv4Address string + +
dumpIpAddresses Address[] + +
audioVolumeLevel number + +
setAudioVolumeLevel void + +
screenBrightnessLevel number + +
setScreenBrightnessLevel void + +
isBluetoothHeadsetConnected boolean + +
isMicAvailable boolean + +
isPortrait boolean + +
isTablet boolean + +
is24Hour boolean + +
isEmulator boolean + +
isBatteryCharging boolean + +
isLocationEnabled Promise + +
isBluetoothEnabled Promise + +

Each of the above APIs is described in detail along with their platform requirements where it makes sense.

totalMemory

Returns total memory(RAM) size of a device in bytes.

DeviceInfo.totalMemory();

freeMemory

Returns free memory(RAM) size of a device in bytes.

DeviceInfo.freeMemory();

totalStorageSpace

Returns total storage(internal) space of a device in bytes.

DeviceInfo.totalStorageSpace();

freeStorageSpace

Returns free storage(internal) space of a device in bytes.

DeviceInfo.freeStorageSpace();

deviceId

Returns a device ID.

DeviceInfo.deviceId();

deviceName

Returns a device name.

DeviceInfo.deviceName();
  • Notes for Android users:
    • Permission BLUETOOTH is needed.

deviceLocale

Returns the locale of a device.

DeviceInfo.deviceLocale();

deviceCountry

Returns the device country.

DeviceInfo.deviceCountry();

timezone

Returns the time zone of a device.

DeviceInfo.timezone();

userAgent

Returns Promise which resolves to 'user agent' if fetched successfully, otherwise 'error'.

DeviceInfo.userAgent();

appName

Returns an app name.

DeviceInfo.appName();

appVersion

Returns an app version.

DeviceInfo.appVersion();

bundleId

Returns an app bundle id.

DeviceInfo.bundleId();

bundleNumber

Returns an app bundle number.

DeviceInfo.bundleNumber();

systemManufacturer

Returns a device manufacturer.

DeviceInfo.systemManufacturer();

batteryLevel

Returns the charge level of a device battery.

DeviceInfo.batteryLevel();

cellularServiceProviders

Returns a list of GSM network providers, Carrier, in use by device. In absence of adequate permission, returns empty Carrier list.

let carriers = DeviceInfo.cellularServiceProviders();
console.log(carriers);

Below is the Carrier interface:

interface Carrier {
  carrierName: string;
  displayName: string;
  country: string;
  mobileCountryCode: string;
  isoCountryCode: string;
  countryCode: string;
  mobileNetworkCode: string;
  generation: WCTGeneration; // Wireless Cellular Technology
  networkType: RadioAccessTechnology;
}

Besides other helpful information returned from the API, it can be used to know whether the device has a fast internet connection or not.

  • Notes for Android users:
    • If the targetSdkVersion is 17, a device with dual sim, the API returns an "active" carrier. Permission ACCESS_COARSE_LOCATION is needed.
    • If the targetSdkVersion is >= 22, a device with dual sim, the API returns both the carriers. Permission READ_PHONE_STATE is needed. To know more about the request permissions process, please visit the link Request App Permissions.

externalStoragePaths

Returns a list of paths for all mountable volumes (external storage cards, USB O-T-G). The empty list means that no mountable volumes found.

DeviceInfo.externalStoragePaths();

storageVolumes

Returns a list of StorageVolume. An empty list means that no mountable volumes found.

let storageVolumes = DeviceInfo.storageVolumes();
console.log(storageVolumes);

Below is the StorageVolume interface:

interface StorageVolume {
  path: string;
  totalSize: number;
  availableSize: number;
  lowBytesLimit: number;
  fullBytesLimit: number;
  description: string;
  isRemovableStorage: boolean;
  isAllowMassStorage: boolean;
  isEmulated: boolean;
  isPrimary: boolean;
}

wifiSSID

Returns service set identifier(SSID) of a wireless local area network (WLAN). In absence of right permissions, returns an empty string.

DeviceInfo.wifiSSID();
  • Notes for Android users:

    • Permissions ACCESS_WIFI_STATE and ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION are required.
    • Android version 9 (Pie) requires location service in enabled(ON) state alongside above-said permissions.
    • To know more about the request permissions process, please visit the link Request App Permissions.
  • Notes for iOS users:

    • To use this API on iOS 12 and earlier, enable the Access WiFi Information.
    • The API for iOS 13 and above uses NEHotspotHelper which requires "com.apple.developer.networking.HotspotHelper" entitlement by Apple.
    • To use this API on iOS 13 and above, enable the Access WiFi Information, and
      • must also meet at least one of criteria below
        • Apps with permission to access location
        • Currently enabled VPN app
        • NEHotspotConfiguration (only Wi-Fi networks that the app configured)
    • Kindly visit the link Access WiFi Information to enable it for your app with the id "nativescript.id" in package.json.
    • Also, add this to your App_Resources/iOS/app.entitlements (mind the name!) file:
        <key>com.apple.developer.networking.wifi-info</key>
        <true/>
    • The demo app has this:
       <?xml version="1.0" encoding="UTF-8"?>
       <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/  PropertyList-1.0.dtd">
        <plist version="1.0">
          <dict>
            <key>com.apple.developer.networking.wifi-info</key>
              <true/>
            </dict>
        </plist>

displayMetrics

Returns DisplayMetrics of a device.

DeviceInfo.displayMetrics();

Below is the DisplayMetrics interface:

interface DisplayMetrics {
  scale: number;
  pixelPerInch: number;
  widthInPixels: number;
  heightInPixels: number;
  diagonalInInches: number;
}
  • Notes for Android users:
    • A word of caution: pixelPerInch and diagonalInInches may be inaccurate and not matches to the device specs.

wifiIpv4Address

Returns WiFi IPv4 address.

DeviceInfo.wifiIpv4Address();
  • Notes for Android users:
    • Make sure that the permissions android.permission.INTERNET, android.permission.ACCESS_NETWORK_STATE, and android.permission.ACCESS_WIFI_STATE are in place in AndroidManifest.xml and in code too.

cellularIpv4Address

Returns cellular IPv4 address.

DeviceInfo.cellularIpv4Address();
  • Notes for Android users:
    • Make sure that the permissions android.permission.INTERNET, android.permission.ACCESS_NETWORK_STATE, and android.permission.ACCESS_WIFI_STATE are in place in AndroidManifest.xml and in code too.

dumpIpAddresses

Returns Address[], which is a collection of IPv4 and IPv6 addresses that a device is equipped with.

DeviceInfo.dumpIpAddresses();
  • Notes for Android users:
    • Make sure that the permissions android.permission.INTERNET, android.permission.ACCESS_NETWORK_STATE, and android.permission.ACCESS_WIFI_STATE are in place in AndroidManifest.xml and in code too.

audioVolumeLevel

Returns the audio volume level as a scalar value from 0 to 100.

DeviceInfo.audioVolumeLevel();

setAudioVolumeLevel

Sets the audio volume level. The level should be a scalar value from 0 and 100.

DeviceInfo.setAudioVolumeLevel(50);

screenBrightnessLevel

Returns the screen brightness level as a scalar value from 0 to 10.

DeviceInfo.screenBrightnessLevel();
  • Notes for Android users:
    • Make sure that the permissions android.permission.WRITE_SETTINGS is in place in AndroidManifest.xml and in code too

setScreenBrightnessLevel

Sets the screen brightness level. The level should be a scalar value from 0 and 10.

DeviceInfo.setScreenBrightnessLevel(0.8);
  • Notes for Android users:
    • Make sure that the permissions android.permission.WRITE_SETTINGS is in place in AndroidManifest.xml and in code too

isBluetoothHeadsetConnected

Returns 'true' if a bluetooth headset is connected with the device, otherwise 'false'.

DeviceInfo.isBluetoothHeadsetConnected();
  • Note for Android users:
    • Permission BLUETOOTH is needed.

isMicAvailable

Returns 'true' if a mic, whether built-in or external, is available, otherwise 'false'.

DeviceInfo.isMicAvailable();

isPortrait

Returns 'true' if a device is in portrait mode, otherwise 'false'.

DeviceInfo.isPortrait();

isTablet

Returns 'true' if a device is a tablet, otherwise 'false'.

DeviceInfo.isTablet();

is24Hour

Returns 'true' if a device configured to a 24-hour clock, otherwise 'false'.

DeviceInfo.is24Hour();

isEmulator

Returns 'true' if an app is running on an emulator, otherwise 'false'.

DeviceInfo.isEmulator();

isBatteryCharging

Returns 'true' if a device is plugged in and charging, otherwise 'false'.

DeviceInfo.isBatteryCharging();

isLocationEnabled

Depending on the state of Location Service and the app permission, returned Promise may resolve to 'true' or 'false'. In the absence of appropriate permission, rejected Promise is returned.

DeviceInfo.isLocationEnabled().then(value => console.log(value))
                              .catch(error => console.log(error));
async LocationServiceStatus() {
  const status = await DeviceInfo.isLocationEnabled().catch(error => console.log(error));
  console.log(status);
}
  • Notes for Android users:
    • Permission ACCESS_FINE_LOCATION is required.

isBluetoothEnabled

Depending on the state of Bluetooth and the app permission, returned Promise may resolve to 'true' or 'false'. In the absence of appropriate permission, rejected Promise is returned.

DeviceInfo.isBluetoothEnabled().then(value => console.log(value))
                               .catch(error => console.log(error));
async PrintBluetoothStatus() {
  const status = await DeviceInfo.isBluetoothEnabled().catch(error => console.log(error));
  console.log(status);
}
  • Note for Android users:
    • Permission BLUETOOTH is needed.

APIs in Action

  async printDeviceInfo() { 
    console.log("Free memory: ", getSize(DeviceInfo.freeMemory()));
    console.log("Total memory: ", getSize(DeviceInfo.totalMemory()));
    console.log("Total storage space: ", getSize(DeviceInfo.totalStorageSpace()));
    console.log("Free storage space: ", getSize(DeviceInfo.freeStorageSpace()));
    console.log("Device id: ", DeviceInfo.deviceId());
    console.log("Device name: ", DeviceInfo.deviceName());
    console.log("Device locale: ", DeviceInfo.deviceLocale());
    console.log("Device country: ", DeviceInfo.deviceCountry());
    console.log("Device timezone: ", DeviceInfo.timezone());
    console.log("Device user agent: ", await DeviceInfo.userAgent().catch(error => console.log(error)));
    console.log("App name: ", DeviceInfo.appName());
    console.log("App version: ", DeviceInfo.appVersion());
    console.log("App bundle id: ", DeviceInfo.bundleId());
    console.log("App bundle number: ", DeviceInfo.bundleNumber());
    console.log("System manufacturer: ", DeviceInfo.systemManufacturer());
    console.log("Battery level: ", Math.round(DeviceInfo.batteryLevel()));
    console.log("Storage paths: ", DeviceInfo.externalStoragePaths());
    console.log("Storage volume info: ", DeviceInfo.storageVolumes());
    console.log("WiFi SSID: ", DeviceInfo.wifiSSID());
    console.log("Display metrics: ", DeviceInfo.displayMetrics());
    console.log("Is portrait orientation: ", DeviceInfo.isPortrait());
    console.log("Is tablet: ", DeviceInfo.isTablet());
    console.log("Is 24 hour: ", DeviceInfo.is24Hour());
    console.log("Is emulator: ", DeviceInfo.isEmulator());
    console.log("Is battery charing: ", DeviceInfo.isBatteryCharging());
    console.log("Is Location service enabled: ", await DeviceInfo.isLocationEnabled().catch(error => console.log(error)));
  }

  formatBytes(bytes, decimals) {
    if (bytes === 0) return '0 GB'
    if (isNaN(parseInt(bytes))) return bytes
    if (typeof bytes === 'string') bytes = parseInt(bytes)
    if (bytes === 0) return '0';
    const k = 1000;
    const dm = decimals + 1 || 3;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
  }

  getSize(bytes: number) {
    return formatBytes(bytes, 2);
  }

Changelogs:

  • 3.7.3: Updated Mobile Country Codes (MCC) and Mobile Network Codes (MNC) table. Improved the test for an emulator for the Android OS.
  • 3.7.2: Bumped up various packages versions. Updated Apple mobile device types.
  • 3.7.1: Reduced the package size.
  • 3.7.0: Bumped up various packages versions. Added APIs to set and get screen brightness levels. Updated Apple mobile device types with iPad Pro 11 inches and 12.9 inches.
  • 3.6.1: Switched to the webpack 3.0.0 version due to some security warnings.
  • 3.6.0: Introducing basic audio management APIs for Android and iOS. For Andriod, memory-related APIs are updated to use non-depreciated system APIs.
  • 3.5.0: Fixed runtime errors related to "NativeClass is not defined" observed on NativeScript Version 7 apps. The fix will likely benefit iOS apps.
  • 3.4.0: Added "dumpIpAddresses" API. Changed "wifiIpv4Address" and "cellularIpv4Address" to return an IPv4 address string, and their Android implementation is revised.
  • 3.3.1: Fixed a crash related to the retrieval of wifi SSID on iOS 13.0 version and above.
  • 3.3.0: Added "wifiIpv4Address" and "cellularIpv4Address" APIs for iOS and Android. Fixed issues related to Bluetooth detection for Android.
  • 3.2.1: Updated Apple's mobile device codes types a.k.a. machine ids (e.g. iPhone1,1, Watch1,1, etc.) and their matching product names.
  • 3.2.0: The API "userAgent" is modified to return Promise. iOS implementation uses WKWebView.
  • 3.1.0: Tested on iOS devices, software version 14.2.1. Fixed issues around the API "deviceId" on iOS.
  • 3.0.0: Upgraded to NativeScript 7.0 version. Note: The plugin is not tested on iOS and Android devices.
  • 2.4.3: For iOS, extended the list of devices with Watch-5, iPhone 11(Pro and Max), iPad mini 5th Gen, and Apple Watch Series 5. For Android, support for AndroidX is added. Bumped up version of various packages.
  • 2.4.2: Handled crash in the API cellularServiceProviders for the Android platform.
  • 2.4.1: Updated documentation.
  • 2.4.0: Added an API to get location service state.
  • 2.3.1: Updated Mobile Country Code and Mobile Network Code.
  • 2.3.0: Added APIs to get device orientation and display metrics.
  • 2.2.0: Added an API to get the status of Bluetooth.
  • 2.1.3: Adjusted the license from Apache-2.0 to MIT.
  • 2.1.2: Added the package nativescript-custom-entitlements to dev dependencies to the demo app.
  • 2.1.1: The documentation is updated.
  • 2.1.0: Added an API to get the service set identifier(SSID) of a wireless local area network (WLAN).
  • 2.0.0: Changed APIs name for storageVolumes & cellularServiceProviders.
  • 1.4.0: Added storageVolumeInfo API.
  • 1.3.0: Added externalStoragePaths API. Fixed crashes and compatibility issues with the Android platform.
  • 1.2.1: Removed unwanted dependencies.
  • 1.2.0: Added an API to retrieve Network Providers, Carriers, related information.
  • 1.1.1: Updated document.
  • 1.1.0: New APIs related to battery charging status and its charge level.
  • 1.0.1: Minor document correction.
  • 1.0.0: First release.

License

MIT license (see LICENSE file)

nativescript-dna-deviceinfo's People

Contributors

darko-bw avatar deepakarora76 avatar dependabot[bot] avatar jfnaud avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

nativescript-dna-deviceinfo's Issues

DeviceInfo.deviceName() does not work anymore for Apps Targeting SDK 31+

Android changed the way how bluetooth permissions work.
Bluetooth permissions Target Android 12 or higher

Which means, that following code returns Unknown, because android.permission.BLUETOOTH does not exist anymore and always fails to be granted

static deviceName() {
        let deviceName = "Unknown";
        const ctx = application.android.context;
        const res = ctx.checkCallingOrSelfPermission("android.permission.BLUETOOTH");
        if (res === android.content.pm.PackageManager.PERMISSION_GRANTED) {
            try {
                const adptr = android.bluetooth.BluetoothAdapter.getDefaultAdapter();
                if (adptr) {
                    deviceName = adptr.getName();
                }
            }
            catch (exception) {

            }
        }
        return deviceName;
}

Edit:
You have to request BLUETOOTH_CONNECT for it to work.
Here is the working code for Apps Targeting SDK 31

if (isAndroid && parseInt(Device.sdkVersion) >= 31) {
      let deviceName = "Unknown";
      const ctx = application.android.context;
      const res = ctx.checkCallingOrSelfPermission("android.permission.BLUETOOTH_CONNECT");
      if (res === android.content.pm.PackageManager.PERMISSION_GRANTED) {
          try {
              const adptr = ctx.getSystemService(android.content.Context.BLUETOOTH_SERVICE).getAdapter();
              if (adptr) {
                  deviceName = adptr.getName();
              }
          }
          catch (exception) {
          }
      }

      return deviceName;
}

DeviceInfo.isEmulator() returns false for some virtual devices

DeviceInfo.isEmulator() erroneously returns false for some virtual devices. For example, with Pixel 4 XL API 30 the following values are reported by android.os.Build:

FINGERPRINT: 'google/sdk_gphone_x86_arm/generic_x86_arm:11/RSR1.201013.001/6903271:userdebug/dev-keys'
MODEL: 'sdk_gphone_x86_arm'
MANUFACTURER: 'Google'
BRAND: 'google'
DEVICE: 'generic_x86_arm'
PRODUCT: 'sdk_gphone_x86_arm'

Deprecated API usage

Platform: iOS
Version: latest

ITMS-90809: Deprecated API Usage - New apps that use UIWebView are no longer accepted. Instead, use WKWebView for improved security and reliability. Learn more (https://developer.apple.com/documentation/uikit/uiwebview).

Apple refuses by default every new application with references to UIWebView APIs.

In the deviceinfo.ios.ts there is a reference to UIWebView (in order to grab the current useragent).
The old UIWebView stringByEvaluatingJavaScriptFromString method is no longer available as it is in the new WKWebView.

WKWebView has evaluateJavaScript method which the result is returned in a closure (completion handler): https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript

Error on build latest NS7

I had install the latest migrated at this plugin but unfortunetely, I encounter this error in build runtime

ERROR in ../node_modules/reduce-css-calc/dist/lib/convert.js
Module not found: Error: Can't resolve 'css-unit-converter' in 'C:\Users\Kronos\Desktop\KronosMobile\nativeRevise\kronos\node_modules\reduce-css-calc\dist\lib'
 @ ../node_modules/reduce-css-calc/dist/lib/convert.js 7:24-53
 @ ../node_modules/reduce-css-calc/dist/lib/reducer.js

deviceCountry and deviceLocale dynamic?

Hi @DeepakArora76

Loving this plugin, thank you! I just want to know, does the deviceLocale and device Country change based on a user's location or are they fixed to where that device was distributed by a carrier? If I have a user that is based in country X and registers that way, but travels to country Y, will deviceCountry() pick that up? I need to display content based on where the user is at that point and not only based on their country of registration on the app. Please advise :)

Also, where is the device pulling the country and locale data from, network level?

Add getModel

I found that device.model from tns-core-modules/platform/platform does not always return model.
I added a function getModel(): string for Android.

static getModel() {
    const Build = android.os.Build;
    return Build.MODEL;
}

I could not find how to do it for iOS (but I did not need it since device.model works good in iOS.

iPhone 11 support

Hallo,
asap is possible to have mapped into device info list the iPhone 11 and iPhone 11 Pro?

Thank you very much

androidx error

in deviceinfo.android.js
line 260
android.support.v4.content.ContextCompat

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.