UNPKG

nativescript-health-data

Version:

Health Data plugin for Nativescript, using Google Fit and Apple HealthKit.

247 lines (246 loc) 13.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HealthData = void 0; var health_data_common_1 = require("./health-data.common"); var core_1 = require("@nativescript/core"); var index_android_1 = require("@nativescript/core/application/index.android"); var GOOGLE_FIT_PERMISSIONS_REQUEST_CODE = 2; var AppPackageName = useAndroidX() ? global.androidx.core.app : android.support.v4.app; var ContentPackageName = useAndroidX() ? global.androidx.core.content : android.support.v4.content; function useAndroidX() { return global.androidx && global.androidx.appcompat; } var DataReadRequest = com.google.android.gms.fitness.request.DataReadRequest; var DataType = com.google.android.gms.fitness.data.DataType; var Fitness = com.google.android.gms.fitness.Fitness; var GoogleApiAvailability = com.google.android.gms.common.GoogleApiAvailability; var TimeUnit = java.util.concurrent.TimeUnit; var FitnessOptions = com.google.android.gms.fitness.FitnessOptions; var GoogleSignIn = com.google.android.gms.auth.api.signin.GoogleSignIn; var HealthData = (function (_super) { __extends(HealthData, _super); function HealthData() { return _super !== null && _super.apply(this, arguments) || this; } HealthData.prototype.isAvailable = function (updateGooglePlayServicesIfNeeded) { if (updateGooglePlayServicesIfNeeded === void 0) { updateGooglePlayServicesIfNeeded = true; } return new Promise(function (resolve, reject) { var gApi = GoogleApiAvailability.getInstance(); var apiResult = gApi.isGooglePlayServicesAvailable(core_1.Utils.android.getApplicationContext()); var available = apiResult === com.google.android.gms.common.ConnectionResult.SUCCESS; if (!available && updateGooglePlayServicesIfNeeded && gApi.isUserResolvableError(apiResult)) { gApi.showErrorDialogFragment(core_1.Application.android.foregroundActivity || core_1.Application.android.startActivity, apiResult, 1, new android.content.DialogInterface.OnCancelListener({ onCancel: function (dialogInterface) { return console.log("Google Play Services update dialog was canceled"); } })); } resolve(available); }); }; HealthData.prototype.isAuthorized = function (types) { var _this = this; return new Promise(function (resolve, reject) { var fitnessOptionsBuilder = FitnessOptions.builder(); types.filter(function (t) { return t.accessType === "read" || t.accessType === "readAndWrite"; }) .forEach(function (t) { return fitnessOptionsBuilder.addDataType(_this.getDataType(t.name), FitnessOptions.ACCESS_READ); }); types.filter(function (t) { return t.accessType === "write" || t.accessType === "readAndWrite"; }) .forEach(function (t) { return fitnessOptionsBuilder.addDataType(_this.getDataType(t.name), FitnessOptions.ACCESS_WRITE); }); resolve(GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount((core_1.Application.android.foregroundActivity || core_1.Application.android.startActivity)), fitnessOptionsBuilder.build())); }); }; HealthData.prototype.requestAuthorization = function (types) { return Promise.all([ this.requestHardwarePermissions(), this.requestAuthorizationInternal(types) ]).then(function (results) { return Promise.resolve(results[0] && results[1]); }); }; HealthData.prototype.requestAuthorizationInternal = function (types) { var _this = this; return new Promise(function (resolve, reject) { var fitnessOptionsBuilder = FitnessOptions.builder(); types.filter(function (t) { return t.accessType === "read" || t.accessType === "readAndWrite"; }) .forEach(function (t) { return fitnessOptionsBuilder.addDataType(_this.getDataType(t.name), FitnessOptions.ACCESS_READ); }); types.filter(function (t) { return t.accessType === "write" || t.accessType === "readAndWrite"; }) .forEach(function (t) { return fitnessOptionsBuilder.addDataType(_this.getDataType(t.name), FitnessOptions.ACCESS_WRITE); }); var fitnessOptions = fitnessOptionsBuilder.build(); if (GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount((core_1.Application.android.foregroundActivity || core_1.Application.android.startActivity)), fitnessOptions)) { resolve(true); return; } var activityResultHandler = function (args) { core_1.Application.android.off(index_android_1.AndroidApplication.activityResultEvent, activityResultHandler); resolve(args.requestCode === GOOGLE_FIT_PERMISSIONS_REQUEST_CODE && args.resultCode === android.app.Activity.RESULT_OK); }; core_1.Application.android.on(index_android_1.AndroidApplication.activityResultEvent, activityResultHandler); GoogleSignIn.requestPermissions(core_1.Application.android.foregroundActivity, GOOGLE_FIT_PERMISSIONS_REQUEST_CODE, GoogleSignIn.getLastSignedInAccount((core_1.Application.android.foregroundActivity || core_1.Application.android.startActivity)), fitnessOptions); }); }; HealthData.prototype.query = function (opts) { var _this = this; return new Promise(function (resolve, reject) { try { _this.requestAuthorizationInternal([{ name: opts.dataType, accessType: "read" }]).then(function (authorized) { if (!authorized) { reject("Not authorized"); return; } var readRequest = new DataReadRequest.Builder() .read(_this.getDataType(opts.dataType)) .setTimeRange(opts.startDate.getTime(), opts.endDate.getTime(), TimeUnit.MILLISECONDS) .build(); Fitness.getHistoryClient((core_1.Application.android.foregroundActivity || core_1.Application.android.startActivity), GoogleSignIn.getLastSignedInAccount((core_1.Application.android.foregroundActivity || core_1.Application.android.startActivity))) .readData(readRequest) .addOnSuccessListener(new com.google.android.gms.tasks.OnSuccessListener({ onSuccess: function (dataReadResponse) { resolve(_this.parseData(dataReadResponse.getResult(), opts)); } })) .addOnFailureListener(new com.google.android.gms.tasks.OnFailureListener({ onFailure: function (exception) { reject(exception.getMessage()); } })) .addOnCompleteListener(new com.google.android.gms.tasks.OnCompleteListener({ onComplete: function (task) { } })); }); } catch (e) { reject(e); } }); }; HealthData.prototype.startMonitoring = function (opts) { return new Promise(function (resolve, reject) { reject("Not supported"); }); }; HealthData.prototype.stopMonitoring = function (opts) { return new Promise(function (resolve, reject) { reject("Not supported"); }); }; HealthData.prototype.parseData = function (readResult, opts) { var result = []; if (readResult.getBuckets().size() > 0) { for (var indexBucket = 0; indexBucket < readResult.getBuckets().size(); indexBucket++) { var dataSets = readResult.getBuckets().get(indexBucket).getDataSets(); for (var indexDataSet = 0; indexDataSet < dataSets.size(); indexDataSet++) { result = result.concat(this.dumpDataSet(dataSets.get(indexDataSet), opts)); } } } else if (readResult.getDataSets().size() > 0) { for (var index_1 = 0; index_1 < readResult.getDataSets().size(); index_1++) { result = result.concat(this.dumpDataSet(readResult.getDataSets().get(index_1), opts)); } } if (opts.sortOrder === "desc") { result = result.reverse(); } return result; }; HealthData.prototype.dumpDataSet = function (dataSet, opts) { var parsedData = []; var packageManager = core_1.Utils.android.getApplicationContext().getPackageManager(); var packageToAppNameCache = new Map(); for (var index_2 = 0; index_2 < dataSet.getDataPoints().size(); index_2++) { var pos = dataSet.getDataPoints().get(index_2); for (var indexField = 0; indexField < pos.getDataType().getFields().size(); indexField++) { var field = pos.getDataType().getFields().get(indexField); var value = pos.getValue(field); var packageName = pos.getOriginalDataSource().getAppPackageName(); var source = packageName ? packageName : pos.getOriginalDataSource().getStreamName(); if (packageName) { if (!packageToAppNameCache.has(packageName)) { try { var appName = packageManager.getApplicationLabel(packageManager.getApplicationInfo(packageName, android.content.pm.PackageManager.GET_META_DATA)); packageToAppNameCache.set(packageName, appName); } catch (ignore) { packageToAppNameCache.set(packageName, packageName); } } source = packageToAppNameCache.get(packageName); } parsedData.push({ start: new Date(pos.getStartTime(TimeUnit.MILLISECONDS)), end: new Date(pos.getEndTime(TimeUnit.MILLISECONDS)), value: value.getFormat() === 1 ? value.asInt() : Math.round(value.asFloat() * 1000) / 1000, unit: opts.unit, source: source }); } } return this.aggregate(parsedData, opts.aggregateBy); }; HealthData.prototype.getDataType = function (pluginType) { var typeOfData = acceptableDataTypesForCommonity[pluginType]; return aggregatedDataTypes[typeOfData]; }; HealthData.prototype.requestHardwarePermissions = function () { var _this = this; return this.requestPermissionFor(this.permissionsNeeded() .filter(function (permission) { return !_this.wasPermissionGranted(permission); })); }; HealthData.prototype.wasPermissionGranted = function (permission) { var hasPermission = android.os.Build.VERSION.SDK_INT < 23; if (!hasPermission) { hasPermission = android.content.pm.PackageManager.PERMISSION_GRANTED === ContentPackageName.ContextCompat.checkSelfPermission(core_1.Utils.android.getApplicationContext(), permission); } return hasPermission; }; HealthData.prototype.wasPermissionsGrantedForAll = function () { var _this = this; return this.permissionsNeeded().every(function (permission) { return _this.wasPermissionGranted(permission); }); }; HealthData.prototype.requestPermissionFor = function (permissions) { var _this = this; return new Promise(function (resolve, reject) { if (!_this.wasPermissionsGrantedForAll()) { var activityRequestPermissionsHandler_1 = function (args) { core_1.Application.android.off(index_android_1.AndroidApplication.activityRequestPermissionsEvent, activityRequestPermissionsHandler_1); resolve(true); }; core_1.Application.android.on(index_android_1.AndroidApplication.activityRequestPermissionsEvent, activityRequestPermissionsHandler_1); AppPackageName.ActivityCompat.requestPermissions(core_1.Application.android.foregroundActivity, permissions, 235); } else { resolve(true); } }); }; HealthData.prototype.permissionsNeeded = function () { var permissions = [ android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.GET_ACCOUNTS ]; if (android.os.Build.VERSION.SDK_INT > 19) { permissions.push(android.Manifest.permission.BODY_SENSORS); } return permissions; }; return HealthData; }(health_data_common_1.Common)); exports.HealthData = HealthData; var aggregatedDataTypes = { TYPE_STEP_COUNT_DELTA: DataType.AGGREGATE_STEP_COUNT_DELTA, TYPE_DISTANCE_DELTA: DataType.AGGREGATE_DISTANCE_DELTA, TYPE_CALORIES_EXPENDED: DataType.AGGREGATE_CALORIES_EXPENDED, TYPE_HEIGHT: DataType.TYPE_HEIGHT, TYPE_WEIGHT: DataType.TYPE_WEIGHT, TYPE_HEART_RATE_BPM: DataType.AGGREGATE_HEART_RATE_SUMMARY, TYPE_BODY_FAT_PERCENTAGE: DataType.AGGREGATE_BODY_FAT_PERCENTAGE_SUMMARY, TYPE_NUTRITION: DataType.AGGREGATE_NUTRITION_SUMMARY }; var acceptableDataTypesForCommonity = { steps: 'TYPE_STEP_COUNT_DELTA', distance: 'TYPE_DISTANCE_DELTA', calories: 'TYPE_CALORIES_EXPENDED', height: 'TYPE_HEIGHT', weight: 'TYPE_WEIGHT', heartRate: 'TYPE_HEART_RATE_BPM', fatPercentage: 'TYPE_BODY_FAT_PERCENTAGE' };