# native_android_path **Repository Path**: suzd2025/native_android_path ## Basic Information - **Project Name**: native_android_path - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-03-13 - **Last Updated**: 2025-03-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # NativeAndroidPath A Flutter plugin that provides access to various storage paths on Android devices. ## Installation Add this to your package's `pubspec.yaml` file: ```yaml dependencies: native_android_path: ^latest_version ``` ```yaml dependencies: native_android_path: ^0.0.1 ``` Then run: ```bash flutter pub get add native_android_path ``` ## Usage Import the package: ```dart import 'package:native_android_path/native_android_path.dart'; ``` Create an instance of the `NativeAndroidPath` class: ```dart final nativeAndroidPath = NativeAndroidPath(); ``` ![android_path](https://github.com/user-attachments/assets/3de1ec77-1b88-4ef5-baf4-90e5fccabb4f) ## Methods ### `getPlatformVersion()` Returns the version of the Android platform. **Example:** ```dart Future getAndroidVersion() async { try { String? version = await NativeAndroidPath().getPlatformVersion(); print('Android version: $version'); } catch (e) { print('Error getting Android version: $e'); } } ``` ### `getAllPaths()` Returns all available storage paths on the device as a map. **Example:** ```dart Future showAllPaths() async { try { Map paths = await NativeAndroidPath().getAllPaths(); paths.forEach((key, value) { print('$key: $value'); }); } catch (e) { print('Error getting all paths: $e'); } } ``` ### `getInternalStoragePath()` Returns the path to the internal storage directory. **Example:** ```dart Future showInternalStorage() async { try { String? path = await NativeAndroidPath().getInternalStoragePath(); print('Internal storage path: $path'); } catch (e) { print('Error getting internal storage path: $e'); } } ``` ### `getExternalStoragePath()` Returns the path to the external storage directory. **Example:** ```dart Future showExternalStorage() async { try { String? path = await NativeAndroidPath().getExternalStoragePath(); print('External storage path: $path'); } catch (e) { print('Error getting external storage path: $e'); } } ``` ### `getInternalCachePath()` Returns the path to the internal cache directory. **Example:** ```dart Future showInternalCache() async { try { String? path = await NativeAndroidPath().getInternalCachePath(); print('Internal cache path: $path'); } catch (e) { print('Error getting internal cache path: $e'); } } ``` ### `getExternalCachePath()` Returns the path to the external cache directory. **Example:** ```dart Future showExternalCache() async { try { String? path = await NativeAndroidPath().getExternalCachePath(); print('External cache path: $path'); } catch (e) { print('Error getting external cache path: $e'); } } ``` ### `getDownloadPath()` Returns the path to the downloads directory. **Example:** ```dart Future showDownloadsFolder() async { try { String? path = await NativeAndroidPath().getDownloadPath(); print('Downloads path: $path'); } catch (e) { print('Error getting downloads path: $e'); } } ``` ### `getDCIMPath()` Returns the path to the DCIM directory (camera photos). **Example:** ```dart Future showDCIMFolder() async { try { String? path = await NativeAndroidPath().getDCIMPath(); print('DCIM path: $path'); } catch (e) { print('Error getting DCIM path: $e'); } } ``` ### `getPicturesPath()` Returns the path to the pictures directory. **Example:** ```dart Future showPicturesFolder() async { try { String? path = await NativeAndroidPath().getPicturesPath(); print('Pictures path: $path'); } catch (e) { print('Error getting pictures path: $e'); } } ``` ### `getMoviesPath()` Returns the path to the movies directory. **Example:** ```dart Future showMoviesFolder() async { try { String? path = await NativeAndroidPath().getMoviesPath(); print('Movies path: $path'); } catch (e) { print('Error getting movies path: $e'); } } ``` ### `getMusicPath()` Returns the path to the music directory. **Example:** ```dart Future showMusicFolder() async { try { String? path = await NativeAndroidPath().getMusicPath(); print('Music path: $path'); } catch (e) { print('Error getting music path: $e'); } } ``` ### `getRingtonesPath()` Returns the path to the ringtones directory. **Example:** ```dart Future showRingtonesFolder() async { try { String? path = await NativeAndroidPath().getRingtonesPath(); print('Ringtones path: $path'); } catch (e) { print('Error getting ringtones path: $e'); } } ``` ### `getAlarmsPath()` Returns the path to the alarms directory. **Example:** ```dart Future showAlarmsFolder() async { try { String? path = await NativeAndroidPath().getAlarmsPath(); print('Alarms path: $path'); } catch (e) { print('Error getting alarms path: $e'); } } ``` ### `getNotificationsPath()` Returns the path to the notifications directory. **Example:** ```dart Future showNotificationsFolder() async { try { String? path = await NativeAndroidPath().getNotificationsPath(); print('Notifications path: $path'); } catch (e) { print('Error getting notifications path: $e'); } } ``` ### `getDocumentsPath()` Returns the path to the documents directory. **Example:** ```dart Future showDocumentsFolder() async { try { String? path = await NativeAndroidPath().getDocumentsPath(); print('Documents path: $path'); } catch (e) { print('Error getting documents path: $e'); } } ``` ### `isExternalStorageWritable()` Checks if external storage is writable. **Example:** ```dart Future checkExternalStorageWritable() async { try { bool isWritable = await NativeAndroidPath().isExternalStorageWritable(); print('External storage is writable: $isWritable'); } catch (e) { print('Error checking if external storage is writable: $e'); } } ``` ### `isExternalStorageReadable()` Checks if external storage is readable. **Example:** ```dart Future checkExternalStorageReadable() async { try { bool isReadable = await NativeAndroidPath().isExternalStorageReadable(); print('External storage is readable: $isReadable'); } catch (e) { print('Error checking if external storage is readable: $e'); } } ``` ### `getExternalStorageDirectories(String type)` Returns a list of external storage directory paths for the specified type. **Example:** ```dart Future getSpecificExternalDirectories() async { try { // Possible types: "music", "pictures", "movies", "documents", etc. List paths = await NativeAndroidPath().getExternalStorageDirectories("pictures"); print('External picture directories:'); for (String path in paths) { print('- $path'); } } catch (e) { print('Error getting external directories: $e'); } } ``` ## Full Example Here's a complete example showing how to use multiple methods: ```dart import 'package:flutter/material.dart'; import 'package:native_android_path/native_android_path.dart'; void main() { runApp(MyApp()); } class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { final NativeAndroidPath _pathPlugin = NativeAndroidPath(); Map _paths = {}; bool _isLoading = true; @override void initState() { super.initState(); _loadPaths(); } Future _loadPaths() async { try { Map allPaths = await _pathPlugin.getAllPaths(); bool isWritable = await _pathPlugin.isExternalStorageWritable(); bool isReadable = await _pathPlugin.isExternalStorageReadable(); setState(() { _paths = { ...allPaths.map((key, value) => MapEntry(key, value ?? 'Not available')), 'External storage writable': isWritable.toString(), 'External storage readable': isReadable.toString(), }; _isLoading = false; }); } catch (e) { setState(() { _paths = {'Error': e.toString()}; _isLoading = false; }); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Android Storage Paths'), ), body: _isLoading ? Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: _paths.length, itemBuilder: (context, index) { String key = _paths.keys.elementAt(index); String value = _paths[key]!; return ListTile( title: Text(key), subtitle: Text(value), ); }, ), ), ); } } ``` ## Permissions For Android 10 (API level 29) and above, you might need to add: ```xml ``` For Android 11 (API level 30) and above, consider implementing more specific storage access using the Storage Access Framework or Media Store API. ### **Required Permissions for Android 13** 1. **General Permissions**: - To access external files, you still need the `READ_EXTERNAL_STORAGE` and `WRITE_EXTERNAL_STORAGE` permissions. ```xml ``` 2. **Specific Permissions for Android 13**: - In Android 13, access to media files (such as photos, videos, and music) is controlled separately. To access these files, you must use **specific permissions**: - `READ_MEDIA_IMAGES`: For accessing photos. - `READ_MEDIA_VIDEO`: For accessing videos. - `READ_MEDIA_AUDIO`: For accessing audio files. ```xml ``` 3. **Requesting Permissions at Runtime**: - In Android 13, you must request specific permissions at runtime from the user. This is done using `ActivityResultContracts.RequestPermission` or `ActivityResultContracts.RequestMultiplePermissions`. Example of requesting permission to access photos: ```dart import 'package:flutter/material.dart'; import 'package:permission_master/permission_master.dart'; Future requestMediaPermissions() async { final permissionMaster = PermissionMaster(); final status = await permissionMaster.requestStoragePermission(); if (status == PermissionStatus.granted) { print('Media permissions granted'); } else if (status == PermissionStatus.openSettings) { // Permanent denial, suggest opening app settings await permissionMaster.openAppSettings(); } else { print('Media permissions denied'); } } ``` --- ### **`AndroidManifest.xml` Settings for Android 13** To support Android 13, your `AndroidManifest.xml` file should look like this: ```xml ``` --- ### **Important Changes for Android 13** 1. **Removal of `requestLegacyExternalStorage`**: - In Android 11 (API level 30) and above, the `requestLegacyExternalStorage` attribute was used to maintain compatibility with the old file system. However, in Android 13, this attribute **is no longer supported**, and you must use **specific permissions** instead. 2. **Use of `MediaStore`**: - To access media files in Android 13, you must use `MediaStore`. This API allows you to access photo, video, and music files. --- ### **Requesting Permissions at Runtime** To request permissions at runtime, you can use the `permission_master` package. This package helps you request and manage permissions easily. #### **Setup and Initialization** 1. **Import the Package** ```dart import 'package:permission_master/permission_master.dart'; ``` 2. **Set BuildContext (Important for Dialogs)** ```dart class _MyAppState extends State { @override void initState() { super.initState(); // Set context for dialog support PermissionMaster.setContext(context); } } ``` #### **Storage Permission Example** ```dart Future requestStorageAccess() async { final permissionMaster = PermissionMaster(); final status = await permissionMaster.requestStoragePermission(); if (status == PermissionStatus.granted) { // Read/write files allowed } else if (status == PermissionStatus.openSettings) { // Permanent denial, suggest opening app settings await permissionMaster.openAppSettings(); } else { print('Storage permission not granted'); } } ``` #### **Adding Dependencies** In your `pubspec.yaml` file, add the package: ```yaml dependencies: permission_master: git: url: https://github.com/SwanFlutter/permission_master.git ``` #### **Note** If you use `permission_master`, you still need to add the necessary permissions to the `AndroidManifest.xml` file. Also, the `android:requestLegacyExternalStorage="true"` attribute should still be included in the application tag.