Commit 830ee21a by songyanzhi

feat:init

parents
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/path_provider_android.iml" filepath="$PROJECT_DIR$/.idea/path_provider_android.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
# Below is a list of people and organizations that have contributed
# to the Flutter project. Names should be added to the list like so:
#
# Name/Organization <email address>
Google Inc.
The Chromium Authors
German Saprykin <saprykin.h@gmail.com>
Benjamin Sauer <sauer.benjamin@gmail.com>
larsenthomasj@gmail.com
Ali Bitek <alibitek@protonmail.ch>
Pol Batlló <pol.batllo@gmail.com>
Anatoly Pulyaevskiy
Hayden Flinner <haydenflinner@gmail.com>
Stefano Rodriguez <hlsroddy@gmail.com>
Salvatore Giordano <salvatoregiordanoo@gmail.com>
Brian Armstrong <brian@flutter.institute>
Paul DeMarco <paulmdemarco@gmail.com>
Fabricio Nogueira <feufeu@gmail.com>
Simon Lightfoot <simon@devangels.london>
Ashton Thomas <ashton@acrinta.com>
Thomas Danner <thmsdnnr@gmail.com>
Diego Velásquez <diego.velasquez.lopez@gmail.com>
Hajime Nakamura <nkmrhj@gmail.com>
Tuyển Vũ Xuân <netsoft1985@gmail.com>
Miguel Ruivo <miguel@miguelruivo.com>
Sarthak Verma <sarthak@artiosys.com>
Mike Diarmid <mike@invertase.io>
Invertase <oss@invertase.io>
Elliot Hesp <elliot@invertase.io>
Vince Varga <vince.varga@smaho.com>
Aawaz Gyawali <awazgyawali@gmail.com>
EUI Limited <ian.evans3@admiralgroup.co.uk>
Katarina Sheremet <katarina@sheremet.ch>
Thomas Stockx <thomas@stockxit.com>
Sarbagya Dhaubanjar <sarbagyastha@gmail.com>
Ozkan Eksi <ozeksi@gmail.com>
Rishab Nayak <rishab@bu.edu>
ko2ic <ko2ic.dev@gmail.com>
Jonathan Younger <jonathan@daikini.com>
Jose Sanchez <josesm82@gmail.com>
Debkanchan Samadder <debu.samadder@gmail.com>
Audrius Karosevicius <audrius.karosevicius@gmail.com>
Lukasz Piliszczuk <lukasz@intheloup.io>
SoundReply Solutions GmbH <ch@soundreply.com>
Rafal Wachol <rwachol@gmail.com>
Pau Picas <pau.picas@gmail.com>
Christian Weder <chrstian.weder@yapeal.ch>
Alexandru Tuca <salexandru.tuca@outlook.com>
Christian Weder <chrstian.weder@yapeal.ch>
Rhodes Davis Jr. <rody.davis.jr@gmail.com>
Luigi Agosti <luigi@tengio.com>
Quentin Le Guennec <quentin@tengio.com>
Koushik Ravikumar <koushik@tengio.com>
Nissim Dsilva <nissim@tengio.com>
Giancarlo Rocha <giancarloiff@gmail.com>
Ryo Miyake <ryo@miyake.id>
Théo Champion <contact.theochampion@gmail.com>
Kazuki Yamaguchi <y.kazuki0614n@gmail.com>
Eitan Schwartz <eshvartz@gmail.com>
Chris Rutkowski <chrisrutkowski89@gmail.com>
Juan Alvarez <juan.alvarez@resideo.com>
Aleksandr Yurkovskiy <sanekyy@gmail.com>
Anton Borries <mail@antonborri.es>
Alex Li <google@alexv525.com>
Rahul Raj <64.rahulraj@gmail.com>
## 2.2.7
* Updates AGP version to 8.5.0.
## 2.2.6
* Updates annotations lib to 1.8.0.
## 2.2.5
* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
* Removes support for apps using the v1 Android embedding.
## 2.2.4
* Updates minSdkVersion version to 19.
* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2.
## 2.2.3
* Updates minimum supported SDK version to Flutter 3.13/Dart 3.1.
* Updates compileSdk version to 34.
## 2.2.2
* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0.
* Updates annotations lib to 1.7.1.
## 2.2.1
* Updates annotations lib to 1.7.0.
## 2.2.0
* Adds implementation of `getDownloadsDirectory()`.
## 2.1.1
* Adds pub topics to package metadata.
* Updates minimum supported SDK version to Flutter 3.7/Dart 2.19.
## 2.1.0
* Adds getApplicationCachePath() for storing app-specific cache files.
* Updates minimum supported SDK version to Flutter 3.3/Dart 2.18.
## 2.0.27
* Fixes compatibility with AGP versions older than 4.2.
## 2.0.26
* Adds a namespace for compatibility with AGP 8.0.
## 2.0.25
* Fixes Java warnings.
## 2.0.24
* Clarifies explanation of endorsement in README.
* Aligns Dart and Flutter SDK constraints.
* Updates compileSdkVersion to 33.
## 2.0.23
* Updates links for the merge of flutter/plugins into flutter/packages.
* Updates minimum Flutter version to 3.0.
## 2.0.22
* Removes unused Guava dependency.
## 2.0.21
* Updates code for `no_leading_underscores_for_local_identifiers` lint.
* Updates minimum Flutter version to 2.10.
* Upgrades `androidx.annotation` version to 1.5.0.
* Upgrades Android Gradle plugin version to 7.3.1.
## 2.0.20
* Reverts changes in versions 2.0.18 and 2.0.19.
## 2.0.19
* Bumps kotlin to 1.7.10
## 2.0.18
* Bumps `androidx.annotation:annotation` version to 1.4.0.
* Bumps gradle version to 7.2.2.
## 2.0.17
* Lower minimim version back to 2.8.1.
## 2.0.16
* Fixes bug with `getExternalStoragePaths(null)`.
## 2.0.15
* Switches the medium from MethodChannels to Pigeon.
## 2.0.14
* Fixes library_private_types_in_public_api, sort_child_properties_last and use_key_in_widget_constructors
lint warnings.
## 2.0.13
* Fixes typing build warning.
## 2.0.12
* Returns to using a different platform channel name, undoing the revert in
2.0.11, but updates the minimum Flutter version to 2.8 to avoid the issue
that caused the revert.
## 2.0.11
* Temporarily reverts the platform channel name change from 2.0.10 in order to
restore compatibility with Flutter versions earlier than 2.8.
## 2.0.10
* Switches to a package-internal implementation of the platform interface.
## 2.0.9
* Updates Android compileSdkVersion to 31.
## 2.0.8
* Updates example app Android compileSdkVersion to 31.
* Fixes typing build warning.
## 2.0.7
* Fixes link in README.
## 2.0.6
* Split from `path_provider` as a federated implementation.
Copyright 2013 The Flutter Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# path\_provider\_android
The Android implementation of [`path_provider`][1].
## Usage
This package is [endorsed][2], which means you can simply use `path_provider`
normally. This package will be automatically included in your app when you do,
so you do not need to add it to your `pubspec.yaml`.
However, if you `import` this package to use any of its APIs directly, you
should add it to your `pubspec.yaml` as usual.
[1]: https://pub.dev/packages/path_provider
[2]: https://flutter.dev/to/endorsed-federated-plugin
group 'io.flutter.plugins.pathprovider'
version '1.0-SNAPSHOT'
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
}
}
rootProject.allprojects {
repositories {
google()
mavenCentral()
}
}
apply plugin: 'com.android.library'
android {
// Conditional for compatibility with AGP <4.2.
if (project.android.hasProperty("namespace")) {
namespace 'io.flutter.plugins.pathprovider'
}
compileSdk 34
defaultConfig {
minSdkVersion 19
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions {
checkAllWarnings true
warningsAsErrors true
disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
testOptions {
unitTests.includeAndroidResources = true
unitTests.returnDefaultValues = true
unitTests.all {
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}
dependencies {
implementation 'androidx.annotation:annotation:1.8.0'
testImplementation 'junit:junit:4.13.2'
}
rootProject.name = 'path_provider_android'
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.flutter.plugins.pathprovider">
</manifest>
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugins.pathprovider;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.pathprovider.Messages.PathProviderApi;
import io.flutter.util.PathUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class PathProviderPlugin implements FlutterPlugin, PathProviderApi {
static final String TAG = "PathProviderPlugin";
private Context context;
public PathProviderPlugin() {}
private void setup(BinaryMessenger messenger, Context context) {
try {
PathProviderApi.setup(messenger, this);
} catch (Exception ex) {
Log.e(TAG, "Received exception while setting up PathProviderPlugin", ex);
}
this.context = context;
}
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
setup(binding.getBinaryMessenger(), binding.getApplicationContext());
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
PathProviderApi.setup(binding.getBinaryMessenger(), null);
}
@Override
public @Nullable String getTemporaryPath() {
return getPathProviderTemporaryDirectory();
}
@Override
public @Nullable String getApplicationSupportPath() {
return getApplicationSupportDirectory();
}
@Override
public @Nullable String getApplicationDocumentsPath() {
return getPathProviderApplicationDocumentsDirectory();
}
@Override
public @Nullable String getApplicationCachePath() {
return context.getCacheDir().getPath();
}
@Override
public @Nullable String getExternalStoragePath() {
return getPathProviderStorageDirectory();
}
@Override
public @NonNull List<String> getExternalCachePaths() {
return getPathProviderExternalCacheDirectories();
}
@Override
public @NonNull List<String> getExternalStoragePaths(
@NonNull Messages.StorageDirectory directory) {
return getPathProviderExternalStorageDirectories(directory);
}
private String getPathProviderTemporaryDirectory() {
return context.getCacheDir().getPath();
}
private String getApplicationSupportDirectory() {
return PathUtils.getFilesDir(context);
}
private String getPathProviderApplicationDocumentsDirectory() {
return PathUtils.getDataDirectory(context);
}
private String getPathProviderStorageDirectory() {
final File dir = context.getExternalFilesDir(null);
if (dir == null) {
return null;
}
return dir.getAbsolutePath();
}
private List<String> getPathProviderExternalCacheDirectories() {
final List<String> paths = new ArrayList<>();
for (File dir : context.getExternalCacheDirs()) {
if (dir != null) {
paths.add(dir.getAbsolutePath());
}
}
return paths;
}
private String getStorageDirectoryString(@NonNull Messages.StorageDirectory directory) {
switch (directory) {
case ROOT:
return null;
case MUSIC:
return "music";
case PODCASTS:
return "podcasts";
case RINGTONES:
return "ringtones";
case ALARMS:
return "alarms";
case NOTIFICATIONS:
return "notifications";
case PICTURES:
return "pictures";
case MOVIES:
return "movies";
case DOWNLOADS:
return "downloads";
case DCIM:
return "dcim";
case DOCUMENTS:
return "documents";
default:
throw new RuntimeException("Unrecognized directory: " + directory);
}
}
private List<String> getPathProviderExternalStorageDirectories(
@NonNull Messages.StorageDirectory directory) {
final List<String> paths = new ArrayList<>();
for (File dir : context.getExternalFilesDirs(getStorageDirectoryString(directory))) {
if (dir != null) {
paths.add(dir.getAbsolutePath());
}
}
return paths;
}
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugins.pathprovider;
import android.os.Environment;
/** Helps to map the Dart `StorageDirectory` enum to a Android system constant. */
class StorageDirectoryMapper {
/**
* Return a Android Environment constant for a Dart Index.
*
* @return The correct Android Environment constant or null, if the index is null.
* @throws IllegalArgumentException If `dartIndex` is not null but also not matches any known
* index.
*/
static String androidType(Integer dartIndex) throws IllegalArgumentException {
if (dartIndex == null) {
return null;
}
switch (dartIndex) {
case 0:
return Environment.DIRECTORY_MUSIC;
case 1:
return Environment.DIRECTORY_PODCASTS;
case 2:
return Environment.DIRECTORY_RINGTONES;
case 3:
return Environment.DIRECTORY_ALARMS;
case 4:
return Environment.DIRECTORY_NOTIFICATIONS;
case 5:
return Environment.DIRECTORY_PICTURES;
case 6:
return Environment.DIRECTORY_MOVIES;
case 7:
return Environment.DIRECTORY_DOWNLOADS;
case 8:
return Environment.DIRECTORY_DCIM;
case 9:
return Environment.DIRECTORY_DOCUMENTS;
default:
throw new IllegalArgumentException("Unknown index: " + dartIndex);
}
}
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugins.pathprovider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import android.os.Environment;
import org.junit.Test;
public class StorageDirectoryMapperTest {
@org.junit.Test
public void testAndroidType_null() {
assertNull(StorageDirectoryMapper.androidType(null));
}
@org.junit.Test
public void testAndroidType_valid() {
assertEquals(Environment.DIRECTORY_MUSIC, StorageDirectoryMapper.androidType(0));
assertEquals(Environment.DIRECTORY_PODCASTS, StorageDirectoryMapper.androidType(1));
assertEquals(Environment.DIRECTORY_RINGTONES, StorageDirectoryMapper.androidType(2));
assertEquals(Environment.DIRECTORY_ALARMS, StorageDirectoryMapper.androidType(3));
assertEquals(Environment.DIRECTORY_NOTIFICATIONS, StorageDirectoryMapper.androidType(4));
assertEquals(Environment.DIRECTORY_PICTURES, StorageDirectoryMapper.androidType(5));
assertEquals(Environment.DIRECTORY_MOVIES, StorageDirectoryMapper.androidType(6));
assertEquals(Environment.DIRECTORY_DOWNLOADS, StorageDirectoryMapper.androidType(7));
assertEquals(Environment.DIRECTORY_DCIM, StorageDirectoryMapper.androidType(8));
}
@Test
public void testAndroidType_invalid() {
try {
assertEquals(Environment.DIRECTORY_DCIM, StorageDirectoryMapper.androidType(10));
fail();
} catch (IllegalArgumentException e) {
assertEquals("Unknown index: " + 10, e.getMessage());
}
}
}
buildFlags:
_pluginToolsConfigGlobalKey:
- "--no-tree-shake-icons"
- "--dart-define=buildmode=testing"
# Platform Implementation Test App
This is a test app for manual testing and automated integration testing
of this platform implementation. It is not intended to demonstrate actual use of
this package, since the intent is that plugin clients use the app-facing
package.
Unless you are making changes to this implementation package, this example is
very unlikely to be relevant.
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace 'io.flutter.plugins.pathproviderexample'
compileSdk flutter.compileSdkVersion
defaultConfig {
applicationId "io.flutter.plugins.pathproviderexample"
minSdkVersion flutter.minSdkVersion
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
lint {
disable 'InvalidPackage'
}
}
flutter {
source '../..'
}
dependencies {
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugins;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* Annotation to aid repository tooling in determining if a test is
* a native java unit test or a java class with a dart integration.
*
* See: https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#enabling-android-ui-tests
* for more infomation.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DartIntegrationTest {}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugins.pathprovider;
import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.integration_test.FlutterTestRunner;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.plugins.DartIntegrationTest;
import org.junit.Rule;
import org.junit.runner.RunWith;
@DartIntegrationTest
@RunWith(FlutterTestRunner.class)
public class MainActivityTest {
@Rule
public ActivityTestRule<FlutterActivity> rule = new ActivityTestRule<>(FlutterActivity.class);
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.flutter.plugins.pathproviderexample">
<uses-permission android:name="android.permission.INTERNET"/>
<application android:label="path_provider_example" android:icon="@mipmap/ic_launcher">
<activity android:name="io.flutter.embedding.android.FlutterActivity"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data android:name="flutterEmbedding" android:value="2"/>
</application>
</manifest>
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
}
}
allprojects {
repositories {
// See https://github.com/flutter/flutter/blob/master/docs/ecosystem/Plugins-and-Packages-repository-structure.md#gradle-structure for more info.
def artifactRepoKey = 'ARTIFACT_HUB_REPOSITORY'
if (System.getenv().containsKey(artifactRepoKey)) {
println "Using artifact hub"
maven { url System.getenv(artifactRepoKey) }
}
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
// Build the plugin project with warnings enabled. This is here rather than
// in the plugin itself to avoid breaking clients that have different
// warnings (e.g., deprecation warnings from a newer SDK than this project
// builds with).
gradle.projectsEvaluated {
project(":path_provider_android") {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:all" << "-Werror"
}
}
}
org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true
android.enableJetifier=true
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withInputStream { stream -> plugins.load(stream) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
// See https://github.com/flutter/flutter/blob/master/docs/ecosystem/Plugins-and-Packages-repository-structure.md#gradle-structure for more info.
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "gradle.plugin.com.google.cloud.artifactregistry:artifactregistry-gradle-plugin:2.2.1"
}
}
apply plugin: "com.google.cloud.artifactregistry.gradle-plugin"
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('getTemporaryDirectory', (WidgetTester tester) async {
final PathProviderPlatform provider = PathProviderPlatform.instance;
final String? result = await provider.getTemporaryPath();
_verifySampleFile(result, 'temporaryDirectory');
});
testWidgets('getApplicationDocumentsDirectory', (WidgetTester tester) async {
final PathProviderPlatform provider = PathProviderPlatform.instance;
final String? result = await provider.getApplicationDocumentsPath();
_verifySampleFile(result, 'applicationDocuments');
});
testWidgets('getApplicationSupportDirectory', (WidgetTester tester) async {
final PathProviderPlatform provider = PathProviderPlatform.instance;
final String? result = await provider.getApplicationSupportPath();
_verifySampleFile(result, 'applicationSupport');
});
testWidgets('getApplicationCacheDirectory', (WidgetTester tester) async {
final PathProviderPlatform provider = PathProviderPlatform.instance;
final String? result = await provider.getApplicationCachePath();
_verifySampleFile(result, 'applicationCache');
});
testWidgets('getLibraryDirectory', (WidgetTester tester) async {
final PathProviderPlatform provider = PathProviderPlatform.instance;
expect(() => provider.getLibraryPath(),
throwsA(isInstanceOf<UnsupportedError>()));
});
testWidgets('getExternalStorageDirectory', (WidgetTester tester) async {
final PathProviderPlatform provider = PathProviderPlatform.instance;
final String? result = await provider.getExternalStoragePath();
_verifySampleFile(result, 'externalStorage');
});
testWidgets('getExternalCacheDirectories', (WidgetTester tester) async {
final PathProviderPlatform provider = PathProviderPlatform.instance;
final List<String>? directories = await provider.getExternalCachePaths();
expect(directories, isNotNull);
for (final String result in directories!) {
_verifySampleFile(result, 'externalCache');
}
});
final List<StorageDirectory?> allDirs = <StorageDirectory?>[
null,
StorageDirectory.music,
StorageDirectory.podcasts,
StorageDirectory.ringtones,
StorageDirectory.alarms,
StorageDirectory.notifications,
StorageDirectory.pictures,
StorageDirectory.movies,
];
for (final StorageDirectory? type in allDirs) {
testWidgets('getExternalStorageDirectories (type: $type)',
(WidgetTester tester) async {
final PathProviderPlatform provider = PathProviderPlatform.instance;
final List<String>? directories =
await provider.getExternalStoragePaths(type: type);
expect(directories, isNotNull);
expect(directories, isNotEmpty);
for (final String result in directories!) {
_verifySampleFile(result, '$type');
}
});
}
}
/// Verify a file called [name] in [directoryPath] by recreating it with test
/// contents when necessary.
void _verifySampleFile(String? directoryPath, String name) {
expect(directoryPath, isNotNull);
if (directoryPath == null) {
return;
}
final Directory directory = Directory(directoryPath);
final File file = File('${directory.path}${Platform.pathSeparator}$name');
if (file.existsSync()) {
file.deleteSync();
expect(file.existsSync(), isFalse);
}
file.writeAsStringSync('Hello world!');
expect(file.readAsStringSync(), 'Hello world!');
// This check intentionally avoids using Directory.listSync due to
// https://github.com/dart-lang/sdk/issues/54287.
expect(
Process.runSync('ls', <String>[directory.path]).stdout, contains(name));
file.deleteSync();
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore_for_file: public_member_api_docs
import 'package:flutter/material.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Path Provider',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Path Provider'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final PathProviderPlatform provider = PathProviderPlatform.instance;
Future<String?>? _tempDirectory;
Future<String?>? _appSupportDirectory;
Future<String?>? _appDocumentsDirectory;
Future<String?>? _appCacheDirectory;
Future<String?>? _externalDocumentsDirectory;
Future<String?>? _externalDownloadsDirectory;
Future<List<String>?>? _externalStorageDirectories;
Future<List<String>?>? _externalCacheDirectories;
void _requestTempDirectory() {
setState(() {
_tempDirectory = provider.getTemporaryPath();
});
}
Widget _buildDirectory(
BuildContext context, AsyncSnapshot<String?> snapshot) {
Text text = const Text('');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
text = Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
text = Text('path: ${snapshot.data}');
} else {
text = const Text('path unavailable');
}
}
return Padding(padding: const EdgeInsets.all(16.0), child: text);
}
Widget _buildDirectories(
BuildContext context, AsyncSnapshot<List<String>?> snapshot) {
Text text = const Text('');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
text = Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
final String combined = snapshot.data!.join(', ');
text = Text('paths: $combined');
} else {
text = const Text('path unavailable');
}
}
return Padding(padding: const EdgeInsets.all(16.0), child: text);
}
void _requestAppDocumentsDirectory() {
setState(() {
_appDocumentsDirectory = provider.getApplicationDocumentsPath();
});
}
void _requestAppSupportDirectory() {
setState(() {
_appSupportDirectory = provider.getApplicationSupportPath();
});
}
void _requestAppCacheDirectory() {
setState(() {
_appCacheDirectory = provider.getApplicationCachePath();
});
}
void _requestExternalStorageDirectory() {
setState(() {
_externalDocumentsDirectory = provider.getExternalStoragePath();
});
}
void _requestExternalStorageDirectories(StorageDirectory type) {
setState(() {
_externalStorageDirectories =
provider.getExternalStoragePaths(type: type);
});
}
void _requestExternalCacheDirectories() {
setState(() {
_externalCacheDirectories = provider.getExternalCachePaths();
});
}
void _requestDownloadsDirectory() {
setState(() {
_externalDownloadsDirectory = provider.getDownloadsPath();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: _requestTempDirectory,
child: const Text('Get Temporary Directory'),
),
),
FutureBuilder<String?>(
future: _tempDirectory, builder: _buildDirectory),
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: _requestAppDocumentsDirectory,
child: const Text('Get Application Documents Directory'),
),
),
FutureBuilder<String?>(
future: _appDocumentsDirectory, builder: _buildDirectory),
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: _requestAppSupportDirectory,
child: const Text('Get Application Support Directory'),
),
),
FutureBuilder<String?>(
future: _appSupportDirectory, builder: _buildDirectory),
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: _requestAppCacheDirectory,
child: const Text('Get Application Cache Directory'),
),
),
FutureBuilder<String?>(
future: _appCacheDirectory, builder: _buildDirectory),
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: _requestExternalStorageDirectory,
child: const Text('Get External Storage Directory'),
),
),
FutureBuilder<String?>(
future: _externalDocumentsDirectory, builder: _buildDirectory),
Column(children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
child: const Text('Get External Storage Directories'),
onPressed: () {
_requestExternalStorageDirectories(
StorageDirectory.music,
);
},
),
),
]),
FutureBuilder<List<String>?>(
future: _externalStorageDirectories,
builder: _buildDirectories),
Column(children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: _requestExternalCacheDirectories,
child: const Text('Get External Cache Directories'),
),
),
]),
FutureBuilder<List<String>?>(
future: _externalCacheDirectories, builder: _buildDirectories),
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: _requestDownloadsDirectory,
child: const Text('Get Downloads Directory'),
),
),
FutureBuilder<String?>(
future: _externalDownloadsDirectory, builder: _buildDirectory),
],
),
),
);
}
}
name: path_provider_example
description: Demonstrates how to use the path_provider plugin.
publish_to: none
environment:
sdk: ^3.4.0
flutter: ">=3.22.0"
dependencies:
flutter:
sdk: flutter
path_provider_android:
# When depending on this package from a real application you should use:
# path_provider: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
path_provider_platform_interface: ^2.1.0
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
flutter:
uses-material-design: true
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v9.2.5), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';
enum StorageDirectory {
root,
music,
podcasts,
ringtones,
alarms,
notifications,
pictures,
movies,
downloads,
dcim,
documents,
}
class PathProviderApi {
/// Constructor for [PathProviderApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
PathProviderApi({BinaryMessenger? binaryMessenger})
: _binaryMessenger = binaryMessenger;
final BinaryMessenger? _binaryMessenger;
static const MessageCodec<Object?> codec = StandardMessageCodec();
Future<String?> getTemporaryPath() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return (replyList[0] as String?);
}
}
Future<String?> getApplicationSupportPath() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return (replyList[0] as String?);
}
}
Future<String?> getApplicationDocumentsPath() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return (replyList[0] as String?);
}
}
Future<String?> getApplicationCachePath() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getApplicationCachePath', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return (replyList[0] as String?);
}
}
Future<String?> getExternalStoragePath() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getExternalStoragePath', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else {
return (replyList[0] as String?);
}
}
Future<List<String?>> getExternalCachePaths() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getExternalCachePaths', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as List<Object?>?)!.cast<String?>();
}
}
Future<List<String?>> getExternalStoragePaths(
StorageDirectory arg_directory) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_directory.index]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as List<Object?>?)!.cast<String?>();
}
}
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'messages.g.dart' as messages;
messages.StorageDirectory _convertStorageDirectory(
StorageDirectory? directory) {
switch (directory) {
case null:
return messages.StorageDirectory.root;
case StorageDirectory.music:
return messages.StorageDirectory.music;
case StorageDirectory.podcasts:
return messages.StorageDirectory.podcasts;
case StorageDirectory.ringtones:
return messages.StorageDirectory.ringtones;
case StorageDirectory.alarms:
return messages.StorageDirectory.alarms;
case StorageDirectory.notifications:
return messages.StorageDirectory.notifications;
case StorageDirectory.pictures:
return messages.StorageDirectory.pictures;
case StorageDirectory.movies:
return messages.StorageDirectory.movies;
case StorageDirectory.downloads:
return messages.StorageDirectory.downloads;
case StorageDirectory.dcim:
return messages.StorageDirectory.dcim;
case StorageDirectory.documents:
return messages.StorageDirectory.documents;
}
}
/// The Android implementation of [PathProviderPlatform].
class PathProviderAndroid extends PathProviderPlatform {
final messages.PathProviderApi _api = messages.PathProviderApi();
/// Registers this class as the default instance of [PathProviderPlatform].
static void registerWith() {
PathProviderPlatform.instance = PathProviderAndroid();
}
@override
Future<String?> getTemporaryPath() {
return _api.getTemporaryPath();
}
@override
Future<String?> getApplicationSupportPath() {
return _api.getApplicationSupportPath();
}
@override
Future<String?> getLibraryPath() {
throw UnsupportedError('getLibraryPath is not supported on Android');
}
@override
Future<String?> getApplicationDocumentsPath() {
return _api.getApplicationDocumentsPath();
}
@override
Future<String?> getApplicationCachePath() {
return _api.getApplicationCachePath();
}
@override
Future<String?> getExternalStoragePath() {
return _api.getExternalStoragePath();
}
@override
Future<List<String>?> getExternalCachePaths() async {
return (await _api.getExternalCachePaths()).cast<String>();
}
@override
Future<List<String>?> getExternalStoragePaths({
StorageDirectory? type,
}) async {
return _getExternalStoragePaths(type: type);
}
@override
Future<String?> getDownloadsPath() async {
final List<String> paths =
await _getExternalStoragePaths(type: StorageDirectory.downloads);
return paths.isEmpty ? null : paths.first;
}
Future<List<String>> _getExternalStoragePaths({
StorageDirectory? type,
}) async {
return (await _api.getExternalStoragePaths(_convertStorageDirectory(type)))
.cast<String>();
}
}
Copyright 2013 The Flutter Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:pigeon/pigeon.dart';
@ConfigurePigeon(PigeonOptions(
input: 'pigeons/messages.dart',
javaOut:
'android/src/main/java/io/flutter/plugins/pathprovider/Messages.java',
javaOptions: JavaOptions(
className: 'Messages', package: 'io.flutter.plugins.pathprovider'),
dartOut: 'lib/messages.g.dart',
dartTestOut: 'test/messages_test.g.dart',
copyrightHeader: 'pigeons/copyright.txt',
))
enum StorageDirectory {
root,
music,
podcasts,
ringtones,
alarms,
notifications,
pictures,
movies,
downloads,
dcim,
documents,
}
@HostApi(dartHostTestHandler: 'TestPathProviderApi')
abstract class PathProviderApi {
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
String? getTemporaryPath();
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
String? getApplicationSupportPath();
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
String? getApplicationDocumentsPath();
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
String? getApplicationCachePath();
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
String? getExternalStoragePath();
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
List<String?> getExternalCachePaths();
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
List<String?> getExternalStoragePaths(StorageDirectory directory);
}
name: path_provider_android
description: Android implementation of the path_provider plugin.
repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22
version: 2.2.7
environment:
sdk: ^3.4.0
flutter: ">=3.22.0"
flutter:
plugin:
implements: path_provider
platforms:
android:
package: io.flutter.plugins.pathprovider
pluginClass: PathProviderPlugin
dartPluginClass: PathProviderAndroid
dependencies:
flutter:
sdk: flutter
path_provider_platform_interface: ^2.1.0
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
pigeon: ^9.2.4
test: ^1.16.0
topics:
- files
- path-provider
- paths
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v9.2.5), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import
// ignore_for_file: avoid_relative_lib_imports
import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path_provider_android/messages.g.dart';
abstract class TestPathProviderApi {
static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
TestDefaultBinaryMessengerBinding.instance;
static const MessageCodec<Object?> codec = StandardMessageCodec();
String? getTemporaryPath();
String? getApplicationSupportPath();
String? getApplicationDocumentsPath();
String? getApplicationCachePath();
String? getExternalStoragePath();
List<String?> getExternalCachePaths();
List<String?> getExternalStoragePaths(StorageDirectory directory);
static void setup(TestPathProviderApi? api,
{BinaryMessenger? binaryMessenger}) {
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
// ignore message
final String? output = api.getTemporaryPath();
return <Object?>[output];
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
// ignore message
final String? output = api.getApplicationSupportPath();
return <Object?>[output];
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath',
codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
// ignore message
final String? output = api.getApplicationDocumentsPath();
return <Object?>[output];
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getApplicationCachePath', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
// ignore message
final String? output = api.getApplicationCachePath();
return <Object?>[output];
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getExternalStoragePath', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
// ignore message
final String? output = api.getExternalStoragePath();
return <Object?>[output];
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getExternalCachePaths', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
// ignore message
final List<String?> output = api.getExternalCachePaths();
return <Object?>[output];
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths was null.');
final List<Object?> args = (message as List<Object?>?)!;
final StorageDirectory? arg_directory =
args[0] == null ? null : StorageDirectory.values[args[0] as int];
assert(arg_directory != null,
'Argument for dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths was null, expected non-null StorageDirectory.');
final List<String?> output =
api.getExternalStoragePaths(arg_directory!);
return <Object?>[output];
});
}
}
}
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
import 'package:path_provider_android/messages.g.dart' as messages;
import 'package:path_provider_android/path_provider_android.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'messages_test.g.dart';
const String kTemporaryPath = 'temporaryPath';
const String kApplicationSupportPath = 'applicationSupportPath';
const String kApplicationDocumentsPath = 'applicationDocumentsPath';
const String kApplicationCachePath = 'applicationCachePath';
const String kExternalCachePaths = 'externalCachePaths';
const String kExternalStoragePaths = 'externalStoragePaths';
class _Api implements TestPathProviderApi {
_Api({this.returnsExternalStoragePaths = true});
final bool returnsExternalStoragePaths;
@override
String? getApplicationDocumentsPath() => kApplicationDocumentsPath;
@override
String? getApplicationSupportPath() => kApplicationSupportPath;
@override
String? getApplicationCachePath() => kApplicationCachePath;
@override
List<String?> getExternalCachePaths() => <String>[kExternalCachePaths];
@override
String? getExternalStoragePath() => kExternalStoragePaths;
@override
List<String?> getExternalStoragePaths(messages.StorageDirectory directory) {
return <String?>[if (returnsExternalStoragePaths) kExternalStoragePaths];
}
@override
String? getTemporaryPath() => kTemporaryPath;
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('PathProviderAndroid', () {
late PathProviderAndroid pathProvider;
setUp(() async {
pathProvider = PathProviderAndroid();
TestPathProviderApi.setup(_Api());
});
test('getTemporaryPath', () async {
final String? path = await pathProvider.getTemporaryPath();
expect(path, kTemporaryPath);
});
test('getApplicationSupportPath', () async {
final String? path = await pathProvider.getApplicationSupportPath();
expect(path, kApplicationSupportPath);
});
test('getApplicationCachePath', () async {
final String? path = await pathProvider.getApplicationCachePath();
expect(path, kApplicationCachePath);
});
test('getLibraryPath fails', () async {
try {
await pathProvider.getLibraryPath();
fail('should throw UnsupportedError');
} catch (e) {
expect(e, isUnsupportedError);
}
});
test('getApplicationDocumentsPath', () async {
final String? path = await pathProvider.getApplicationDocumentsPath();
expect(path, kApplicationDocumentsPath);
});
test('getExternalCachePaths succeeds', () async {
final List<String>? result = await pathProvider.getExternalCachePaths();
expect(result!.length, 1);
expect(result.first, kExternalCachePaths);
});
for (final StorageDirectory? type in <StorageDirectory?>[
...StorageDirectory.values
]) {
test('getExternalStoragePaths (type: $type) android succeeds', () async {
final List<String>? result =
await pathProvider.getExternalStoragePaths(type: type);
expect(result!.length, 1);
expect(result.first, kExternalStoragePaths);
});
} // end of for-loop
test('getDownloadsPath succeeds', () async {
final String? path = await pathProvider.getDownloadsPath();
expect(path, kExternalStoragePaths);
});
test(
'getDownloadsPath returns null, when getExternalStoragePaths returns '
'an empty list', () async {
final PathProviderAndroid pathProvider = PathProviderAndroid();
TestPathProviderApi.setup(_Api(returnsExternalStoragePaths: false));
final String? path = await pathProvider.getDownloadsPath();
expect(path, null);
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment