একটি বিজ্ঞপ্তি তৈরি করুন

আপনার অ্যাপটি যখন ব্যবহৃত হচ্ছে না, তখন নোটিফিকেশন এর ভেতরের ঘটনা সম্পর্কে সংক্ষিপ্ত ও সময়োপযোগী তথ্য প্রদান করে। এই ডকুমেন্টটিতে বিভিন্ন বৈশিষ্ট্যসহ একটি নোটিফিকেশন তৈরি করার পদ্ধতি দেখানো হয়েছে। অ্যান্ড্রয়েডে নোটিফিকেশন কীভাবে প্রদর্শিত হয়, সে সম্পর্কে প্রাথমিক ধারণা পেতে ‘নোটিফিকেশন ওভারভিউ’ দেখুন। নোটিফিকেশন ব্যবহার করে এমন নমুনা কোডের জন্য, গিটহাবে থাকা ‘সোশ্যালাইট’ নমুনাটি দেখুন।

এই পৃষ্ঠার কোডটি AndroidX লাইব্রেরির NotificationCompat API ব্যবহার করে। এই API-গুলো আপনাকে অ্যান্ড্রয়েডের নতুন সংস্করণগুলিতে উপলব্ধ বৈশিষ্ট্যগুলি যুক্ত করার সুযোগ দেয়, এবং একই সাথে অ্যান্ড্রয়েড ৯ (API লেভেল ২৮) পর্যন্ত সামঞ্জস্যতা বজায় রাখে। তবে, ইনলাইন রিপ্লাই অ্যাকশনের মতো কিছু বৈশিষ্ট্য পূর্ববর্তী সংস্করণগুলিতে কাজ করে না।

একটি প্রাথমিক বিজ্ঞপ্তি তৈরি করুন

একটি নোটিফিকেশন তার সবচেয়ে মৌলিক এবং সংক্ষিপ্ত রূপে—যা সংকুচিত রূপ নামেও পরিচিত—একটি আইকন, একটি শিরোনাম এবং অল্প পরিমাণ টেক্সট প্রদর্শন করে। এই বিভাগে দেখানো হয়েছে কীভাবে এমন একটি নোটিফিকেশন তৈরি করতে হয়, যেটিতে ট্যাপ করে ব্যবহারকারী আপনার অ্যাপের কোনো অ্যাক্টিভিটি চালু করতে পারবেন।

চিত্র ১. একটি আইকন, একটি শিরোনাম এবং কিছু লেখা সহ একটি নোটিফিকেশন।

নোটিফিকেশনের প্রতিটি অংশ সম্পর্কে আরও বিস্তারিত জানতে, নোটিফিকেশনের গঠনতন্ত্র সম্পর্কে পড়ুন।

রানটাইম অনুমতি ঘোষণা করুন

অ্যান্ড্রয়েড ১৩ (এপিআই লেভেল ৩৩) এবং এর পরবর্তী সংস্করণগুলো কোনো অ্যাপ থেকে নন-এক্সেম্পট (ফোরগ্রাউন্ড সার্ভিসেস (এফজিএস) সহ) নোটিফিকেশন পোস্ট করার জন্য একটি রানটাইম পারমিশন সমর্থন করে।

আপনার অ্যাপের ম্যানিফেস্ট ফাইলে যে পারমিশনটি ঘোষণা করতে হবে, তা নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:

<manifest ...>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application ...>
        ...
    </application>
</manifest>

রানটাইম পারমিশন সম্পর্কে আরও বিস্তারিত জানতে, নোটিফিকেশন রানটাইম পারমিশন দেখুন।

বিজ্ঞপ্তির বিষয়বস্তু সেট করুন

শুরু করার জন্য, একটি NotificationCompat.Builder অবজেক্ট ব্যবহার করে নোটিফিকেশনের বিষয়বস্তু এবং চ্যানেল সেট করুন। নিম্নলিখিত উদাহরণটি দেখায় কিভাবে নিম্নলিখিত বিষয়গুলো ব্যবহার করে একটি নোটিফিকেশন তৈরি করতে হয়:

  • setSmallIcon() দ্বারা সেট করা একটি ছোট আইকন। এটিই একমাত্র আবশ্যক ব্যবহারকারী-দৃশ্যমান বিষয়বস্তু।

  • একটি শিরোনাম, যা setContentTitle() দ্বারা সেট করা হয়।

  • setContentText() দ্বারা নির্ধারিত মূল লেখা।

  • setPriority() মাধ্যমে নোটিফিকেশনের প্রায়োরিটি নির্ধারণ করা হয়। অ্যান্ড্রয়েড ৭.১ এবং তার পূর্ববর্তী সংস্করণগুলোতে এই প্রায়োরিটিই নির্ধারণ করে যে নোটিফিকেশনটি কতটা বিরক্তিকর হবে। অ্যান্ড্রয়েড ৮.০ এবং তার পরবর্তী সংস্করণগুলোর জন্য, এর পরিবর্তে পরবর্তী বিভাগে দেখানো পদ্ধতি অনুযায়ী চ্যানেলের গুরুত্ব (channel importance) সেট করুন।

