Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 57 additions & 24 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,30 +1,63 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
# https://www.dartlang.org/guides/libraries/private-files

# Files and directories created by pub
.dart_tool/
.packages
.pub/
build/
pubspec.lock

# Directory created by dartdoc
/doc/api/

# IDE
*.iml // IntelliJ
*.ipr // IntelliJ
*.iws // IntelliJ
.idea/ // IntelliJ
.DS_Store // Mac

# copied from https://github.com/flutter/plugins/blob/master/.gitignore
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
.vscode/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.packages
.pub/
.dart_tool/
pubspec.lock
flutter_export_environment.sh

examples/all_plugins/pubspec.yaml

Podfile
Podfile.lock
Pods/
.symlinks/
**/Flutter/App.framework/
**/Flutter/Flutter.framework/
**/Flutter/Generated.xcconfig
**/Flutter/flutter_assets/
ServiceDefinitions.json
xcuserdata/
**/DerivedData/

local.properties
keystore.properties
.gradle/
gradlew
gradlew.bat
gradle-wrapper.jar
.flutter-plugins-dependencies
*.iml

GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
GeneratedPluginRegistrant.java
build/
.flutter-plugins

.project
.classpath
.settings
10 changes: 7 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ group 'com.cleveroad.cr_file_saver'
version '1.0-SNAPSHOT'

buildscript {
ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand All @@ -25,7 +25,11 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 31
// Conditional for compatibility with AGP <4.2.
if (project.android.hasProperty("namespace")) {
namespace 'com.cleveroad.cr_file_saver'
}
compileSdkVersion 33

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand Down
5 changes: 5 additions & 0 deletions android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package com.cleveroad.cr_file_saver

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.provider.MediaStore

import android.util.Log
import androidx.annotation.NonNull
import androidx.core.app.ActivityCompat
import com.cleveroad.cr_file_saver.base.AbstractActivityAware
import com.cleveroad.cr_file_saver.base.FileSaverPluginCallback
import com.cleveroad.cr_file_saver.utils.getFileName
import com.cleveroad.cr_file_saver.utils.getFileNameWithoutExtension
import com.cleveroad.cr_file_saver.utils.getMimeType
import com.cleveroad.cr_file_saver.utils.saveFileInBackground
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
Expand All @@ -19,6 +24,7 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry
import java.io.File
import kotlin.math.log

/** CrFileSaverPlugin */
class CrFileSaverPlugin : FlutterPlugin, MethodCallHandler, AbstractActivityAware(),
Expand Down Expand Up @@ -82,24 +88,51 @@ class CrFileSaverPlugin : FlutterPlugin, MethodCallHandler, AbstractActivityAwar
}

override fun onSaveFileDialog(
sourceFile: File,
result: Pigeon.Result<String>?,
destinationFileName: String?
context: Context,
sourceFile: File,
result: Pigeon.Result<String>?,
destinationFileName: String?
) {
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
putExtra(Intent.EXTRA_TITLE, destinationFileName ?: getFileName(sourceFile.path))
type = "*/*"
}.let {
this.sourceFile = sourceFile
this.saveFilePendingResult = result

activity?.let { activity ->
// Checking for available activity to handle
if (it.resolveActivity(activity.packageManager) != null) {
activity.startActivityForResult(it, SAVEFILE_REQCODE)
} else {
result?.error(NoResolvedActivityException())
val mimeType = getMimeType(context, sourceFile.path)
if (mimeType == null) {
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
putExtra(Intent.EXTRA_TITLE, destinationFileName ?: getFileName(sourceFile.path))
type = "*/*"
}.let {
this.sourceFile = sourceFile
this.saveFilePendingResult = result

activity?.let { activity ->
// Checking for available activity to handle
if (it.resolveActivity(activity.packageManager) != null) {
activity.startActivityForResult(it, SAVEFILE_REQCODE)
} else {
result?.error(NoResolvedActivityException())
}
}
}
} else {
val fileNameWithoutExtension =
destinationFileName?.let { getFileNameWithoutExtension(it) }
?: getFileNameWithoutExtension(getFileName(sourceFile.path))

Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
putExtra(Intent.EXTRA_TITLE, fileNameWithoutExtension)
putExtra(MediaStore.MediaColumns.MIME_TYPE, mimeType)
type = mimeType
}.let {
this.sourceFile = sourceFile
this.saveFilePendingResult = result

activity?.let { activity ->
// Checking for available activity to handle
if (it.resolveActivity(activity.packageManager) != null) {
activity.startActivityForResult(it, SAVEFILE_REQCODE)
} else {
result?.error(NoResolvedActivityException())
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class FileSaverImpl(private val context: Context, private val callback: FileSave
result: Pigeon.Result<String>?
) {
val sourceFile = File(params.sourceFilePath)
callback.onSaveFileDialog(sourceFile, result, params.destinationFileName)
callback.onSaveFileDialog(context, sourceFile, result, params.destinationFileName)
}

@Suppress("DEPRECATION")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.cleveroad.cr_file_saver.base

import android.content.Context
import com.cleveroad.cr_file_saver.Pigeon
import java.io.File

interface FileSaverPluginCallback {
fun onRequestPermission(result: Pigeon.Result<Boolean>?)
fun onSaveFileDialog(
context: Context,
sourceFile: File,
result: Pigeon.Result<String>?,
destinationFileName: String?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ fun getFileName(url: String): String {
val last = segments.last();
return last
}
// get file name without extension
fun getFileNameWithoutExtension(fileName: String): String {
val lastIndex = fileName.lastIndexOf('.')
if (lastIndex != -1) {
return fileName.substring(0, lastIndex)
}
return fileName
}

// Only used in old APIs
@Suppress("DEPRECATION")
Expand Down