কপি এবং পেস্ট করুন

কপি এবং পেস্ট করার জন্য অ্যান্ড্রয়েড ক্লিপবোর্ড-ভিত্তিক কাঠামো আদিম এবং জটিল ডেটা প্রকারগুলিকে সমর্থন করে, যার মধ্যে রয়েছে:

  • টেক্সট স্ট্রিং
  • জটিল ডেটা স্ট্রাকচার
  • পাঠ্য এবং বাইনারি স্ট্রিম ডেটা
  • আবেদন সম্পদ

সরল পাঠ্য ডেটা সরাসরি ক্লিপবোর্ডে সংরক্ষণ করা হয়, যখন জটিল ডেটা একটি রেফারেন্স হিসাবে সংরক্ষণ করা হয় যা পেস্টিং অ্যাপ্লিকেশন একটি বিষয়বস্তু প্রদানকারীর সাথে সমাধান করে।

অনুলিপি এবং আটকানো একটি অ্যাপ্লিকেশনের মধ্যে এবং ফ্রেমওয়ার্ক বাস্তবায়নকারী অ্যাপ্লিকেশনগুলির মধ্যে উভয়ই কাজ করে।

যেহেতু ফ্রেমওয়ার্কের একটি অংশ সামগ্রী প্রদানকারী ব্যবহার করে, এই নথিটি Android সামগ্রী প্রদানকারী API এর সাথে কিছু পরিচিতি অনুমান করে৷

টেক্সট দিয়ে কাজ করুন

কিছু উপাদান বক্সের বাইরে পাঠ্য অনুলিপি এবং আটকানো সমর্থন করে, যেমনটি নিম্নলিখিত টেবিলে দেখানো হয়েছে।

কম্পোনেন্ট পাঠ্য অনুলিপি করা হচ্ছে পাঠ্য আটকানো হচ্ছে
বেসিক টেক্সটফিল্ড
টেক্সটফিল্ড
নির্বাচন কন্টেইনার

উদাহরণস্বরূপ, আপনি নিম্নলিখিত স্নিপেটে ক্লিপবোর্ডে কার্ডের পাঠ্যটি অনুলিপি করতে পারেন এবং অনুলিপি করা পাঠ্যটিকে TextField আটকাতে পারেন। আপনি TextField স্পর্শ করে ধরে রেখে বা কার্সার হ্যান্ডেল ট্যাপ করে টেক্সট পেস্ট করতে মেনু প্রদর্শন করেন।

val textFieldState = rememberTextFieldState()

Column {
    Card {
        SelectionContainer {
            Text("You can copy this text")
        }
    }
    BasicTextField(state = textFieldState)
}

আপনি নিম্নলিখিত কীবোর্ড শর্টকাট দিয়ে পাঠ্য পেস্ট করতে পারেন: Ctrl + V। কীবোর্ড শর্টকাট ডিফল্টরূপে উপলব্ধ। বিস্তারিত জানার জন্য হ্যান্ডেল কীবোর্ড অ্যাকশন পড়ুন।

ClipboardManager দিয়ে কপি করুন

আপনি ClipboardManager দিয়ে ক্লিপবোর্ডে পাঠ্য অনুলিপি করতে পারেন। এর setText() পদ্ধতি পাস করা স্ট্রিং অবজেক্টকে ক্লিপবোর্ডে কপি করে। ব্যবহারকারী বোতামে ক্লিক করলে নিম্নলিখিত স্নিপেটটি ক্লিপবোর্ডে "হ্যালো, ক্লিপবোর্ড" কপি করে।

// Retrieve a ClipboardManager object
val clipboardManager = LocalClipboardManager.current

Button(
    onClick = {
        // Copy "Hello, clipboard" to the clipboard
        clipboardManager.setText("Hello, clipboard")
    }
) {
   Text("Click to copy a text")
}