কোটলিন

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

জাভা

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

NotificationCompat.Builder কনস্ট্রাক্টরে আপনাকে একটি চ্যানেল আইডি প্রদান করতে হবে। অ্যান্ড্রয়েড ৮.০ (এপিআই লেভেল ২৬) এবং তার পরবর্তী সংস্করণগুলোর সাথে সামঞ্জস্যের জন্য এটি প্রয়োজন, কিন্তু এর আগের সংস্করণগুলোতে এটি উপেক্ষা করা হয়।

ডিফল্টরূপে, নোটিফিকেশনের টেক্সট এক লাইনে ধরানোর জন্য সংক্ষিপ্ত করা হয়। একটি এক্সপ্যান্ডেবল নোটিফিকেশন তৈরি করে আপনি অতিরিক্ত তথ্য দেখাতে পারেন।

চিত্র ২. একটি প্রসারণযোগ্য নোটিফিকেশনের সংকুচিত এবং প্রসারিত রূপ।

আপনি যদি আপনার নোটিফিকেশনটি আরও দীর্ঘ করতে চান, তাহলে setStyle() ব্যবহার করে একটি স্টাইল টেমপ্লেট যোগ করে এক্সপ্যান্ডেবল নোটিফিকেশন সক্রিয় করতে পারেন। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি একটি বৃহত্তর টেক্সট এরিয়া তৈরি করে:

কোটলিন

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        <b>.setStyle(NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))</b>
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

জাভা

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        <b>.setStyle(new NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))</b>
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

ছবি যোগ করার পদ্ধতি এবং মিডিয়া প্লেব্যাক কন্ট্রোল সহ অন্যান্য বড় নোটিফিকেশন স্টাইল সম্পর্কে আরও তথ্যের জন্য, ‘একটি প্রসারণযোগ্য নোটিফিকেশন তৈরি করুন’ দেখুন।

একটি চ্যানেল তৈরি করুন এবং গুরুত্ব নির্ধারণ করুন।

Android 8.0 এবং তার পরবর্তী সংস্করণগুলিতে নোটিফিকেশন পাঠানোর আগে, createNotificationChannel() ফাংশনে NotificationChannel এর একটি ইনস্ট্যান্স পাস করে আপনার অ্যাপের নোটিফিকেশন চ্যানেলটি সিস্টেমের সাথে রেজিস্টার করুন। নিম্নলিখিত কোডটি SDK_INT ভার্সনের একটি শর্ত দ্বারা ব্লক করা আছে:

কোটলিন

private fun createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = getString(R.string.channel_name)
        val descriptionText = getString(R.string.channel_description)
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        // Register the channel with the system.
        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

জাভা

private void createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this.
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

যেহেতু অ্যান্ড্রয়েড ৮.০ এবং তার পরবর্তী সংস্করণগুলিতে যেকোনো নোটিফিকেশন পোস্ট করার আগে আপনাকে অবশ্যই নোটিফিকেশন চ্যানেল তৈরি করতে হবে, তাই আপনার অ্যাপ চালু হওয়ার সাথে সাথেই এই কোডটি চালান। এটি বারবার কল করা নিরাপদ, কারণ একটি বিদ্যমান নোটিফিকেশন চ্যানেল তৈরি করলে কোনো অপারেশন সম্পন্ন হয় না।

NotificationChannel কনস্ট্রাক্টরের জন্য একটি ইম্পরটেন্স ( importance প্রয়োজন হয়, যা NotificationManager ক্লাসের কনস্ট্যান্টগুলোর মধ্যে একটি ব্যবহার করে নির্ধারণ করা হয়। এই প্যারামিটারটি নির্ধারণ করে যে এই চ্যানেলের অন্তর্গত যেকোনো নোটিফিকেশনের জন্য ব্যবহারকারীকে কীভাবে বাধা দেওয়া হবে। পূর্ববর্তী উদাহরণে দেখানো অনুযায়ী, Android 7.1 এবং তার পূর্ববর্তী সংস্করণগুলোকে সাপোর্ট করার জন্য setPriority() ব্যবহার করে প্রায়োরিটি সেট করুন।

যদিও আপনাকে নিম্নলিখিত উদাহরণে দেখানো অনুযায়ী নোটিফিকেশনের গুরুত্ব বা অগ্রাধিকার নির্ধারণ করতে হবে, সিস্টেম আপনার প্রাপ্ত অ্যালার্ট আচরণের কোনো নিশ্চয়তা দেয় না। কিছু ক্ষেত্রে, সিস্টেম অন্যান্য কারণের উপর ভিত্তি করে গুরুত্বের স্তর পরিবর্তন করতে পারে, এবং ব্যবহারকারী সর্বদা একটি নির্দিষ্ট চ্যানেলের জন্য গুরুত্বের স্তর পুনরায় নির্ধারণ করতে পারেন।

বিভিন্ন স্তরের অর্থ কী, সে সম্পর্কে আরও তথ্যের জন্য, নোটিফিকেশনের গুরুত্বের স্তরগুলো সম্পর্কে পড়ুন।

নোটিফিকেশনের ট্যাপ অ্যাকশন সেট করুন

প্রতিটি নোটিফিকেশনে ট্যাপ করলে সাধারণত আপনার অ্যাপের সেই নোটিফিকেশন-সম্পর্কিত অ্যাক্টিভিটিটি খোলে। এটি করার জন্য, একটি PendingIntent অবজেক্ট দিয়ে সংজ্ঞায়িত একটি কন্টেন্ট ইন্টেন্ট নির্দিষ্ট করুন এবং সেটি setContentIntent() ফাংশনে পাস করুন।

নিচের কোড স্নিপেটটিতে দেখানো হয়েছে, ব্যবহারকারী নোটিফিকেশনে ট্যাপ করলে কীভাবে একটি অ্যাক্টিভিটি খোলার জন্য একটি বেসিক ইন্টেন্ট তৈরি করতে হয়:

কোটলিন

// Create an explicit intent for an Activity in your app.
<b>val intent = Intent(this, AlertDetails::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}</b>
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        <b>.setContentIntent(pendingIntent)</b>
        .setAutoCancel(true)

জাভা

// Create an explicit intent for an Activity in your app.
<b>Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);</b>
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        <b>.setContentIntent(pendingIntent)</b>
        .setAutoCancel(true);

এই কোডটি setAutoCancel() কল করে, যা ব্যবহারকারী ট্যাপ করলে নোটিফিকেশনটি স্বয়ংক্রিয়ভাবে সরিয়ে দেয়

পূর্ববর্তী উদাহরণে থাকা ইন্টেন্ট ফ্ল্যাগগুলো, ব্যবহারকারী নোটিফিকেশন ব্যবহার করে আপনার অ্যাপটি খোলার পরেও তার প্রত্যাশিত নেভিগেশন অভিজ্ঞতা বজায় রাখে। আপনি যে ধরনের অ্যাক্টিভিটি শুরু করছেন, তার উপর নির্ভর করে এটি ব্যবহার করতে পারেন, যা নিম্নলিখিতগুলোর মধ্যে একটি হতে পারে:

  • এমন একটি অ্যাক্টিভিটি যা শুধুমাত্র নোটিফিকেশনের প্রতিক্রিয়া জানানোর জন্য বিদ্যমান। সাধারণ অ্যাপ ব্যবহারের সময় ব্যবহারকারীর এই অ্যাক্টিভিটিতে যাওয়ার কোনো কারণ নেই, তাই অ্যাক্টিভিটিটি আপনার অ্যাপের বিদ্যমান টাস্ক এবং ব্যাক স্ট্যাকে যুক্ত না হয়ে একটি নতুন টাস্ক শুরু করে। পূর্ববর্তী স্যাম্পলে এই ধরনের ইন্টেন্টই তৈরি করা হয়েছিল।

  • একটি অ্যাক্টিভিটি যা আপনার অ্যাপের নিয়মিত কার্যপ্রবাহের অংশ। এক্ষেত্রে, অ্যাক্টিভিটিটি শুরু করলে একটি ব্যাক স্ট্যাক তৈরি হয়, যাতে ব্যাক এবং আপ বাটনগুলোর প্রতি ব্যবহারকারীর প্রত্যাশা বজায় থাকে।

আপনার নোটিফিকেশনের ইন্টেন্ট কনফিগার করার বিভিন্ন উপায় সম্পর্কে আরও জানতে, ‘স্টার্ট অ্যান অ্যাক্টিভিটি ফ্রম এ নোটিফিকেশন’ দেখুন।

বিজ্ঞপ্তি দেখান

নোটিফিকেশনটি প্রদর্শিত করার জন্য, NotificationManagerCompat.notify() কল করুন এবং এর সাথে নোটিফিকেশনের জন্য একটি অনন্য আইডি ও NotificationCompat.Builder.build() -এর ফলাফল পাস করুন। নিচের উদাহরণে এটি দেখানো হয়েছে:

কোটলিন

with(NotificationManagerCompat.from(this)) {
    if (ActivityCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.POST_NOTIFICATIONS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // TODO: Consider calling
        // ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        // public fun onRequestPermissionsResult(requestCode: Int, permissions: Array&lt;out String&gt;,
        //                                        grantResults: IntArray)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.

        return@with
    }
    // notificationId is a unique int for each notification that you must define.
    notify(NOTIFICATION_ID, builder.build())
}

জাভা

if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
    // TODO: Consider calling
    // ActivityCompat#requestPermissions
    // here to request the missing permissions, and then overriding
    // public void onRequestPermissionsResult(int requestCode, String[] permissions,
    //                                        int[] grantResults)
    // to handle the case where the user grants the permission. See the documentation
    // for ActivityCompat#requestPermissions for more details.
    return;
}
NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, builder.build());

NotificationManagerCompat.notify() -তে যে নোটিফিকেশন আইডিটি দেন, সেটি সংরক্ষণ করুন, কারণ নোটিফিকেশনটি আপডেট বা অপসারণ করার সময় আপনার এটি প্রয়োজন হবে।

এছাড়াও, অ্যান্ড্রয়েড ১৩ এবং তার পরবর্তী সংস্করণে চালিত ডিভাইসগুলিতে সাধারণ নোটিফিকেশন পরীক্ষা করার জন্য, ম্যানুয়ালি নোটিফিকেশন চালু করুন অথবা নোটিফিকেশনের অনুরোধ জানাতে একটি ডায়ালগ তৈরি করুন।

অ্যাকশন বাটন যোগ করুন

একটি নোটিফিকেশনে সর্বোচ্চ তিনটি অ্যাকশন বাটন থাকতে পারে, যা ব্যবহারকারীকে দ্রুত প্রতিক্রিয়া জানাতে সাহায্য করে, যেমন রিমাইন্ডার স্নুজ করা বা টেক্সট মেসেজের উত্তর দেওয়া। কিন্তু এই অ্যাকশন বাটনগুলো অবশ্যই সেই কাজটি পুনরাবৃত্তি করবে না, যা ব্যবহারকারী নোটিফিকেশনটিতে ট্যাপ করলে সম্পন্ন হয়।

চিত্র ৩. একটি অ্যাকশন বাটনসহ নোটিফিকেশন।

একটি অ্যাকশন বাটন যোগ করতে, addAction() মেথডে একটি PendingIntent পাস করুন। এটি নোটিফিকেশনের ডিফল্ট ট্যাপ অ্যাকশন সেট আপ করার মতোই, তবে অ্যাক্টিভিটি চালু করার পরিবর্তে আপনি অন্যান্য কাজ করতে পারেন, যেমন একটি BroadcastReceiver শুরু করা যা ব্যাকগ্রাউন্ডে কোনো কাজ সম্পাদন করে, যাতে অ্যাকশনটি আগে থেকে খোলা অ্যাপটিতে বাধা সৃষ্টি না করে।

উদাহরণস্বরূপ, নিম্নলিখিত কোডটি দেখায় কিভাবে একজন নির্দিষ্ট রিসিভারের কাছে একটি ব্রডকাস্ট পাঠাতে হয়:

কোটলিন

val ACTION_SNOOZE = "snooze"

<b>val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply {
    action = ACTION_SNOOZE
    putExtra(EXTRA_NOTIFICATION_ID, 0)
}
val snoozePendingIntent: PendingIntent =
    PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)</b>
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        <b>.addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent)</b>

জাভা

String ACTION_SNOOZE = "snooze"

<b>Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);</b>

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        <b>.addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);</b>

ব্যাকগ্রাউন্ডে কাজ চালানোর জন্য একটি BroadcastReceiver তৈরি করার বিষয়ে আরও তথ্যের জন্য, ব্রডকাস্ট ওভারভিউ দেখুন।

এর পরিবর্তে আপনি যদি মিডিয়া প্লেব্যাক বাটন, যেমন ট্র্যাক পজ করা বা স্কিপ করার বাটনসহ কোনো নোটিফিকেশন তৈরি করতে চান, তাহলে মিডিয়া কন্ট্রোলসহ নোটিফিকেশন কীভাবে তৈরি করতে হয় তা দেখুন।

সরাসরি উত্তর দেওয়ার একটি অ্যাকশন যোগ করুন

অ্যান্ড্রয়েড ৭.০ (এপিআই লেভেল ২৪)-এ চালু হওয়া ডাইরেক্ট রিপ্লাই অ্যাকশন ব্যবহারকারীদের সরাসরি নোটিফিকেশনে টেক্সট লেখার সুযোগ দেয়। এরপর কোনো অ্যাক্টিভিটি না খুলেই সেই টেক্সট আপনার অ্যাপে পৌঁছে যায়। উদাহরণস্বরূপ, আপনি ডাইরেক্ট রিপ্লাই অ্যাকশন ব্যবহার করে ব্যবহারকারীদের নোটিফিকেশনের ভেতর থেকেই টেক্সট মেসেজের উত্তর দিতে বা টাস্ক লিস্ট আপডেট করতে দিতে পারেন।

চিত্র ৪। 'Reply' বাটনে ট্যাপ করলে টেক্সট ইনপুট খুলে যায়।

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

উত্তর বোতাম যোগ করুন

