1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Android: Fixes #3010: Request permissions if needed when exporting profile (#3202)

This commit is contained in:
Roman Musin 2020-06-08 09:01:11 +01:00 committed by GitHub
parent d2b81d221b
commit 2c6a298758
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 32 deletions

View File

@ -1,9 +1,19 @@
const { PermissionsAndroid } = require('react-native'); const { Platform, PermissionsAndroid } = require('react-native');
type rationale = {
title: string,
message: string,
buttonPositive: string,
buttonNegative?: string
buttonNeutral?: string
}
export default async (permissions: string, rationale?: rationale) => {
if (Platform.OS !== 'android') return true;
export default async (permissions: string) => {
let result = await PermissionsAndroid.check(permissions); let result = await PermissionsAndroid.check(permissions);
if (result !== PermissionsAndroid.RESULTS.GRANTED) { if (result !== PermissionsAndroid.RESULTS.GRANTED) {
result = await PermissionsAndroid.request(permissions); result = await PermissionsAndroid.request(permissions, rationale);
} }
return result === PermissionsAndroid.RESULTS.GRANTED; return result === PermissionsAndroid.RESULTS.GRANTED;
}; };

View File

@ -1,8 +1,6 @@
import { PermissionsAndroid } from 'react-native';
import Slider from '@react-native-community/slider'; import Slider from '@react-native-community/slider';
const React = require('react'); const React = require('react');
const { Platform, TouchableOpacity, Linking, View, Switch, StyleSheet, Text, Button, ScrollView, TextInput, Alert } = require('react-native'); const { Platform, TouchableOpacity, Linking, View, Switch, StyleSheet, Text, Button, ScrollView, TextInput, Alert, PermissionsAndroid } = require('react-native');
const { connect } = require('react-redux'); const { connect } = require('react-redux');
const { ScreenHeader } = require('lib/components/screen-header.js'); const { ScreenHeader } = require('lib/components/screen-header.js');
const { _ } = require('lib/locale.js'); const { _ } = require('lib/locale.js');
@ -20,6 +18,7 @@ const { time } = require('lib/time-utils');
const { shim } = require('lib/shim'); const { shim } = require('lib/shim');
const SearchEngine = require('lib/services/SearchEngine'); const SearchEngine = require('lib/services/SearchEngine');
const RNFS = require('react-native-fs'); const RNFS = require('react-native-fs');
const checkPermissions = require('lib/checkPermissions.js').default;
class ConfigScreenComponent extends BaseScreenComponent { class ConfigScreenComponent extends BaseScreenComponent {
static navigationOptions() { static navigationOptions() {
@ -101,28 +100,30 @@ class ConfigScreenComponent extends BaseScreenComponent {
const exportPath = this.state.profileExportPath; const exportPath = this.state.profileExportPath;
const resourcePath = `${exportPath}/resources`; const resourcePath = `${exportPath}/resources`;
try { try {
const hasPermissions = await checkPermissions(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);
{ if (!hasPermissions) {
const copyFiles = async (source, dest) => { throw new Error('Permission denied');
await shim.fsDriver().mkdir(dest);
const files = await shim.fsDriver().readDirStats(source);
for (const file of files) {
const source_ = `${source}/${file.path}`;
const dest_ = `${dest}/${file.path}`;
if (!file.isDirectory()) {
reg.logger().info(`Copying profile: ${source_} => ${dest_}`);
await shim.fsDriver().copy(source_, dest_);
} else {
await copyFiles(source_, dest_);
}
}
};
await copyFiles(dbPath, exportPath);
await copyFiles(Setting.value('resourceDir'), resourcePath);
} }
const copyFiles = async (source, dest) => {
await shim.fsDriver().mkdir(dest);
const files = await shim.fsDriver().readDirStats(source);
for (const file of files) {
const source_ = `${source}/${file.path}`;
const dest_ = `${dest}/${file.path}`;
if (!file.isDirectory()) {
reg.logger().info(`Copying profile: ${source_} => ${dest_}`);
await shim.fsDriver().copy(source_, dest_);
} else {
await copyFiles(source_, dest_);
}
}
};
await copyFiles(dbPath, exportPath);
await copyFiles(Setting.value('resourceDir'), resourcePath);
alert('Profile has been exported!'); alert('Profile has been exported!');
} catch (error) { } catch (error) {
alert(`Could not export files: ${error.message}`); alert(`Could not export files: ${error.message}`);
@ -141,16 +142,11 @@ class ConfigScreenComponent extends BaseScreenComponent {
// Not implemented yet // Not implemented yet
return true; return true;
} }
const hasPermission = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE); return await checkPermissions(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
if (hasPermission) {
return true;
}
const requestResult = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
title: _('Information'), title: _('Information'),
message: _('In order to use file system synchronisation your permission to write to external storage is required.'), message: _('In order to use file system synchronisation your permission to write to external storage is required.'),
buttonPositive: _('OK'), buttonPositive: _('OK'),
}); });
return requestResult === PermissionsAndroid.RESULTS.GRANTED;
} }
UNSAFE_componentWillMount() { UNSAFE_componentWillMount() {