নিম্নলিখিত স্নিপেট একই জিনিস করে, কিন্তু আপনাকে আরও দানাদার নিয়ন্ত্রণ দেয়। একটি সাধারণ ব্যবহারের ক্ষেত্রে সংবেদনশীল বিষয়বস্তু অনুলিপি করা , যেমন পাসওয়ার্ড। ClipEntry ক্লিপবোর্ডে একটি আইটেম বর্ণনা করে। এটিতে একটি ClipData অবজেক্ট রয়েছে যা ক্লিপবোর্ডে ডেটা বর্ণনা করে। ClipData.newPlainText() পদ্ধতি হল একটি স্ট্রিং অবজেক্ট থেকে একটি ClipData অবজেক্ট তৈরি করার একটি সুবিধাজনক পদ্ধতি। আপনি ClipboardManager অবজেক্টের উপর setClip() মেথড কল করে ক্লিপবোর্ডে তৈরি করা ClipEntry অবজেক্ট সেট করতে পারেন।

// Retrieve a ClipboardManager object
val clipboardManager = LocalClipboardManager.current

Button(
    onClick = {
        val clipData = ClipData.newPlainText("plain text", "Hello, clipboard")
        val clipEntry = ClipEntry(clipData)
        clipboardManager.setClip(clipEntry)
    }
) {
   Text("Click to copy a text")
}

ClipboardManager দিয়ে পেস্ট করুন

আপনি ClipboardManager মাধ্যমে getText() পদ্ধতিতে কল করে ক্লিপবোর্ডে অনুলিপি করা পাঠ্যটি অ্যাক্সেস করতে পারেন। ক্লিপবোর্ডে একটি পাঠ্য অনুলিপি করা হলে এর getText() পদ্ধতি একটি AnnotatedString অবজেক্ট প্রদান করে। নিম্নলিখিত স্নিপেটটি ক্লিপবোর্ডের পাঠ্যকে TextField পাঠ্যের সাথে যুক্ত করে।

var textFieldState = rememberTextFieldState()

Column {
    TextField(state = textFieldState)

    Button(
        onClick = {
            // The getText method returns an AnnotatedString object or null
            val annotatedString = clipboardManager.getText()
            if(annotatedString != null) {
                // The pasted text is placed on the tail of the TextField
                textFieldState.edit {
                    append(text.toString())
                }
            }
        }
    ) {
        Text("Click to paste the text in the clipboard")
    }
}

সমৃদ্ধ বিষয়বস্তু সঙ্গে কাজ

ব্যবহারকারীরা ছবি, ভিডিও এবং অন্যান্য অভিব্যক্তিপূর্ণ বিষয়বস্তু পছন্দ করেন। আপনার অ্যাপ ব্যবহারকারীকে ClipboardManager এবং ClipEntry মাধ্যমে সমৃদ্ধ সামগ্রী কপি করতে সক্ষম করতে পারে। contentReceiver মডিফায়ার আপনাকে সমৃদ্ধ কন্টেন্ট পেস্ট করতে সাহায্য করে।

সমৃদ্ধ বিষয়বস্তু অনুলিপি

আপনার অ্যাপ সরাসরি ক্লিপবোর্ডে সমৃদ্ধ সামগ্রী কপি করতে পারে না। পরিবর্তে, আপনার অ্যাপ ক্লিপবোর্ডে একটি URI অবজেক্ট পাস করে এবং একটি ContentProvider মাধ্যমে সামগ্রীতে অ্যাক্সেস প্রদান করে। নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে একটি JPEG ছবি ক্লিপবোর্ডে অনুলিপি করতে হয়। বিস্তারিত জানার জন্য ডেটা স্ট্রীম অনুলিপি করুন।

// Get a reference to the context
val context = LocalContext.current

Button(
    onClick = {
        // URI of the copied JPEG data
        val uri = Uri.parse("content://your.app.authority/0.jpg")
        // Create a ClipData object from the URI value
        // A ContentResolver finds a proper ContentProvider so that ClipData.newUri can set appropriate MIME type to the given URI
        val clipData = ClipData.newUri(context.contentResolver, "Copied", uri)
        // Create a ClipEntry object from the clipData value
        val clipEntry = ClipEntry(clipData)
        // Copy the JPEG data to the clipboard
        clipboardManager.setClip(clipEntry)
    }
) {
    Text("Copy a JPEG data")
}

একটি সমৃদ্ধ সামগ্রী পেস্ট করুন

contentReceiver মডিফায়ারের সাহায্যে, আপনি পরিবর্তিত কম্পোনেন্টে BasicTextField সমৃদ্ধ বিষয়বস্তু পেস্ট করা পরিচালনা করতে পারেন। নিম্নলিখিত কোড স্নিপেট Uri অবজেক্টের একটি তালিকায় একটি চিত্র ডেটার পেস্ট করা URI যোগ করে।

// A URI list of images
val imageList by remember{ mutableListOf<Uri>() }

// Remember the ReceiveContentListener object as it is created inside a Composable scope
val receiveContentListener = remember {
    ReceiveContentListener { transferableContent ->
        // Handle the pasted data if it is image data
        when {
            // Check if the pasted data is an image or not
            transferableContent.hasMediaType(MediaType.Image)) -> {
                // Handle for each ClipData.Item object
                // The consume() method returns a new TransferableContent object containging ignored ClipData.Item objects
                transferableContent.consume { item ->
                    val uri = item.uri
                    if (uri != null) {
                        imageList.add(uri)
                    }
                   // Mark the ClipData.Item object consumed when the retrieved URI is not null
                    uri != null
                }
            }
            // Return the given transferableContent when the pasted data is not an image
            else -> transferableContent
        }
    }
}

val textFieldState = rememberTextFieldState()

BasicTextField(
    state = textFieldState,
    modifier = Modifier
        .contentReceiver(receiveContentListener)
        .fillMaxWidth()
        .height(48.dp)
)

contentReceiver মডিফায়ার একটি ReceiveContentListener অবজেক্টকে তার আর্গুমেন্ট হিসেবে নেয় এবং পাস করা অবজেক্টের onReceive পদ্ধতিতে কল করে যখন ব্যবহারকারী পরিবর্তিত কম্পোনেন্টের ভিতরে BasicTextField ডেটা পেস্ট করে।

একটি TransferableContent অবজেক্ট onReceive পদ্ধতিতে পাস করা হয়, যা এই ক্ষেত্রে পেস্ট করে অ্যাপগুলির মধ্যে স্থানান্তর করা যেতে পারে এমন ডেটা বর্ণনা করে। আপনি clipEntry বৈশিষ্ট্য উল্লেখ করে ClipEntry অবজেক্ট অ্যাক্সেস করতে পারেন।

একটি ClipEntry অবজেক্টে অনেকগুলি ClipData.Item অবজেক্ট থাকতে পারে যখন ব্যবহারকারী বেশ কয়েকটি ছবি নির্বাচন করে এবং উদাহরণ স্বরূপ ক্লিপবোর্ডে অনুলিপি করে। আপনার প্রতিটি ClipData.Item অবজেক্টের জন্য গ্রাস করা বা উপেক্ষা করা চিহ্নিত করা উচিত এবং উপেক্ষা করা ClipData.Item অবজেক্ট সমন্বিত একটি TransferableContent ফেরত দেওয়া উচিত যাতে নিকটতম পূর্বপুরুষ contentReceiver সংশোধক এটি গ্রহণ করতে পারে।

TransferableContent.hasMediaType() পদ্ধতি আপনাকে নির্ধারণ করতে সাহায্য করতে পারে যে TransferableContent বস্তুটি মিডিয়া টাইপের সাথে একটি আইটেম প্রদান করতে পারে কিনা। উদাহরণস্বরূপ, যদি TransferableContent অবজেক্ট একটি ইমেজ প্রদান করতে পারে তাহলে নিম্নোক্ত পদ্ধতি কলটি true হয়।

transferableContent.hasMediaType(MediaType.Image)

জটিল ডেটা নিয়ে কাজ করুন

আপনি সমৃদ্ধ বিষয়বস্তুর জন্য একই পদ্ধতিতে ক্লিপবোর্ডে জটিল ডেটা অনুলিপি করতে পারেন। বিশদ বিবরণের জন্য জটিল ডেটা অনুলিপি করতে সামগ্রী সরবরাহকারীদের ব্যবহার করুন দেখুন।

আপনি সমৃদ্ধ সামগ্রীর জন্য একই পদ্ধতিতে জটিল ডেটার পেস্টগুলি পরিচালনা করতে পারেন। আপনি পেস্ট করা ডেটার একটি URI পেতে পারেন। প্রকৃত তথ্য একটি ContentProvider থেকে পুনরুদ্ধার করা যেতে পারে। আরও তথ্যের জন্য প্রদানকারীর কাছ থেকে ডেটা পুনরুদ্ধার পড়ুন।

কন্টেন্ট অনুলিপি প্রতিক্রিয়া

ব্যবহারকারীরা যখন ক্লিপবোর্ডে বিষয়বস্তু অনুলিপি করে তখন প্রতিক্রিয়া আশা করে, তাই কপি এবং পেস্ট করার ক্ষমতা দেয় এমন কাঠামোর পাশাপাশি, Android 13 (API স্তর 33) এবং উচ্চতর কপি করার সময় Android তাদের একটি ডিফল্ট UI দেখায়। এই বৈশিষ্ট্যের কারণে, নকল বিজ্ঞপ্তির ঝুঁকি রয়েছে। আপনি ডুপ্লিকেট বিজ্ঞপ্তি এড়িয়ে এই প্রান্ত কেস সম্পর্কে আরও জানতে পারেন।

Android 13 ক্লিপবোর্ড বিজ্ঞপ্তি দেখানো একটি অ্যানিমেশন
চিত্র 1. অ্যান্ড্রয়েড 13 এবং তার উপরে ক্লিপবোর্ডে সামগ্রী প্রবেশ করলে UI দেখানো হয়।

Android 12L (API লেভেল 32) এবং তার নিচে কপি করার সময় ব্যবহারকারীদের ম্যানুয়ালি ফিডব্যাক প্রদান করুন। সুপারিশ দেখুন.

সংবেদনশীল বিষয়বস্তু

আপনি যদি আপনার অ্যাপটি ব্যবহারকারীকে ক্লিপবোর্ডে সংবেদনশীল বিষয়বস্তু কপি করতে দিতে চান, যেমন পাসওয়ার্ড, আপনার অ্যাপটিকে অবশ্যই সিস্টেমকে জানাতে হবে যাতে সিস্টেমটি UI-তে অনুলিপি করা সংবেদনশীল সামগ্রী প্রদর্শন করা এড়াতে পারে (চিত্র 2)।

সংবেদনশীল কন্টেন্ট ফ্ল্যাগিং টেক্সট প্রিভিউ কপি করা হয়েছে।
চিত্র 2. একটি সংবেদনশীল বিষয়বস্তুর পতাকা সহ অনুলিপি করা পাঠ্যের পূর্বরূপ৷

ClipboardManager অবজেক্টের উপর setClip() পদ্ধতিতে কল করার আগে আপনাকে ClipDataClipDescription এ একটি পতাকা যোগ করতে হবে:

// If your app is compiled with the API level 33 SDK or higher.
clipData.apply {
    description.extras = PersistableBundle().apply {
        putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true)
    }
}

// If your app is compiled with a lower SDK.
clipData.apply {
    description.extras = PersistableBundle().apply {
        putBoolean("android.content.extra.IS_SENSITIVE", true)
    }
}