সরাসরি উত্তর সমর্থন করে এমন একটি নোটিফিকেশন অ্যাকশন তৈরি করতে, এই ধাপগুলো অনুসরণ করুন:

  1. RemoteInput.Builder এর একটি ইনস্ট্যান্স তৈরি করুন যা আপনি আপনার নোটিফিকেশন অ্যাকশনে যোগ করতে পারেন। এই ক্লাসের কনস্ট্রাক্টর একটি স্ট্রিং গ্রহণ করে যা সিস্টেম টেক্সট ইনপুটের জন্য কী (key) হিসেবে ব্যবহার করে। আপনার অ্যাপ পরে সেই কী ব্যবহার করে ইনপুটের টেক্সট পুনরুদ্ধার করে। * {কোটলিন} ```kotlin // অ্যাকশনের ইন্টেন্টে পাঠানো স্ট্রিং-এর জন্য কী। private val KEY_TEXT_REPLY = "key_text_reply" var replyLabel: String = resources.getString(R.string.reply_label) var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run { setLabel(replyLabel) build() } ``` * {জাভা} ```java // অ্যাকশনের ইন্টেন্টে পাঠানো স্ট্রিং-এর জন্য কী। private static final String KEY_TEXT_REPLY = "key_text_reply"; String replyLabel = getResources().getString(R.string.reply_label); RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY) .setLabel(replyLabel) .build(); ```
  2. রিপ্লাই অ্যাকশনের জন্য একটি PendingIntent তৈরি করুন। * {কোটলিন} ```kotlin // ট্রিগার করার জন্য রিপ্লাই অ্যাকশনের জন্য একটি PendingIntent তৈরি করুন। var replyPendingIntent: PendingIntent = PendingIntent.getBroadcast(applicationContext, conversation.getConversationId(), getMessageReplyIntent(conversation.getConversationId()), PendingIntent.FLAG_UPDATE_CURRENT) ``` * {জাভা} ```java // ট্রিগার করার জন্য রিপ্লাই অ্যাকশনের জন্য একটি PendingIntent তৈরি করুন। PendingIntent replyPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), conversation.getConversationId(), getMessageReplyIntent(conversation.getConversationId()), PendingIntent.FLAG_UPDATE_CURRENT); ```
  3. addRemoteInput() ব্যবহার করে RemoteInput অবজেক্টটিকে একটি অ্যাকশনের সাথে সংযুক্ত করুন। * {কোটলিন} ```কোটলিন // রিপ্লাই অ্যাকশন তৈরি করুন এবং রিমোট ইনপুট যোগ করুন। var action: NotificationCompat.Action = NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), replyPendingIntent) .addRemoteInput(remoteInput) .build() ``` * {জাভা} ```জাভা // রিপ্লাই অ্যাকশন তৈরি করুন এবং রিমোট ইনপুট যোগ করুন। NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), replyPendingIntent) .addRemoteInput(remoteInput) .build(); ```
  4. একটি নোটিফিকেশনে অ্যাকশনটি প্রয়োগ করুন এবং নোটিফিকেশনটি ইস্যু করুন। * {কোটলিন} ```কোটলিন // নোটিফিকেশনটি তৈরি করুন এবং অ্যাকশনটি যোগ করুন। val newMessageNotification = Notification.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentTitle(getString(R.string.title)) .setContentText(getString(R.string.content)) .addAction(action) .build() // নোটিফিকেশনটি ইস্যু করুন। with(NotificationManagerCompat.from(this)) { notificationManager.notify(notificationId, newMessageNotification) } ``` * {জাভা} ```জাভা // নোটিফিকেশনটি তৈরি করুন এবং অ্যাকশনটি যোগ করুন। `Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentTitle(getString(R.string.title)) .setContentText(getString(R.string.content)) .addAction(action) .build(); // নোটিফিকেশনটি ইস্যু করুন। NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, newMessageNotification);` ```

চিত্র ৪-এ দেখানো অনুযায়ী, ব্যবহারকারী যখন নোটিফিকেশন অ্যাকশনটি চালু করেন, তখন সিস্টেমটি তাকে একটি প্রতিক্রিয়া ইনপুট করতে অনুরোধ করে।

উত্তর থেকে ব্যবহারকারীর ইনপুট পুনরুদ্ধার করুন

নোটিফিকেশনের রিপ্লাই UI থেকে ব্যবহারকারীর ইনপুট গ্রহণ করতে, আপনার BroadcastReceiver দ্বারা প্রাপ্ত Intent পাস করে RemoteInput.getResultsFromIntent() কল করুন:

কোটলিন

private fun getMessageText(intent: Intent): CharSequence? {
    return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY_TEXT_REPLY)
}

জাভা

private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }

টেক্সটটি প্রসেস করার পর, একই আইডি এবং ট্যাগ (যদি ব্যবহৃত হয়ে থাকে) ব্যবহার করে NotificationManagerCompat.notify() কল করে নোটিফিকেশনটি আপডেট করুন। সরাসরি উত্তর দেওয়ার UI লুকানোর জন্য এবং ব্যবহারকারীকে নিশ্চিত করার জন্য এটি করা প্রয়োজন যে তার উত্তরটি গৃহীত ও সঠিকভাবে প্রসেস করা হয়েছে।

