Hybrid implementation for GPXexport (#9) using the capacitor FileSystem plugin when needed. The export is done in the Documents/Download folder and there is no notification (yet).

This commit is contained in:
Eric van der Vlist 2022-10-02 16:37:06 +02:00
parent cb4a257003
commit ca28d767c0
5 changed files with 304 additions and 67 deletions

309
package-lock.json generated
View File

@ -15,6 +15,7 @@
"@capacitor/app": "4.0.1", "@capacitor/app": "4.0.1",
"@capacitor/cli": "^4.2.0", "@capacitor/cli": "^4.2.0",
"@capacitor/core": "^4.2.0", "@capacitor/core": "^4.2.0",
"@capacitor/filesystem": "^4.1.2",
"@capacitor/haptics": "4.0.1", "@capacitor/haptics": "4.0.1",
"@capacitor/keyboard": "4.0.1", "@capacitor/keyboard": "4.0.1",
"@capacitor/status-bar": "4.0.1", "@capacitor/status-bar": "4.0.1",
@ -25,7 +26,7 @@
"@testing-library/jest-dom": "^5.11.9", "@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.7", "@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3", "@testing-library/user-event": "^12.8.3",
"@trapezedev/configure": "^5.0.3", "@trapezedev/configure": "^5.0.6",
"@types/jest": "^26.0.20", "@types/jest": "^26.0.20",
"@types/node": "^12.19.15", "@types/node": "^12.19.15",
"@types/pouchdb": "^6.4.0", "@types/pouchdb": "^6.4.0",
@ -2089,6 +2090,14 @@
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@capacitor/filesystem": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-4.1.2.tgz",
"integrity": "sha512-akQTgNZBIRE5mN8IPagd4TUk9vx8c2xTllX8yBRzf4BhHHkQPzAnEVikmX+qB/114DvRMh3l2s8mtpXiWOg9NQ==",
"peerDependencies": {
"@capacitor/core": "^4.0.0"
}
},
"node_modules/@capacitor/haptics": { "node_modules/@capacitor/haptics": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-4.0.1.tgz", "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-4.0.1.tgz",
@ -3688,16 +3697,22 @@
} }
}, },
"node_modules/@trapezedev/configure": { "node_modules/@trapezedev/configure": {
"version": "5.0.3", "version": "5.0.6",
"resolved": "https://registry.npmjs.org/@trapezedev/configure/-/configure-5.0.3.tgz", "resolved": "https://registry.npmjs.org/@trapezedev/configure/-/configure-5.0.6.tgz",
"integrity": "sha512-/IECC2b7QRVKMM++15rtm5yKExugh5TYw6BvJJy1jJ63SXzIyUbhXAvk0hMR8sByIS3P5jP4OOWwLXMipQWQMQ==", "integrity": "sha512-1ROgWNR14Qch0UM6J8mNij/n6LwgSAOJ+3RY8YePaBnTCpUTm844aWHf9FGQ/tJmZ0dHN/sqHqSb7IeW3HSQVA==",
"dependencies": { "dependencies": {
"@ionic/cli-framework-output": "^2.2.2", "@ionic/cli-framework-output": "^2.2.2",
"@ionic/utils-fs": "^3.1.5", "@ionic/utils-fs": "^3.1.5",
"@ionic/utils-subprocess": "^2.1.8", "@ionic/utils-subprocess": "^2.1.8",
"@ionic/utils-terminal": "^2.3.1", "@ionic/utils-terminal": "^2.3.1",
"@prettier/plugin-xml": "^1.1.0", "@prettier/plugin-xml": "^1.1.0",
"@trapezedev/project": "5.0.3", "@trapezedev/project": "5.0.6",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.2",
"@types/lodash": "^4.14.175",
"@types/plist": "^3.0.2",
"@types/prompts": "^2.0.14",
"@types/slice-ansi": "^5.0.0",
"commander": "^8.2.0", "commander": "^8.2.0",
"conventional-changelog": "^3.1.4", "conventional-changelog": "^3.1.4",
"env-paths": "^3.0.0", "env-paths": "^3.0.0",
@ -3716,6 +3731,28 @@
"trapeze": "bin/trapeze" "trapeze": "bin/trapeze"
} }
}, },
"node_modules/@trapezedev/configure/node_modules/@types/fs-extra": {
"version": "9.0.13",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@trapezedev/configure/node_modules/@types/jest": {
"version": "27.5.2",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz",
"integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==",
"dependencies": {
"jest-matcher-utils": "^27.0.0",
"pretty-format": "^27.0.0"
}
},
"node_modules/@trapezedev/configure/node_modules/@types/slice-ansi": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-5.0.0.tgz",
"integrity": "sha512-Bt9wdwNObyD9EQMNN2GSeutWmpsZUC1/bip6XKawJ+cAK9Vhf2EwnSgg7G9Zd7KJv0fTvEbgHFjrHnImemyYQg=="
},
"node_modules/@trapezedev/configure/node_modules/commander": { "node_modules/@trapezedev/configure/node_modules/commander": {
"version": "8.3.0", "version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
@ -3761,20 +3798,27 @@
} }
}, },
"node_modules/@trapezedev/gradle-parse": { "node_modules/@trapezedev/gradle-parse": {
"version": "5.0.3", "version": "5.0.6",
"resolved": "https://registry.npmjs.org/@trapezedev/gradle-parse/-/gradle-parse-5.0.3.tgz", "resolved": "https://registry.npmjs.org/@trapezedev/gradle-parse/-/gradle-parse-5.0.6.tgz",
"integrity": "sha512-j7AeYOoP9nBmYrRoXDpgv1ZFXkB5SKA6H+BFD3uDoo5nipIXvVyYoSZvG5TNMg5xRvpQ2cPHMMOE58217LV7bA==" "integrity": "sha512-57iw3RqtDmIIX0Es3OKDTW0Xy9M4+I12jPFaJgECbN9A19yM06Q3JaUJqtpjlAsohYbOiKSz7I7BaaEUOuKbqw=="
}, },
"node_modules/@trapezedev/project": { "node_modules/@trapezedev/project": {
"version": "5.0.3", "version": "5.0.6",
"resolved": "https://registry.npmjs.org/@trapezedev/project/-/project-5.0.3.tgz", "resolved": "https://registry.npmjs.org/@trapezedev/project/-/project-5.0.6.tgz",
"integrity": "sha512-GrnfSz41Wh2J01M44fKHJ9nLLHDCbujPcoTC//PI3lNqry4P3CY8i2O+UhQh3oaRgqfTr0g0bhQQNGWMhSXyaw==", "integrity": "sha512-hgt7msAbU54Appy6hYGJaQoE9uIHGxskUr2RmuXjCa8eZyyTDUn2y57B9weOQ3nJIiXQcj1bpkYEVBCNYd1NLg==",
"dependencies": { "dependencies": {
"@ionic/utils-fs": "^3.1.5", "@ionic/utils-fs": "^3.1.5",
"@ionic/utils-subprocess": "^2.1.8", "@ionic/utils-subprocess": "^2.1.8",
"@prettier/plugin-xml": "^2.2.0", "@prettier/plugin-xml": "^2.2.0",
"@trapezedev/gradle-parse": "5.0.3", "@trapezedev/gradle-parse": "5.0.6",
"@types/cross-spawn": "^6.0.2",
"@types/diff": "^5.0.2", "@types/diff": "^5.0.2",
"@types/fs-extra": "^9.0.13",
"@types/ini": "^1.3.31",
"@types/jest": "^27.0.2",
"@types/lodash": "^4.14.175",
"@types/plist": "^3.0.2",
"@types/slice-ansi": "^5.0.0",
"@xmldom/xmldom": "^0.7.5", "@xmldom/xmldom": "^0.7.5",
"conventional-changelog": "^3.1.4", "conventional-changelog": "^3.1.4",
"cross-spawn": "^7.0.3", "cross-spawn": "^7.0.3",
@ -3807,6 +3851,41 @@
"prettier": ">=2.4.0" "prettier": ">=2.4.0"
} }
}, },
"node_modules/@trapezedev/project/node_modules/@types/fs-extra": {
"version": "9.0.13",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@trapezedev/project/node_modules/@types/jest": {
"version": "27.5.2",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz",
"integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==",
"dependencies": {
"jest-matcher-utils": "^27.0.0",
"pretty-format": "^27.0.0"
}
},
"node_modules/@trapezedev/project/node_modules/@types/slice-ansi": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-5.0.0.tgz",
"integrity": "sha512-Bt9wdwNObyD9EQMNN2GSeutWmpsZUC1/bip6XKawJ+cAK9Vhf2EwnSgg7G9Zd7KJv0fTvEbgHFjrHnImemyYQg=="
},
"node_modules/@trapezedev/project/node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@trapezedev/project/node_modules/env-paths": { "node_modules/@trapezedev/project/node_modules/env-paths": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
@ -3856,11 +3935,11 @@
} }
}, },
"node_modules/@trapezedev/project/node_modules/yargs": { "node_modules/@trapezedev/project/node_modules/yargs": {
"version": "17.5.1", "version": "17.6.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
"integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
"dependencies": { "dependencies": {
"cliui": "^7.0.2", "cliui": "^8.0.1",
"escalade": "^3.1.1", "escalade": "^3.1.1",
"get-caller-file": "^2.0.5", "get-caller-file": "^2.0.5",
"require-directory": "^2.1.1", "require-directory": "^2.1.1",
@ -3989,6 +4068,14 @@
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
"integrity": "sha512-rkiiTuf/z2wTd4RxFOb+clE7PF4AEJU0hsczbUdkHHBtkUmpWQpEddynNfJYKYtZFJKbq4F+brfekt1kx85IZA==" "integrity": "sha512-rkiiTuf/z2wTd4RxFOb+clE7PF4AEJU0hsczbUdkHHBtkUmpWQpEddynNfJYKYtZFJKbq4F+brfekt1kx85IZA=="
}, },
"node_modules/@types/cross-spawn": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz",
"integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/debug": { "node_modules/@types/debug": {
"version": "4.1.7", "version": "4.1.7",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
@ -4089,6 +4176,11 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/ini": {
"version": "1.3.31",
"resolved": "https://registry.npmjs.org/@types/ini/-/ini-1.3.31.tgz",
"integrity": "sha512-8ecxxaG4AlVEM1k9+BsziMw8UsX0qy3jYI1ad/71RrDZ+rdL6aZB0wLfAuflQiDhkD5o4yJ0uPK3OSUic3fG0w=="
},
"node_modules/@types/istanbul-lib-coverage": { "node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@ -4169,8 +4261,7 @@
"node_modules/@types/lodash": { "node_modules/@types/lodash": {
"version": "4.14.184", "version": "4.14.184",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.184.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.184.tgz",
"integrity": "sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q==", "integrity": "sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q=="
"dev": true
}, },
"node_modules/@types/mime": { "node_modules/@types/mime": {
"version": "3.0.1", "version": "3.0.1",
@ -4202,6 +4293,15 @@
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
}, },
"node_modules/@types/plist": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz",
"integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==",
"dependencies": {
"@types/node": "*",
"xmlbuilder": ">=11.0.1"
}
},
"node_modules/@types/pouchdb": { "node_modules/@types/pouchdb": {
"version": "6.4.0", "version": "6.4.0",
"resolved": "https://registry.npmjs.org/@types/pouchdb/-/pouchdb-6.4.0.tgz", "resolved": "https://registry.npmjs.org/@types/pouchdb/-/pouchdb-6.4.0.tgz",
@ -4370,6 +4470,14 @@
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
"integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==" "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A=="
}, },
"node_modules/@types/prompts": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.14.tgz",
"integrity": "sha512-HZBd99fKxRWpYCErtm2/yxUZv6/PBI9J7N4TNFffl5JbrYMHBwF25DjQGTW3b3jmXq+9P6/8fCIb2ee57BFfYA==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/prop-types": { "node_modules/@types/prop-types": {
"version": "15.7.5", "version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
@ -13101,15 +13209,14 @@
"integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg=="
}, },
"node_modules/nodemon": { "node_modules/nodemon": {
"version": "2.0.19", "version": "2.0.20",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.19.tgz", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz",
"integrity": "sha512-4pv1f2bMDj0Eeg/MhGqxrtveeQ5/G/UVe9iO6uTZzjnRluSA4PVWf8CW99LUPwGB3eNIA7zUFoP77YuI7hOc0A==", "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==",
"hasInstallScript": true,
"dependencies": { "dependencies": {
"chokidar": "^3.5.2", "chokidar": "^3.5.2",
"debug": "^3.2.7", "debug": "^3.2.7",
"ignore-by-default": "^1.0.1", "ignore-by-default": "^1.0.1",
"minimatch": "^3.0.4", "minimatch": "^3.1.2",
"pstree.remy": "^1.1.8", "pstree.remy": "^1.1.8",
"semver": "^5.7.1", "semver": "^5.7.1",
"simple-update-notifier": "^1.0.7", "simple-update-notifier": "^1.0.7",
@ -18176,9 +18283,9 @@
} }
}, },
"node_modules/uglify-js": { "node_modules/uglify-js": {
"version": "3.17.0", "version": "3.17.2",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.2.tgz",
"integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==", "integrity": "sha512-bbxglRjsGQMchfvXZNusUcYgiB9Hx2K4AHYXQy2DITZ9Rd+JzhX7+hoocE5Winr7z2oHvPsekkBwXtigvxevXg==",
"optional": true, "optional": true,
"bin": { "bin": {
"uglifyjs": "bin/uglifyjs" "uglifyjs": "bin/uglifyjs"
@ -20978,6 +21085,12 @@
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"@capacitor/filesystem": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-4.1.2.tgz",
"integrity": "sha512-akQTgNZBIRE5mN8IPagd4TUk9vx8c2xTllX8yBRzf4BhHHkQPzAnEVikmX+qB/114DvRMh3l2s8mtpXiWOg9NQ==",
"requires": {}
},
"@capacitor/haptics": { "@capacitor/haptics": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-4.0.1.tgz", "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-4.0.1.tgz",
@ -22047,16 +22160,22 @@
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="
}, },
"@trapezedev/configure": { "@trapezedev/configure": {
"version": "5.0.3", "version": "5.0.6",
"resolved": "https://registry.npmjs.org/@trapezedev/configure/-/configure-5.0.3.tgz", "resolved": "https://registry.npmjs.org/@trapezedev/configure/-/configure-5.0.6.tgz",
"integrity": "sha512-/IECC2b7QRVKMM++15rtm5yKExugh5TYw6BvJJy1jJ63SXzIyUbhXAvk0hMR8sByIS3P5jP4OOWwLXMipQWQMQ==", "integrity": "sha512-1ROgWNR14Qch0UM6J8mNij/n6LwgSAOJ+3RY8YePaBnTCpUTm844aWHf9FGQ/tJmZ0dHN/sqHqSb7IeW3HSQVA==",
"requires": { "requires": {
"@ionic/cli-framework-output": "^2.2.2", "@ionic/cli-framework-output": "^2.2.2",
"@ionic/utils-fs": "^3.1.5", "@ionic/utils-fs": "^3.1.5",
"@ionic/utils-subprocess": "^2.1.8", "@ionic/utils-subprocess": "^2.1.8",
"@ionic/utils-terminal": "^2.3.1", "@ionic/utils-terminal": "^2.3.1",
"@prettier/plugin-xml": "^1.1.0", "@prettier/plugin-xml": "^1.1.0",
"@trapezedev/project": "5.0.3", "@trapezedev/project": "5.0.6",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.2",
"@types/lodash": "^4.14.175",
"@types/plist": "^3.0.2",
"@types/prompts": "^2.0.14",
"@types/slice-ansi": "^5.0.0",
"commander": "^8.2.0", "commander": "^8.2.0",
"conventional-changelog": "^3.1.4", "conventional-changelog": "^3.1.4",
"env-paths": "^3.0.0", "env-paths": "^3.0.0",
@ -22072,6 +22191,28 @@
"yargs": "^17.2.1" "yargs": "^17.2.1"
}, },
"dependencies": { "dependencies": {
"@types/fs-extra": {
"version": "9.0.13",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
"requires": {
"@types/node": "*"
}
},
"@types/jest": {
"version": "27.5.2",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz",
"integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==",
"requires": {
"jest-matcher-utils": "^27.0.0",
"pretty-format": "^27.0.0"
}
},
"@types/slice-ansi": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-5.0.0.tgz",
"integrity": "sha512-Bt9wdwNObyD9EQMNN2GSeutWmpsZUC1/bip6XKawJ+cAK9Vhf2EwnSgg7G9Zd7KJv0fTvEbgHFjrHnImemyYQg=="
},
"commander": { "commander": {
"version": "8.3.0", "version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
@ -22104,20 +22245,27 @@
} }
}, },
"@trapezedev/gradle-parse": { "@trapezedev/gradle-parse": {
"version": "5.0.3", "version": "5.0.6",
"resolved": "https://registry.npmjs.org/@trapezedev/gradle-parse/-/gradle-parse-5.0.3.tgz", "resolved": "https://registry.npmjs.org/@trapezedev/gradle-parse/-/gradle-parse-5.0.6.tgz",
"integrity": "sha512-j7AeYOoP9nBmYrRoXDpgv1ZFXkB5SKA6H+BFD3uDoo5nipIXvVyYoSZvG5TNMg5xRvpQ2cPHMMOE58217LV7bA==" "integrity": "sha512-57iw3RqtDmIIX0Es3OKDTW0Xy9M4+I12jPFaJgECbN9A19yM06Q3JaUJqtpjlAsohYbOiKSz7I7BaaEUOuKbqw=="
}, },
"@trapezedev/project": { "@trapezedev/project": {
"version": "5.0.3", "version": "5.0.6",
"resolved": "https://registry.npmjs.org/@trapezedev/project/-/project-5.0.3.tgz", "resolved": "https://registry.npmjs.org/@trapezedev/project/-/project-5.0.6.tgz",
"integrity": "sha512-GrnfSz41Wh2J01M44fKHJ9nLLHDCbujPcoTC//PI3lNqry4P3CY8i2O+UhQh3oaRgqfTr0g0bhQQNGWMhSXyaw==", "integrity": "sha512-hgt7msAbU54Appy6hYGJaQoE9uIHGxskUr2RmuXjCa8eZyyTDUn2y57B9weOQ3nJIiXQcj1bpkYEVBCNYd1NLg==",
"requires": { "requires": {
"@ionic/utils-fs": "^3.1.5", "@ionic/utils-fs": "^3.1.5",
"@ionic/utils-subprocess": "^2.1.8", "@ionic/utils-subprocess": "^2.1.8",
"@prettier/plugin-xml": "^2.2.0", "@prettier/plugin-xml": "^2.2.0",
"@trapezedev/gradle-parse": "5.0.3", "@trapezedev/gradle-parse": "5.0.6",
"@types/cross-spawn": "^6.0.2",
"@types/diff": "^5.0.2", "@types/diff": "^5.0.2",
"@types/fs-extra": "^9.0.13",
"@types/ini": "^1.3.31",
"@types/jest": "^27.0.2",
"@types/lodash": "^4.14.175",
"@types/plist": "^3.0.2",
"@types/slice-ansi": "^5.0.0",
"@xmldom/xmldom": "^0.7.5", "@xmldom/xmldom": "^0.7.5",
"conventional-changelog": "^3.1.4", "conventional-changelog": "^3.1.4",
"cross-spawn": "^7.0.3", "cross-spawn": "^7.0.3",
@ -22150,6 +22298,38 @@
"prettier": ">=2.4.0" "prettier": ">=2.4.0"
} }
}, },
"@types/fs-extra": {
"version": "9.0.13",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
"requires": {
"@types/node": "*"
}
},
"@types/jest": {
"version": "27.5.2",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz",
"integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==",
"requires": {
"jest-matcher-utils": "^27.0.0",
"pretty-format": "^27.0.0"
}
},
"@types/slice-ansi": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-5.0.0.tgz",
"integrity": "sha512-Bt9wdwNObyD9EQMNN2GSeutWmpsZUC1/bip6XKawJ+cAK9Vhf2EwnSgg7G9Zd7KJv0fTvEbgHFjrHnImemyYQg=="
},
"cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
}
},
"env-paths": { "env-paths": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
@ -22178,11 +22358,11 @@
"integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==" "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg=="
}, },
"yargs": { "yargs": {
"version": "17.5.1", "version": "17.6.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
"integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
"requires": { "requires": {
"cliui": "^7.0.2", "cliui": "^8.0.1",
"escalade": "^3.1.1", "escalade": "^3.1.1",
"get-caller-file": "^2.0.5", "get-caller-file": "^2.0.5",
"require-directory": "^2.1.1", "require-directory": "^2.1.1",
@ -22304,6 +22484,14 @@
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz", "resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
"integrity": "sha512-rkiiTuf/z2wTd4RxFOb+clE7PF4AEJU0hsczbUdkHHBtkUmpWQpEddynNfJYKYtZFJKbq4F+brfekt1kx85IZA==" "integrity": "sha512-rkiiTuf/z2wTd4RxFOb+clE7PF4AEJU0hsczbUdkHHBtkUmpWQpEddynNfJYKYtZFJKbq4F+brfekt1kx85IZA=="
}, },
"@types/cross-spawn": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz",
"integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==",
"requires": {
"@types/node": "*"
}
},
"@types/debug": { "@types/debug": {
"version": "4.1.7", "version": "4.1.7",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
@ -22404,6 +22592,11 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/ini": {
"version": "1.3.31",
"resolved": "https://registry.npmjs.org/@types/ini/-/ini-1.3.31.tgz",
"integrity": "sha512-8ecxxaG4AlVEM1k9+BsziMw8UsX0qy3jYI1ad/71RrDZ+rdL6aZB0wLfAuflQiDhkD5o4yJ0uPK3OSUic3fG0w=="
},
"@types/istanbul-lib-coverage": { "@types/istanbul-lib-coverage": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@ -22480,8 +22673,7 @@
"@types/lodash": { "@types/lodash": {
"version": "4.14.184", "version": "4.14.184",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.184.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.184.tgz",
"integrity": "sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q==", "integrity": "sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q=="
"dev": true
}, },
"@types/mime": { "@types/mime": {
"version": "3.0.1", "version": "3.0.1",
@ -22513,6 +22705,15 @@
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
}, },
"@types/plist": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz",
"integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==",
"requires": {
"@types/node": "*",
"xmlbuilder": ">=11.0.1"
}
},
"@types/pouchdb": { "@types/pouchdb": {
"version": "6.4.0", "version": "6.4.0",
"resolved": "https://registry.npmjs.org/@types/pouchdb/-/pouchdb-6.4.0.tgz", "resolved": "https://registry.npmjs.org/@types/pouchdb/-/pouchdb-6.4.0.tgz",
@ -22681,6 +22882,14 @@
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
"integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==" "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A=="
}, },
"@types/prompts": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.14.tgz",
"integrity": "sha512-HZBd99fKxRWpYCErtm2/yxUZv6/PBI9J7N4TNFffl5JbrYMHBwF25DjQGTW3b3jmXq+9P6/8fCIb2ee57BFfYA==",
"requires": {
"@types/node": "*"
}
},
"@types/prop-types": { "@types/prop-types": {
"version": "15.7.5", "version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
@ -29166,14 +29375,14 @@
"integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg=="
}, },
"nodemon": { "nodemon": {
"version": "2.0.19", "version": "2.0.20",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.19.tgz", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz",
"integrity": "sha512-4pv1f2bMDj0Eeg/MhGqxrtveeQ5/G/UVe9iO6uTZzjnRluSA4PVWf8CW99LUPwGB3eNIA7zUFoP77YuI7hOc0A==", "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==",
"requires": { "requires": {
"chokidar": "^3.5.2", "chokidar": "^3.5.2",
"debug": "^3.2.7", "debug": "^3.2.7",
"ignore-by-default": "^1.0.1", "ignore-by-default": "^1.0.1",
"minimatch": "^3.0.4", "minimatch": "^3.1.2",
"pstree.remy": "^1.1.8", "pstree.remy": "^1.1.8",
"semver": "^5.7.1", "semver": "^5.7.1",
"simple-update-notifier": "^1.0.7", "simple-update-notifier": "^1.0.7",
@ -32768,9 +32977,9 @@
"integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==" "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig=="
}, },
"uglify-js": { "uglify-js": {
"version": "3.17.0", "version": "3.17.2",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.2.tgz",
"integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==", "integrity": "sha512-bbxglRjsGQMchfvXZNusUcYgiB9Hx2K4AHYXQy2DITZ9Rd+JzhX7+hoocE5Winr7z2oHvPsekkBwXtigvxevXg==",
"optional": true "optional": true
}, },
"unbox-primitive": { "unbox-primitive": {

View File

@ -10,6 +10,7 @@
"@capacitor/app": "4.0.1", "@capacitor/app": "4.0.1",
"@capacitor/cli": "^4.2.0", "@capacitor/cli": "^4.2.0",
"@capacitor/core": "^4.2.0", "@capacitor/core": "^4.2.0",
"@capacitor/filesystem": "^4.1.2",
"@capacitor/haptics": "4.0.1", "@capacitor/haptics": "4.0.1",
"@capacitor/keyboard": "4.0.1", "@capacitor/keyboard": "4.0.1",
"@capacitor/status-bar": "4.0.1", "@capacitor/status-bar": "4.0.1",
@ -20,7 +21,7 @@
"@testing-library/jest-dom": "^5.11.9", "@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.7", "@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3", "@testing-library/user-event": "^12.8.3",
"@trapezedev/configure": "^5.0.3", "@trapezedev/configure": "^5.0.6",
"@types/jest": "^26.0.20", "@types/jest": "^26.0.20",
"@types/node": "^12.19.15", "@types/node": "^12.19.15",
"@types/pouchdb": "^6.4.0", "@types/pouchdb": "^6.4.0",

View File

@ -1,15 +1,19 @@
import { IonButton, IonIcon } from '@ionic/react'; import { IonButton, IonIcon, isPlatform } from '@ionic/react';
import { cloudDownload } from 'ionicons/icons'; import { cloudDownload } from 'ionicons/icons';
import React, { Fragment, useRef } from 'react'; import React, { Fragment, useRef } from 'react';
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
import { useDB } from 'react-pouchdb'; import { useDB } from 'react-pouchdb';
import { getGpxAsXmlString } from '../../db/gpx'; import { getGpxAsXmlString } from '../../db/gpx';
const GpxExport: React.FC<{ gpx: any }> = (props: { gpx: any }) => { const GpxExport: React.FC<{ gpx: any }> = (props: { gpx: any }) => {
const db = useDB(); const db = useDB();
const isCapacitor = isPlatform('capacitor');
console.log(`isPlatform('capacitor'): ${isPlatform('capacitor')}`);
const hiddenLinkElement = useRef<HTMLAnchorElement>(null); const hiddenLinkElement = useRef<HTMLAnchorElement>(null);
var downloadName; var downloadName: string;
if (props.gpx.metadata.name !== undefined) { if (props.gpx.metadata.name !== undefined) {
downloadName = props.gpx.metadata.name; downloadName = props.gpx.metadata.name;
@ -24,16 +28,35 @@ const GpxExport: React.FC<{ gpx: any }> = (props: { gpx: any }) => {
console.log('download()'); console.log('download()');
const gpxAsXml = await getGpxAsXmlString(db, props.gpx._id); const gpxAsXml = await getGpxAsXmlString(db, props.gpx._id);
console.log(`gpxAsXml: ${gpxAsXml}`); console.log(`gpxAsXml: ${gpxAsXml}`);
const blob = new Blob([gpxAsXml], { if (isCapacitor) {
type: 'application/gpx+xml', await Filesystem.writeFile({
}); path: `Download/${downloadName}`,
const fileDownloadUrl = URL.createObjectURL(blob); data: gpxAsXml,
console.log(`fileDownloadUrl: ${fileDownloadUrl}`); directory: Directory.Documents,
console.log(`hiddenLinkElement.current: ${hiddenLinkElement.current}`); encoding: Encoding.UTF8,
hiddenLinkElement.current!.href = fileDownloadUrl; recursive: true,
hiddenLinkElement.current?.click(); });
URL.revokeObjectURL(fileDownloadUrl); } else {
hiddenLinkElement.current!.href = ''; const blob = new Blob([gpxAsXml], {
type: 'application/gpx+xml',
});
const fileDownloadUrl = URL.createObjectURL(blob);
console.log(`fileDownloadUrl: ${fileDownloadUrl}`);
console.log(
`hiddenLinkElement.current, href: ${
hiddenLinkElement.current!.href
}, click: ${hiddenLinkElement.current!.click}`
);
hiddenLinkElement.current!.href = fileDownloadUrl;
hiddenLinkElement.current?.click();
console.log(
`hiddenLinkElement.current, href: ${
hiddenLinkElement.current!.href
}, click: ${hiddenLinkElement.current!.click}`
);
URL.revokeObjectURL(fileDownloadUrl);
hiddenLinkElement.current!.href = '';
}
}; };
return ( return (
@ -41,9 +64,11 @@ const GpxExport: React.FC<{ gpx: any }> = (props: { gpx: any }) => {
<IonButton id='gpx-export-button' onClick={download}> <IonButton id='gpx-export-button' onClick={download}>
<IonIcon icon={cloudDownload} title='Export' slot='icon-only' /> <IonIcon icon={cloudDownload} title='Export' slot='icon-only' />
</IonButton> </IonButton>
<a className='hidden' download={downloadName} ref={hiddenLinkElement}> {isCapacitor && (
download <a className='hidden' download={downloadName} ref={hiddenLinkElement}>
</a> download
</a>
)}
</Fragment> </Fragment>
); );
}; };

View File

@ -172,12 +172,13 @@ export const deleteCurrent = async (db: any) => {
}; };
export const getGpx = async (db: any, gpxId: string) => { export const getGpx = async (db: any, gpxId: string) => {
console.log(`getGpx(db, "${gpxId}")`);
var gpxResult = await db.get(gpxId); var gpxResult = await db.get(gpxId);
var gpx = gpxResult.gpx; var gpx = gpxResult.gpx;
var trkptResults = await db.find({ var trkptResults = await db.find({
selector: { selector: {
type: 'trkpt', type: 'trkpt',
gpx: gpx._id, gpx: gpxId,
}, },
}); });
var trkpts = trkptResults.docs; var trkpts = trkptResults.docs;

View File

@ -13,3 +13,4 @@ platforms:
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />