@@ -15,97 +15,112 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler
1515import io.flutter.plugin.common.MethodChannel.Result
1616import java.io.ByteArrayOutputStream
1717import java.io.File
18- import java.io.FileInputStream
1918import java.io.FileOutputStream
20- import java.io.IOException
2119import java.util.UUID
22- import kotlin. concurrent.thread
20+ import java.util. concurrent.Executors
2321
2422/* * PasteboardPlugin */
25- class PasteboardPlugin : FlutterPlugin , MethodCallHandler {
26- // / The MethodChannel that will the communication between Flutter and native Android
27- // /
28- // / This local reference serves to register the plugin with the Flutter Engine and unregister it
29- // / when the Flutter Engine is detached from the Activity
30- private lateinit var context: Context
31- private lateinit var channel : MethodChannel
23+ class PasteboardPlugin : FlutterPlugin , MethodCallHandler {
24+ // / The MethodChannel that will the communication between Flutter and native Android
25+ // /
26+ // / This local reference serves to register the plugin with the Flutter Engine and unregister it
27+ // / when the Flutter Engine is detached from the Activity
28+ private lateinit var context: Context
29+ private lateinit var channel: MethodChannel
3230
33- override fun onAttachedToEngine (flutterPluginBinding : FlutterPlugin .FlutterPluginBinding ) {
34- channel = MethodChannel (flutterPluginBinding.binaryMessenger, " pasteboard" )
35- channel.setMethodCallHandler(this )
36- context = flutterPluginBinding.applicationContext
37- }
31+ private val executor = Executors .newSingleThreadExecutor()
3832
39- override fun onMethodCall (call : MethodCall , result : Result ) {
40- val manager = context.getSystemService(Context .CLIPBOARD_SERVICE ) as ClipboardManager
41- val cr = context.contentResolver
42- val first = manager.primaryClip?.getItemAt(0 )
43- when (call.method) {
44- " image" -> {
45- first?.uri?.let {
46- val mime = cr.getType(it)
47- if (mime == null || ! mime.startsWith(" image" )) return result.success(null )
48- result.success(cr.openInputStream(it).use { stream ->
49- stream?.buffered()?.readBytes()
50- })
51- }
52- result.success(null )
53- }
54- " files" -> {
55- manager.primaryClip?.run {
56- if (itemCount == 0 ) result.success(null )
57- val files: MutableList <String > = mutableListOf ()
58- for (i in 0 until itemCount) {
59- getItemAt(i).uri?.let {
60- files.add(it.toString())
33+ override fun onAttachedToEngine (flutterPluginBinding : FlutterPlugin .FlutterPluginBinding ) {
34+ channel = MethodChannel (flutterPluginBinding.binaryMessenger, " pasteboard" )
35+ channel.setMethodCallHandler(this )
36+ context = flutterPluginBinding.applicationContext
37+ }
38+
39+ override fun onMethodCall (call : MethodCall , result : Result ) {
40+ val manager = context.getSystemService(Context .CLIPBOARD_SERVICE ) as ClipboardManager
41+ val cr = context.contentResolver
42+ val first = manager.primaryClip?.getItemAt(0 )
43+ when (call.method) {
44+ " image" -> {
45+ executor.run {
46+ val uri = first?.uri ? : return @run result.success(null )
47+ val mime = cr.getType(uri)
48+ if (mime == null || ! mime.startsWith(" image" )) return @run result.success(null )
49+ val bytes =
50+ cr.openInputStream(uri)?.readBytes() ? : return @run result.success(null )
51+ result.success(bytes)
52+ }
6153 }
62- }
63- result.success(files)
64- }
65- }
66- " html" -> result.success(first?.htmlText)
67- " writeFiles" -> {
68- val args = call.arguments<List <String >>() ? : return result.error(
69- " NoArgs" ,
70- " Missing Arguments" ,
71- null ,
72- )
73- val clip: ClipData ? = null
74- for (i in args) {
75- val uri = Uri .parse(i)
76- clip ? : ClipData .newUri(cr, " files" , uri)
77- clip?.addItem(ClipData .Item (uri))
78- }
79- clip?.let {
80- manager.setPrimaryClip(it)
81- }
82- result.success(null )
83- }
84- " writeImage" -> {
85- val image = call.arguments<ByteArray >() ? : return result.error(
86- " NoArgs" ,
87- " Missing Arguments" ,
88- null ,
89- )
90- val out = ByteArrayOutputStream ()
91- thread {
92- val bitmap = BitmapFactory .decodeByteArray(image, 0 , image.size)
93- bitmap.compress(Bitmap .CompressFormat .PNG , 100 , out )
94- }
95- val name = UUID .randomUUID().toString()
96- val file = File (context.cacheDir, name)
97- FileOutputStream (file).use {
98- out .writeTo(it)
54+
55+ " files" -> {
56+ manager.primaryClip?.run {
57+ if (itemCount == 0 ) result.success(null )
58+ val files: MutableList <String > = mutableListOf ()
59+ for (i in 0 until itemCount) {
60+ getItemAt(i).uri?.let {
61+ files.add(it.toString())
62+ }
63+ }
64+ result.success(files)
65+ }
66+ }
67+
68+ " html" -> result.success(first?.htmlText)
69+ " writeFiles" -> {
70+ val args = call.arguments<List <String >>() ? : return result.error(
71+ " NoArgs" ,
72+ " Missing Arguments" ,
73+ null ,
74+ )
75+ val clip: ClipData ? = null
76+ for (i in args) {
77+ val uri = Uri .parse(i)
78+ clip ? : ClipData .newUri(cr, " files" , uri)
79+ clip?.addItem(ClipData .Item (uri))
80+ }
81+ clip?.let {
82+ manager.setPrimaryClip(it)
83+ }
84+ result.success(null )
85+ }
86+
87+ " writeImage" -> {
88+ val image = call.arguments<ByteArray >() ? : return result.error(
89+ " NoArgs" ,
90+ " Missing Arguments" ,
91+ null ,
92+ )
93+
94+ val name = UUID .randomUUID().toString() + " .png"
95+ val file = File (context.cacheDir, name)
96+
97+ executor.execute {
98+ try {
99+ val bitmap = BitmapFactory .decodeByteArray(image, 0 , image.size)
100+ val out = ByteArrayOutputStream ()
101+ bitmap.compress(Bitmap .CompressFormat .PNG , 100 , out )
102+
103+ FileOutputStream (file).use {
104+ out .writeTo(it)
105+ }
106+
107+ val uri = FileProvider .getUriForFile(
108+ context, " ${context.packageName} .provider" , file
109+ )
110+ val clip = ClipData .newUri(cr, " image.png" , uri)
111+ manager.setPrimaryClip(clip)
112+ result.success(null )
113+ } catch (e: Exception ) {
114+ result.error(" Error" , " Failed to write image" , e.message)
115+ }
116+ }
117+ }
118+
119+ else -> result.notImplemented()
99120 }
100- val uri = FileProvider .getUriForFile(context, " ${context.packageName} .provider" , file)
101- val clip = ClipData .newUri(cr, " image.png" , uri)
102- manager.setPrimaryClip(clip)
103- }
104- else -> result.notImplemented()
105121 }
106- }
107122
108- override fun onDetachedFromEngine (binding : FlutterPlugin .FlutterPluginBinding ) {
109- channel.setMethodCallHandler(null )
110- }
123+ override fun onDetachedFromEngine (binding : FlutterPlugin .FlutterPluginBinding ) {
124+ channel.setMethodCallHandler(null )
125+ }
111126}
0 commit comments