কোটলিন

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
val repliedNotification = Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build()

// Issue the new notification.
NotificationManagerCompat.from(this).apply {
    notificationManager.notify(notificationId, repliedNotification)
}

জাভা

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build();

// Issue the new notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, repliedNotification);

অন্যান্য ডেটা পুনরুদ্ধার করুন

RemoteInput ব্যবহার করে অন্যান্য ডেটা টাইপও একইভাবে পরিচালনা করা যায়। নিচের উদাহরণটিতে ইনপুট হিসেবে ছবি ব্যবহার করা হয়েছে।

কোটলিন

  // Key for the data that's delivered in the action's intent.
  private val KEY_REPLY = "key_reply"
  var replyLabel: String = resources.getString(R.string.reply_label)
  var remoteInput: RemoteInput = RemoteInput.Builder(KEY_REPLY).run {
      setLabel(replyLabel)
      // Allow for image data types in the input
  // This method can be used again to
  // allow for other data types
      setAllowDataType("image/*", true)
      build()
}

RemoteInput#getDataResultsFromIntent কল করুন এবং সংশ্লিষ্ট ডেটা বের করে নিন।

কোটলিন

  import android.app.RemoteInput;
  import android.content.Intent;
  import android.os.Bundle;

  class ReplyReceiver: BroadcastReceiver()  {

      public static final String KEY_DATA = "key_data";

      public static void handleRemoteInput(Intent intent) {
          Bundle dataResults = RemoteInput.getDataResultsFromIntent(intent, KEY_DATA);
          val imageUri: Uri? = dataResults.values.firstOrNull()
          if (imageUri != null) {
              // Extract the image
          try {
                  val inputStream = context.contentResolver.openInputStream(imageUri)
                  val bitmap = BitmapFactory.decodeStream(inputStream)
                  // Display the image
                  // ...
              } catch (e: Exception) {
                  Log.e("ReplyReceiver", "Failed to process image URI", e)
              }
      }
  }

এই নতুন নোটিফিকেশনটি নিয়ে কাজ করার সময়, রিসিভারের onReceive() মেথডে পাস করা কনটেক্সটটি ব্যবহার করুন।

setRemoteInputHistory() কল করে নোটিফিকেশনের শেষে উত্তরটি যুক্ত করুন। তবে, যদি আপনি একটি মেসেজিং অ্যাপ তৈরি করেন, তাহলে একটি মেসেজিং-স্টাইলের নোটিফিকেশন তৈরি করুন এবং নতুন বার্তাটি কথোপকথনে যুক্ত করুন।

মেসেজিং অ্যাপের নোটিফিকেশন সংক্রান্ত আরও পরামর্শের জন্য, মেসেজিং অ্যাপের সেরা অনুশীলন সম্পর্কিত বিভাগটি দেখুন।

একটি জরুরি বার্তা দেখান

আপনার অ্যাপে কোনো জরুরি ও সময়-সংবেদনশীল বার্তা, যেমন আগত ফোন কল বা বেজে ওঠা অ্যালার্ম, প্রদর্শন করার প্রয়োজন হতে পারে। এই ধরনের পরিস্থিতিতে, আপনি আপনার নোটিফিকেশনের সাথে একটি ফুল-স্ক্রিন ইন্টেন্ট যুক্ত করতে পারেন।

নোটিফিকেশনটি চালু হলে, ডিভাইসের লক স্ট্যাটাসের ওপর নির্ভর করে ব্যবহারকারীরা নিম্নলিখিতগুলির মধ্যে একটি দেখতে পান:

  • ব্যবহারকারীর ডিভাইসটি লক করা থাকলে, একটি পূর্ণ-স্ক্রিন অ্যাক্টিভিটি প্রদর্শিত হয়, যা লকস্ক্রিনটিকে ঢেকে দেয়।
  • ব্যবহারকারীর ডিভাইসটি আনলক করা থাকলে, নোটিফিকেশনটি বিস্তারিত আকারে প্রদর্শিত হয়, যেখানে নোটিফিকেশনটি গ্রহণ বা বাতিল করার বিকল্প থাকে।

নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে আপনার নোটিফিকেশনকে একটি ফুল-স্ক্রিন ইন্টেন্টের সাথে যুক্ত করতে হয়:

কোটলিন

val fullScreenIntent = Intent(this, ImportantActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
    fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        <b>.setFullScreenIntent(fullScreenPendingIntent, true)</b>

জাভা

Intent fullScreenIntent = new Intent(this, ImportantActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        <b>.setFullScreenIntent(fullScreenPendingIntent, true);</b>

লক স্ক্রিনের দৃশ্যমানতা সেট করুন

লক স্ক্রিন থেকে নোটিফিকেশনে দৃশ্যমান বিবরণের মাত্রা নিয়ন্ত্রণ করতে, setVisibility() ফাংশনটি কল করুন এবং নিম্নলিখিত মানগুলির মধ্যে একটি নির্দিষ্ট করুন:

  • VISIBILITY_PUBLIC : নোটিফিকেশনের সম্পূর্ণ বিষয়বস্তু লক স্ক্রিনে দেখা যায়।

  • VISIBILITY_SECRET : নোটিফিকেশনের কোনো অংশই লক স্ক্রিনে দেখা যায় না।

  • VISIBILITY_PRIVATE : লক স্ক্রিনে শুধুমাত্র মৌলিক তথ্য, যেমন নোটিফিকেশনের আইকন এবং বিষয়বস্তুর শিরোনাম, দেখা যায়। নোটিফিকেশনের সম্পূর্ণ বিষয়বস্তু দেখানো হয় না।

যখন আপনি VISIBILITY_PRIVATE সেট করেন, তখন আপনি নোটিফিকেশন কন্টেন্টের একটি বিকল্প সংস্করণও প্রদান করতে পারেন যা নির্দিষ্ট কিছু বিবরণ গোপন রাখে। উদাহরণস্বরূপ, একটি এসএমএস অ্যাপ এমন একটি নোটিফিকেশন প্রদর্শন করতে পারে যেখানে লেখা থাকবে "আপনার ৩টি নতুন টেক্সট মেসেজ এসেছে," কিন্তু মেসেজের বিষয়বস্তু এবং প্রেরকদের পরিচয় গোপন থাকবে। এই বিকল্প নোটিফিকেশনটি প্রদান করার জন্য, প্রথমে NotificationCompat.Builder ব্যবহার করে যথারীতি বিকল্প নোটিফিকেশনটি তৈরি করুন। তারপর, setPublicVersion() ব্যবহার করে বিকল্প নোটিফিকেশনটিকে সাধারণ নোটিফিকেশনের সাথে সংযুক্ত করুন।

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

একটি বিজ্ঞপ্তি আপডেট করুন

একবার কোনো নোটিফিকেশন জারি করার পর তা আপডেট করতে, পূর্বে ব্যবহৃত একই আইডিটি পাস করে NotificationManagerCompat.notify() আবার কল করুন। যদি পূর্ববর্তী নোটিফিকেশনটি ডিসমিস করা হয়, তবে তার পরিবর্তে একটি নতুন নোটিফিকেশন তৈরি হবে।

আপনি চাইলে setOnlyAlertOnce() কল করতে পারেন, যাতে আপনার নোটিফিকেশনটি শুধুমাত্র প্রথমবার প্রদর্শিত হওয়ার সময় শব্দ, কম্পন বা দৃশ্যমান সংকেতের মাধ্যমে ব্যবহারকারীকে বাধা দেয় এবং পরবর্তী আপডেটগুলোর ক্ষেত্রে তা না করে।

একটি বিজ্ঞপ্তি সরান

নিম্নলিখিত ঘটনাগুলোর মধ্যে কোনো একটি না ঘটা পর্যন্ত নোটিফিকেশনগুলো দৃশ্যমান থাকে:

  • ব্যবহারকারী নোটিফিকেশনটি খারিজ করে দেন।
  • নোটিফিকেশন তৈরি করার সময় আপনি যদি setAutoCancel() কল করেন, তাহলে ব্যবহারকারী নোটিফিকেশনটিতে ট্যাপ করে।
  • আপনি একটি নির্দিষ্ট নোটিফিকেশন আইডির জন্য cancel() মেথডটি কল করেন। এই মেথডটি চলমান নোটিফিকেশনগুলোও মুছে দেয়।
  • আপনি cancelAll() কল করলে, আপনার পূর্বে জারি করা সমস্ত নোটিফিকেশন মুছে যায়।
  • নোটিফিকেশন তৈরি করার সময় setTimeoutAfter() ব্যবহার করে টাইমআউট সেট করলে, নির্দিষ্ট সময়কাল অতিবাহিত হয়। প্রয়োজন হলে, নির্দিষ্ট টাইমআউটের সময়কাল শেষ হওয়ার আগেই আপনি নোটিফিকেশনটি বাতিল করতে পারেন।

মেসেজিং অ্যাপের জন্য সর্বোত্তম অনুশীলন

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

মেসেজিংস্টাইল ব্যবহার করুন

অ্যান্ড্রয়েড ৭.০ (এপিআই লেভেল ২৪) থেকে, অ্যান্ড্রয়েড বিশেষভাবে মেসেজিং কন্টেন্টের জন্য একটি নোটিফিকেশন স্টাইল টেমপ্লেট প্রদান করে। NotificationCompat.MessagingStyle ক্লাসটি ব্যবহার করে, আপনি নোটিফিকেশনে প্রদর্শিত বিভিন্ন লেবেল পরিবর্তন করতে পারেন, যার মধ্যে রয়েছে কথোপকথনের শিরোনাম, অতিরিক্ত মেসেজ এবং নোটিফিকেশনের কন্টেন্ট ভিউ।

নিম্নলিখিত কোড স্নিপেটটিতে দেখানো হয়েছে কিভাবে MessagingStyle ক্লাস ব্যবহার করে একটি নোটিফিকেশনের স্টাইল কাস্টমাইজ করা যায়।

কোটলিন

val user = Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build()

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with $sender")
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build()

জাভা

Person user = new Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build();

Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with " + sender)
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(new NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build();

অ্যান্ড্রয়েড ৯.০ (এপিআই লেভেল ২৮) থেকে, নোটিফিকেশন এবং এর অ্যাভাটারগুলোর সর্বোত্তম রেন্ডারিং পাওয়ার জন্য Person ক্লাসটি ব্যবহার করাও আবশ্যক।

NotificationCompat.MessagingStyle ব্যবহার করার সময়, নিম্নলিখিতগুলি করুন:

  • দুইজনের বেশি সদস্যের গ্রুপ চ্যাটের জন্য একটি শিরোনাম সেট করতে MessagingStyle.setConversationTitle() কল করুন। একটি ভালো কথোপকথনের শিরোনাম হতে পারে গ্রুপ চ্যাটের নাম অথবা, যদি এর কোনো নাম না থাকে, তবে কথোপকথনে অংশগ্রহণকারীদের একটি তালিকা। এটি ছাড়া, বার্তাটিকে কথোপকথনের সর্বশেষ বার্তা প্রেরকের সাথে একটি এক-এক কথোপকথনের অংশ বলে ভুল করা হতে পারে।
  • ছবির মতো মিডিয়া মেসেজ অন্তর্ভুক্ত করতে MessagingStyle.setData() মেথডটি ব্যবহার করুন। image/* প্যাটার্নের MIME টাইপগুলো সমর্থিত।

সরাসরি উত্তর ব্যবহার করুন

ডাইরেক্ট রিপ্লাই ব্যবহারকারীকে কোনো মেসেজের মধ্যেই উত্তর দেওয়ার সুযোগ দেয়।

  • ব্যবহারকারী ইনলাইন রিপ্লাই অ্যাকশনের মাধ্যমে উত্তর দেওয়ার পর, MessagingStyle নোটিফিকেশনটি আপডেট করতে MessagingStyle.addMessage() ব্যবহার করুন এবং নোটিফিকেশনটি প্রত্যাহার বা বাতিল করবেন না। নোটিফিকেশনটি বাতিল না করলে ব্যবহারকারী সেই নোটিফিকেশন থেকেই একাধিক উত্তর পাঠাতে পারেন।
  • ইনলাইন রিপ্লাই অ্যাকশনটিকে Wear OS-এর সাথে সামঞ্জস্যপূর্ণ করতে, Action.WearableExtender.setHintDisplayInlineAction(true) কল করুন।
  • নোটিফিকেশনে ঐতিহাসিক বার্তা যোগ করে সরাসরি উত্তর দেওয়ার কথোপকথনে প্রাসঙ্গিকতা যোগ করতে addHistoricMessage() পদ্ধতিটি ব্যবহার করুন।

স্মার্ট রিপ্লাই সক্রিয় করুন

  • স্মার্ট রিপ্লাই চালু করতে, রিপ্লাই অ্যাকশনে setAllowGeneratedResponses(true) কল করুন। এর ফলে, যখন নোটিফিকেশনটি একটি Wear OS ডিভাইসে ব্রিজ করা হয়, তখন ব্যবহারকারীরা স্মার্ট রিপ্লাই প্রতিক্রিয়াগুলো পেতে পারেন। স্মার্ট রিপ্লাই প্রতিক্রিয়াগুলো NotificationCompat.MessagingStyle নোটিফিকেশন দ্বারা প্রদত্ত কনটেক্সট ব্যবহার করে সম্পূর্ণভাবে একটি অন-ওয়াচ মেশিন লার্নিং মডেল দ্বারা তৈরি করা হয় এবং এই প্রতিক্রিয়াগুলো তৈরি করার জন্য কোনো ডেটা ইন্টারনেটে আপলোড করা হয় না।

বিজ্ঞপ্তি মেটাডেটা যোগ করুন

  • ডিভাইসটি Do Not Disturb mode থাকলে আপনার অ্যাপের নোটিফিকেশনগুলো কীভাবে পরিচালনা করতে হবে, তা সিস্টেমকে জানানোর জন্য নোটিফিকেশন মেটাডেটা নির্ধারণ করুন। উদাহরণস্বরূপ, ডু নট ডিস্টার্ব ওভাররাইড করতে addPerson() বা setCategory(Notification.CATEGORY_MESSAGE) মেথডটি ব্যবহার করুন।