📝
React-Native(expo)でMANAGE EXTERNAL STORAGE権限を要求する方法
概要
Android11移行からストレージ権限が一種類追加されており、
expo-media-libraryのgetAssetAsyncやreact-native-fsのreadDirでxlsxファイルやpdfファイル等を取得する事が出来なくなっている。
※後日ファイル取得方法も記載予定
MANAGE_EXTERNAL_STORAGE権限の取得方法
AndroidManifest.xmlの修正
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
を以下のように修正する。
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
上記修正完了後アプリをビルドし直し起動するとアプリのストレージ権限許可欄に「すべてのファイルの管理を許可」という項目が追加される。
Nativeモジュールの作成
MANAGE_EXTERNAL_STORAGEはReact-Native公式でまだサポートされていないため、
ネイティブモジュールで権限問い合わせと権限をリクエストするモジュールの作成が必須である。
以下のディレクトリに今回作成するモジュールを新規作成する。
- ディレクトリ
- 「project-name/android/app/src/main/java/projectname」
- モジュール
- 「ManagePermissionModule.java」
- 「ManagePermissionPackage.java」
ManagePermissionModule.java
public class ManageStorageModule extends ReactContextBaseJavaModule {
private final ReactApplicationContext reactContext;
private ReactApplicationContext mApplicationContext;
ManageStorageModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
mApplicationContext = getReactApplicationContext();
}
@Override
public String getName() {
return "ManagePermission";
}
/**
* MANAGE_EXTERNAL_STORAGE権限問い合わせ関数
*/
@RequiresApi(api = Build.VERSION_CODES.R)
@ReactMethod
private void getManageStoragePermission(Promise promise) {
try {
// true:許可 false:拒否
promise.resolve(Environment.isExternalStorageManager());
} catch (Exception error) {
promise.reject(error);
}
}
/**
* MANAGE_EXTERNAL_STORAGE権限リクエスト関数
*/
@RequiresApi(api = Build.VERSION_CODES.R)
@ReactMethod
private void requestManageStoragePermission(Promise promise) {
try {
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", this.reactContext.getPackageName(), null);
intent.setData(uri);
this.reactContext.startActivity(intent);
promise.resolve(true);
} catch (Exception error) {
promise.reject(error);
}
}
}
ManagePermissionPackage.java
public class ManagePermissionPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ManageStorageModule(reactContext));
return modules;
}
}
React-Native側での実装
manage-permission.ts
import { NativeModules, Platform } from 'react-native'
if (Platform.OS === 'android') {
var { ManagePermission } = NativeModules
}
// 権限をネイティブ側に問い合わせる
export async function getManagePermission():Promise<boolean> {
return await ManagePermission.getManagePermission()
}
// 権限をネイティブ側に要求
export async function requestManageStoragePermission():Promise<boolean> {
return await ManagePermission.requestManageStoragePermission()
}
上記の関数を実行する事で権限の問い合わせ及び、権限のリクエストを行う事ができる。
Discussion