@@ -3,6 +3,7 @@ package com.dawndrizzle.wing.cqut
33import android.app.DownloadManager
44import android.app.ActivityManager
55import android.content.ComponentName
6+ import android.content.ContentValues
67import android.content.Context
78import android.content.Intent
89import android.content.IntentFilter
@@ -13,6 +14,7 @@ import android.os.Build
1314import android.os.BatteryManager
1415import android.os.Environment
1516import android.os.PowerManager
17+ import android.provider.MediaStore
1618import android.provider.Settings
1719import io.flutter.embedding.android.FlutterActivity
1820import io.flutter.embedding.engine.FlutterEngine
@@ -69,6 +71,72 @@ class MainActivity : FlutterActivity() {
6971 }
7072 }
7173
74+ " exportToDownloads" -> {
75+ val srcPath = call.argument<String >(" srcPath" )
76+ val fileName = call.argument<String >(" fileName" )
77+ val mimeType = call.argument<String >(" mimeType" ) ? : " application/octet-stream"
78+
79+ if (srcPath.isNullOrBlank() || fileName.isNullOrBlank()) {
80+ result.error(" INVALID_ARGS" , " srcPath/fileName is required" , null )
81+ return @setMethodCallHandler
82+ }
83+
84+ try {
85+ val src = java.io.File (srcPath)
86+ if (! src.exists() || ! src.isFile) {
87+ result.error(" NOT_FOUND" , " source file not found" , null )
88+ return @setMethodCallHandler
89+ }
90+
91+ val savedPath = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .Q ) {
92+ val values = ContentValues ().apply {
93+ put(MediaStore .Downloads .DISPLAY_NAME , fileName)
94+ put(MediaStore .Downloads .MIME_TYPE , mimeType)
95+ put(MediaStore .Downloads .RELATIVE_PATH , " ${Environment .DIRECTORY_DOWNLOADS } /CQUT-Helper" )
96+ put(MediaStore .Downloads .IS_PENDING , 1 )
97+ }
98+
99+ val collection = MediaStore .Downloads .getContentUri(MediaStore .VOLUME_EXTERNAL_PRIMARY )
100+ val uri = contentResolver.insert(collection, values)
101+ ? : throw IllegalStateException (" failed to create downloads item" )
102+
103+ contentResolver.openOutputStream(uri)?.use { out ->
104+ src.inputStream().use { input ->
105+ input.copyTo(out )
106+ }
107+ } ? : throw IllegalStateException (" failed to open output stream" )
108+
109+ values.clear()
110+ values.put(MediaStore .Downloads .IS_PENDING , 0 )
111+ contentResolver.update(uri, values, null , null )
112+
113+ " /Download/CQUT-Helper/$fileName "
114+ } else {
115+ val dir = java.io.File (
116+ Environment .getExternalStoragePublicDirectory(Environment .DIRECTORY_DOWNLOADS ),
117+ " CQUT-Helper" ,
118+ )
119+ if (! dir.exists()) {
120+ dir.mkdirs()
121+ }
122+ val dst = java.io.File (dir, fileName)
123+ src.inputStream().use { input ->
124+ dst.outputStream().use { out ->
125+ input.copyTo(out )
126+ }
127+ }
128+ dst.absolutePath
129+ }
130+
131+ val map: HashMap <String , Any > = hashMapOf(
132+ " path" to savedPath,
133+ )
134+ result.success(map)
135+ } catch (e: Exception ) {
136+ result.error(" EXPORT_FAILED" , e.toString(), null )
137+ }
138+ }
139+
72140 else -> result.notImplemented()
73141 }
74142 }
0 commit comments