Skip to content

Commit 064fd5a

Browse files
Add permissions request #15
1 parent 6c873ec commit 064fd5a

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

src/health-data.android.ts

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@ import getApplicationContext = ad.getApplicationContext;
1414

1515
const GOOGLE_FIT_PERMISSIONS_REQUEST_CODE = 2;
1616

17-
declare const com: any;
17+
declare const android, com, global: any;
18+
19+
const AppPackageName = useAndroidX() ? global.androidx.core.app : android.support.v4.app;
20+
const ContentPackageName = useAndroidX() ? global.androidx.core.content : android.support.v4.content;
21+
22+
function useAndroidX () {
23+
return global.androidx && global.androidx.appcompat;
24+
}
1825

1926
// android imports
2027
const DataReadRequest = com.google.android.gms.fitness.request.DataReadRequest;
@@ -57,7 +64,13 @@ export class HealthData extends Common implements HealthDataApi {
5764
}
5865

5966
requestAuthorization(types: Array<HealthDataType>): Promise<boolean> {
60-
return new Promise<boolean>((resolve, reject) => {
67+
return Promise.all([
68+
this.requestHardwarePermissions(),
69+
this.requestAuthorizationInternal(types)
70+
]).then(results => Promise.resolve(results[0] && results[1]));
71+
}
72+
73+
requestAuthorizationInternal(types: Array<HealthDataType>): Promise<boolean> { return new Promise<boolean>((resolve, reject) => {
6174
const fitnessOptionsBuilder = FitnessOptions.builder();
6275

6376
types.filter(t => t.accessType === "read" || t.accessType === "readAndWrite")
@@ -90,7 +103,7 @@ export class HealthData extends Common implements HealthDataApi {
90103
return new Promise((resolve, reject) => {
91104
try {
92105
// make sure the user is authorized
93-
this.requestAuthorization([{name: opts.dataType, accessType: "read"}]).then(authorized => {
106+
this.requestAuthorizationInternal([{name: opts.dataType, accessType: "read"}]).then(authorized => {
94107
if (!authorized) {
95108
reject("Not authorized");
96109
return;
@@ -221,6 +234,60 @@ export class HealthData extends Common implements HealthDataApi {
221234
const typeOfData = acceptableDataTypesForCommonity[pluginType];
222235
return aggregatedDataTypes[typeOfData];
223236
}
237+
238+
private requestHardwarePermissions(): Promise<boolean> {
239+
return this.requestPermissionFor(this.permissionsNeeded()
240+
.filter(permission => !this.wasPermissionGranted(permission)));
241+
}
242+
243+
private wasPermissionGranted(permission: any) {
244+
let hasPermission = android.os.Build.VERSION.SDK_INT < 23; // Android M. (6.0)
245+
if (!hasPermission) {
246+
hasPermission = android.content.pm.PackageManager.PERMISSION_GRANTED ===
247+
ContentPackageName.ContextCompat.checkSelfPermission(
248+
utils.ad.getApplicationContext(),
249+
permission);
250+
}
251+
return hasPermission;
252+
}
253+
254+
private wasPermissionsGrantedForAll(): boolean {
255+
return this.permissionsNeeded().every(permission => this.wasPermissionGranted(permission));
256+
}
257+
258+
private requestPermissionFor(permissions: any[]): Promise<boolean> {
259+
return new Promise<boolean>((resolve, reject) => {
260+
if (!this.wasPermissionsGrantedForAll()) {
261+
const activityRequestPermissionsHandler = args => {
262+
application.android.off(application.AndroidApplication.activityRequestPermissionsEvent, activityRequestPermissionsHandler);
263+
resolve(true);
264+
};
265+
266+
application.android.on(application.AndroidApplication.activityRequestPermissionsEvent, activityRequestPermissionsHandler);
267+
268+
AppPackageName.ActivityCompat.requestPermissions(
269+
application.android.foregroundActivity,
270+
permissions,
271+
235 // irrelevant since we simply invoke onPermissionGranted
272+
);
273+
} else {
274+
resolve(true);
275+
}
276+
});
277+
}
278+
279+
private permissionsNeeded(): any[] {
280+
const permissions = [
281+
android.Manifest.permission.ACCESS_FINE_LOCATION,
282+
android.Manifest.permission.ACCESS_NETWORK_STATE,
283+
android.Manifest.permission.GET_ACCOUNTS];
284+
285+
if (android.os.Build.VERSION.SDK_INT > 19) {
286+
permissions.push(android.Manifest.permission.BODY_SENSORS);
287+
}
288+
289+
return permissions;
290+
}
224291
}
225292

226293
const aggregatedDataTypes = {

src/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
"demo.ios": "npm i && npm run tsc && cd ../demo && tns run ios",
2121
"demo.android": "npm i && npm run tsc && cd ../demo && tns run android",
2222
"clean": "rm -rf node_modules && cd ../demo && rm -rf hooks node_modules platforms && cd ../src && npm run plugin.link",
23-
"demo.ng.ios": "npm i && npm run tsc && npm run package && cd ../demo-ng && tns run ios",
24-
"demo.ng.android": "npm i && npm run tsc && npm run package && cd ../demo-ng && tns run android",
23+
"demo.ng.ios": "npm i && npm run tsc && npm run package && cd ../demo-ng && tns plugin remove nativescript-health-data && tns plugin add ../publish/package/*.tgz && tns run ios",
24+
"demo.ng.android": "npm i && npm run tsc && npm run package && cd ../demo-ng && tns plugin remove nativescript-health-data && tns plugin add ../publish/package/*.tgz && tns run android",
2525
"plugin.ng.link": "npm link && cd ../demo-ng && npm link nativescript-health-data && cd ../src",
2626
"package": "cd ../publish && ./pack.sh",
2727
"setup": "npm i && npm run tsc && cd ../demo-ng && npm i"

src/references.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
2-
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />
2+
/// <reference path="./node_modules/tns-platform-declarations/android-20.d.ts" />

0 commit comments

Comments
 (0)