অ্যাপ অ্যাকশনের সাথে Google অ্যাসিস্ট্যান্টে ডায়নামিক শর্টকাট প্রসারিত করুন

1. সংক্ষিপ্ত বিবরণ

পূর্ববর্তী কোডল্যাবে , আপনি একটি নমুনা অ্যাপে সাধারণভাবে ব্যবহৃত বিল্ট-ইন ইনটেন্ট (BII) বাস্তবায়নের জন্য স্ট্যাটিক শর্টকাট ব্যবহার করেছিলেন। অ্যান্ড্রয়েড ডেভেলপাররা গুগল অ্যাসিস্ট্যান্টে অ্যাপের কার্যকারিতা প্রসারিত করতে অ্যাপ অ্যাকশন ব্যবহার করে।

স্ট্যাটিক শর্টকাটগুলি একটি অ্যাপের সাথে যুক্ত থাকে এবং শুধুমাত্র অ্যাপের নতুন সংস্করণ প্রকাশের মাধ্যমেই আপডেট করা যায়। ব্যবহারকারীর তৈরি কন্টেন্টের মতো অ্যাপে ডাইনামিক উপাদানগুলির জন্য ভয়েস কার্যকারিতা সক্ষম করা, ডায়নামিক শর্টকাট ব্যবহার করে অর্জন করা হয়। ব্যবহারকারীরা প্রাসঙ্গিক ক্রিয়া সম্পাদন করার পরে, যেমন টাস্ক ট্র্যাকিং অ্যাপে একটি নতুন নোট তৈরি করার পরে অ্যাপগুলি ডায়নামিক শর্টকাটগুলি পুশ করে। অ্যাপ অ্যাকশনের সাহায্যে, আপনি ভয়েসের জন্য এই শর্টকাটগুলিকে একটি BII-তে আবদ্ধ করে সক্ষম করেন, ব্যবহারকারীদের "Hey Google, ExampleApp-এ আমার মুদিখানার তালিকা খুলুন" এই ধরণের কথা বলে Assistant থেকে তাদের সামগ্রী অ্যাক্সেস করতে সক্ষম করে।

তিনটি প্রগতিশীল স্ক্রিনে গুগল অ্যাসিস্ট্যান্ট একটি ডায়নামিক শর্টকাট চালু করছে।

চিত্র ১. তিনটি প্রগতিশীল স্ক্রিন যেখানে ব্যবহারকারীর তৈরি একটি টাস্ক এবং গুগল অ্যাসিস্ট্যান্ট সেই টাস্ক আইটেমের জন্য একটি গতিশীল শর্টকাট চালু করছে।

তুমি কী তৈরি করবে

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

পূর্বশর্ত

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

অতিরিক্তভাবে, এগিয়ে যাওয়ার আগে নিশ্চিত করুন যে আপনার ডেভেলপমেন্ট পরিবেশে নিম্নলিখিত কনফিগারেশন রয়েছে:

  • গিট ইনস্টল করে শেল কমান্ড চালানোর জন্য একটি টার্মিনাল।
  • অ্যান্ড্রয়েড স্টুডিওর সর্বশেষ স্থিতিশীল সংস্করণ।
  • ইন্টারনেট অ্যাক্সেস সহ একটি বাস্তব বা ভার্চুয়াল অ্যান্ড্রয়েড ডিভাইস।
  • একটি Google অ্যাকাউন্ট যা Android Studio, Google অ্যাপ এবং Google Assistant অ্যাপে সাইন ইন করা আছে।

2. এটি কীভাবে কাজ করে তা বুঝুন

ভয়েস অ্যাক্সেসের জন্য একটি গতিশীল শর্টকাট সক্ষম করার জন্য নিম্নলিখিত পদক্ষেপগুলি অন্তর্ভুক্ত রয়েছে:

  • একটি যোগ্য BII-এর সাথে একটি গতিশীল শর্টকাট বাঁধাই।
  • Google Shortcuts Integration লাইব্রেরি যোগ করে Assistant-কে শর্টকাটগুলি গ্রহণ করতে সক্ষম করা।
  • যখনই কোনও ব্যবহারকারী প্রাসঙ্গিক ইন-অ্যাপ কাজটি সম্পন্ন করেন তখনই একটি শর্টকাট পুশ করা

বাইন্ডিং শর্টকাট

অ্যাসিস্ট্যান্ট থেকে একটি ডায়নামিক শর্টকাট অ্যাক্সেস করার জন্য, এটিকে একটি প্রাসঙ্গিক BII-তে আবদ্ধ করতে হবে। যখন একটি শর্টকাট সহ একটি BII ট্রিগার করা হয়, তখন অ্যাসিস্ট্যান্ট ব্যবহারকারীর অনুরোধের প্যারামিটারগুলিকে বাউন্ড শর্টকাটে সংজ্ঞায়িত কীওয়ার্ডের সাথে মেলায়। উদাহরণস্বরূপ:

  • GET_THING BII-এর সাথে সংযুক্ত একটি শর্টকাট ব্যবহারকারীদের সরাসরি Assistant থেকে নির্দিষ্ট ইন-অ্যাপ কন্টেন্টের অনুরোধ করার অনুমতি দিতে পারে। * "Ok Google, ExampleApp-এ আমার মুদিখানার তালিকা খুলুন।"
  • START_EXERCISE BII-তে আবদ্ধ একটি শর্টকাট ব্যবহারকারীদের তাদের ব্যায়াম সেশনগুলি দেখতে সাহায্য করতে পারে। * "হ্যালো গুগল, ExampleApp কে আমার স্বাভাবিক ব্যায়াম শুরু করতে বলুন।"

BII-এর সম্পূর্ণ শ্রেণীবদ্ধ তালিকার জন্য বিল্ট-ইন ইন্টেন্টস রেফারেন্সটি দেখুন।

সহকারীকে শর্টকাট প্রদান করা হচ্ছে

আপনার শর্টকাটগুলিকে BII-তে আবদ্ধ করার পর, পরবর্তী ধাপ হল আপনার প্রোজেক্টে Google Shortcuts Integration লাইব্রেরি যোগ করে Assistant-কে এই শর্টকাটগুলি গ্রহণ করতে সক্ষম করা। এই লাইব্রেরিটি চালু হওয়ার সাথে সাথে, Assistant আপনার অ্যাপ দ্বারা পুশ করা প্রতিটি শর্টকাট সম্পর্কে সচেতন থাকবে, ব্যবহারকারীরা Assistant-এ শর্টকাটের ট্রিগার বাক্যাংশ ব্যবহার করে সেই শর্টকাটগুলি চালু করতে সক্ষম হবে।

৩. আপনার উন্নয়ন পরিবেশ প্রস্তুত করুন

এই কোডল্যাবটি অ্যান্ড্রয়েডের জন্য তৈরি একটি নমুনা করণীয় তালিকা অ্যাপ ব্যবহার করে। এই অ্যাপের সাহায্যে ব্যবহারকারীরা তালিকায় আইটেম যোগ করতে পারবেন, বিভাগ অনুসারে টাস্ক লিস্ট আইটেমগুলি অনুসন্ধান করতে পারবেন এবং সমাপ্তির স্থিতি অনুসারে কাজগুলি ফিল্টার করতে পারবেন। এই বিভাগটি সম্পূর্ণ করে নমুনা অ্যাপটি ডাউনলোড করুন এবং প্রস্তুত করুন।

আপনার বেস ফাইলগুলি ডাউনলোড করুন

নমুনা অ্যাপের GitHub সংগ্রহস্থল ক্লোন করতে নিম্নলিখিত কমান্ডটি চালান:

git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git

একবার আপনি রিপোজিটরিটি ক্লোন করার পরে, এটি অ্যান্ড্রয়েড স্টুডিওতে খুলতে এই পদক্ষেপগুলি অনুসরণ করুন:

  1. Welcome to Android Studio ডায়ালগে, Import project এ ক্লিক করুন।
  2. আপনি যে ফোল্ডারে রিপোজিটরি ক্লোন করেছেন সেই ফোল্ডারটি নির্বাচন করুন।

বিকল্পভাবে, আপনি Github রেপোর codelab-complete শাখাটি ক্লোন করে সম্পূর্ণ কোডল্যাব প্রতিনিধিত্বকারী নমুনা অ্যাপের একটি সংস্করণ দেখতে পারেন:

git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git --branch codelab-complete

অ্যান্ড্রয়েড অ্যাপ্লিকেশন আইডি আপডেট করুন

অ্যাপের অ্যাপ্লিকেশন আইডি আপডেট করলে আপনার পরীক্ষামূলক ডিভাইসে অ্যাপটি অনন্যভাবে শনাক্ত করা যায় এবং অ্যাপটি Play Console-এ আপলোড করা হলে "ডুপ্লিকেট প্যাকেজ নাম" ত্রুটি এড়ানো যায়। অ্যাপ্লিকেশন আইডি আপডেট করতে, app/build.gradle খুলুন:

android {
...
  defaultConfig {
    applicationId "com.MYUNIQUENAME.android.fitactions"
    ...
  }
}

applicationId ক্ষেত্রের "MYUNIQUENAME" এর পরিবর্তে আপনার জন্য অনন্য কিছু লিখুন।

শর্টকাট API নির্ভরতা যোগ করুন

app/build.gradle রিসোর্স ফাইলে নিম্নলিখিত Jetpack লাইব্রেরিগুলি যোগ করুন:

অ্যাপ/বিল্ড.গ্রেডল

dependencies {
   ...
   // Shortcuts library
   implementation "androidx.core:core:1.6.0"
   implementation 'androidx.core:core-google-shortcuts:1.0.1'
   ...
}

আপনার ডিভাইসে অ্যাপটি পরীক্ষা করুন

অ্যাপটিতে আরও পরিবর্তন আনার আগে, নমুনা অ্যাপটি কী করতে পারে তার একটি ধারণা নেওয়া সহায়ক। আপনার এমুলেটরে অ্যাপটি চালাতে, এই পদক্ষেপগুলি অনুসরণ করুন:

  1. অ্যান্ড্রয়েড স্টুডিওতে, রান > রান অ্যাপ নির্বাচন করুন অথবা রান এ ক্লিক করুন অ্যান্ড্রয়েড স্টুডিওতে অ্যাপ আইকন চালান টুলবারে।
  2. Select Deployment Target ডায়ালগে, একটি ডিভাইস নির্বাচন করুন এবং OK এ ক্লিক করুন। প্রস্তাবিত OS সংস্করণটি হল Android 10 (API লেভেল 30) বা তার বেশি, যদিও App Actions Android 5 (API লেভেল 21) এর ডিভাইসগুলিতে কাজ করে।
  3. অ্যাসিস্ট্যান্ট সেট আপ করতে এবং এটি কাজ করছে কিনা তা যাচাই করতে হোম বোতামটি দীর্ঘক্ষণ টিপুন। যদি আপনি ইতিমধ্যেই অ্যাসিস্ট্যান্টে সাইন ইন না করে থাকেন তবে আপনাকে আপনার ডিভাইসে অ্যাসিস্ট্যান্টে সাইন ইন করতে হবে।

অ্যান্ড্রয়েড ভার্চুয়াল ডিভাইস সম্পর্কে আরও তথ্যের জন্য, ভার্চুয়াল ডিভাইস তৈরি এবং পরিচালনা দেখুন।

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

৪. একটি শর্টকাট রিপোজিটরি ক্লাস তৈরি করুন

আমাদের নমুনা অ্যাপের বেশ কয়েকটি ক্লাস ডায়নামিক শর্টকাট পুশ এবং পরিচালনা করার জন্য ShortcutManagerCompat API কল করবে। কোড রিডানডেন্সি কমাতে, আপনি একটি রিপোজিটরি বাস্তবায়ন করবেন যাতে আপনার প্রোজেক্ট ক্লাসগুলি সহজেই ডায়নামিক শর্টকাট পরিচালনা করতে পারে।

রিপোজিটরি ডিজাইন প্যাটার্ন শর্টকাট পরিচালনার জন্য একটি পরিষ্কার API প্রদান করে। একটি রিপোজিটরির সুবিধা হল অন্তর্নিহিত API এর বিবরণ একটি ন্যূনতম API এর পিছনে সমানভাবে বিমূর্ত করা হয়। এই পদক্ষেপগুলি অনুসরণ করে রিপোজিটরিটি বাস্তবায়ন করুন:

  1. ShortcutManagerCompat API বিমূর্ত করার জন্য একটি ShortcutsRepository ক্লাস তৈরি করুন।
  2. অ্যাপের সার্ভিস লোকেটারে ShortcutsRepository পদ্ধতি যোগ করুন।
  3. মূল অ্যাপ্লিকেশনে ShortcutRepository পরিষেবাটি নিবন্ধন করুন।

সংগ্রহস্থল তৈরি করুন

com.example.android.architecture.blueprints.todoapp.data.source প্যাকেজে ShortcutsRepository নামে একটি নতুন Kotlin ক্লাস তৈরি করুন। আপনি এই প্যাকেজটি app/src/main/java ফোল্ডারে সংগঠিতভাবে খুঁজে পেতে পারেন। আপনি এই ক্লাসটি ব্যবহার করে একটি ইন্টারফেস বাস্তবায়ন করবেন যা আমাদের কোডল্যাব ব্যবহারের ক্ষেত্রে ন্যূনতম পদ্ধতির সেট প্রদান করে।

শর্টকাটসরিপোজিটরি ক্লাসের অবস্থান প্রদর্শনকারী অ্যান্ড্রয়েড স্টুডিও উইন্ডো।

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

নতুন ক্লাসে নিম্নলিখিত কোডটি পেস্ট করুন:

package com.example.android.architecture.blueprints.todoapp.data.source

import android.content.Context
import android.content.Intent
import androidx.annotation.WorkerThread
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import com.example.android.architecture.blueprints.todoapp.data.Task
import com.example.android.architecture.blueprints.todoapp.tasks.TasksActivity

private const val GET_THING_KEY = "q"

/**
* ShortcutsRepository provides an interface for managing dynamic shortcuts.
*/
class ShortcutsRepository(val context: Context) {

   private val appContext = context.applicationContext

   /**
    * Pushes a dynamic shortcut. The task ID is used as the shortcut ID.
    * The task's title and description are used as shortcut's short and long labels.
    * The resulting shortcut corresponds to the GET_THING capability with task's
    * title used as BII's "name" argument.
    *
    * @param task Task object for which to create a shortcut.
    */
   @WorkerThread
   fun pushShortcut(task: Task) {
      // TODO
   }

   private fun createShortcutCompat(task: Task): ShortcutInfoCompat {
      //...
   }

   /**
    *  Updates a dynamic shortcut for the provided task. If the shortcut
    *  associated with this task doesn't exist, this method throws an error.
    *  This operation may take a few seconds to complete.
    *
    * @param tasks list of tasks to update.
    */
   @WorkerThread
   fun updateShortcuts(tasks: List<Task>) {
       //...
   }

   /**
    * Removes shortcuts if IDs are known.
    *
    * @param ids list of shortcut IDs
    */
   @WorkerThread
   fun removeShortcutsById(ids: List<String>) {
       //...
   }

   /**
    * Removes shortcuts associated with the tasks.
    *
    * @param tasks list of tasks to remove.
    */
   @WorkerThread
   fun removeShortcuts(tasks: List<Task>) {
       //...
   }
}

এরপর, ShortcutManagerCompat API কল করার জন্য pushShortcut পদ্ধতিটি আপডেট করুন। নিম্নলিখিত কোড দিয়ে ShortcutsRepository ক্লাসটি আপডেট করুন:

শর্টকাটসরিপোজিটরি.কেটি

/**
* Pushes a dynamic shortcut for the task. The task's ID is used as a shortcut
* ID. The task's title and description are used as shortcut's short and long
* labels. The created shortcut corresponds to GET_THING capability with task's
* title used as BII's "name" argument.
*
* @param task Task object for which to create a shortcut.
*/


@WorkerThread
fun pushShortcut(task: Task) {
   ShortcutManagerCompat.pushDynamicShortcut(appContext, createShortcutCompat(task))
}

পূর্ববর্তী কোড নমুনায় আমরা appContext API তে পাস করেছি। এটি একটি ক্লাস প্রোপার্টি যার মধ্যে একটি Application Context রয়েছে। মেমোরি লিক এড়াতে একটি Application Context ( Activity Context এর বিপরীতে) ব্যবহার করা গুরুত্বপূর্ণ, কারণ কনটেক্সটটি হোস্ট অ্যাক্টিভিটি লাইফসাইকেলের চেয়ে বেশি সময় ধরে ধরে রাখা যেতে পারে।

অতিরিক্তভাবে, API-এর জন্য আমাদের Task অবজেক্টের জন্য একটি ShortcutInfoCompat অবজেক্ট পাস করতে হবে। পূর্ববর্তী কোড নমুনায় আমরা createShortcutCompat private পদ্ধতিটি কল করে এটি সম্পন্ন করি, যা আমরা একটি ShortcutInfoCompat অবজেক্ট তৈরি এবং ফেরত দেওয়ার জন্য আপডেট করব। এটি সম্পন্ন করার জন্য, createShortcutCompat স্টাবটি নিম্নলিখিত কোড দিয়ে আপডেট করুন:

শর্টকাটসরিপোজিটরি.কেটি

private fun createShortcutCompat(task: Task): ShortcutInfoCompat {
   val intent = Intent(appContext, TasksActivity::class.java)
   intent.action = Intent.ACTION_VIEW
   // Filtering is set based on currentTitle.
   intent.putExtra(GET_THING_KEY, task.title)

   // A unique ID is required to avoid overwriting an existing shortcut.
   return ShortcutInfoCompat.Builder(appContext, task.id)
           .setShortLabel(task.title)
           .setLongLabel(task.title)
           // Call addCapabilityBinding() to link this shortcut to a BII. Enables user to invoke a shortcut using its title in Assistant.
           .addCapabilityBinding(
                   "actions.intent.GET_THING", "thing.name", listOf(task.title))
           .setIntent(intent)
           .setLongLived(false)
       .build()
}

এই ক্লাসের বাকি ফাংশন স্টাবগুলি ডায়নামিক শর্টকাটগুলি আপডেট এবং মুছে ফেলার সাথে সম্পর্কিত। নিম্নলিখিত কোড দিয়ে আপডেট করে এই ফাংশনগুলি সক্ষম করুন:

শর্টকাটসরিপোজিটরি.কেটি

/**
* Updates a Dynamic Shortcut for the task. If the shortcut associated with this task
* doesn't exist, throws an error. This operation may take a few seconds to complete.
*
* @param tasks list of tasks to update.
*/
@WorkerThread
fun updateShortcuts(tasks: List<Task>) {
   val scs = tasks.map { createShortcutCompat(it) }
   ShortcutManagerCompat.updateShortcuts(appContext, scs)
}

/**
* Removes shortcuts if IDs are known.
* @param ids list of shortcut IDs
*/
@WorkerThread
fun removeShortcutsById(ids: List<String>) {
   ShortcutManagerCompat.removeDynamicShortcuts(appContext, ids)
}

/**
* Removes shortcuts associated with the tasks.
*
* @param tasks list of tasks to remove.
*/
@WorkerThread
fun removeShortcuts(tasks: List<Task>) {
   ShortcutManagerCompat.removeDynamicShortcuts (appContext,
           tasks.map { it.id })
}

সার্ভিস লোকেটারে ক্লাস যোগ করুন

ShortcutsRepository ক্লাস তৈরি করার পর, পরবর্তী ধাপ হল এই ক্লাসের ইনস্ট্যান্টিয়েটেড অবজেক্টগুলিকে অ্যাপের বাকি অংশের জন্য উপলব্ধ করা। এই অ্যাপটি সার্ভিস লোকেটার প্যাটার্ন বাস্তবায়নের মাধ্যমে ক্লাস নির্ভরতা পরিচালনা করে। Android Studio-তে ক্লাস ব্রাউজার ব্যবহার করে Navigate > Class-এ গিয়ে "ServiceLocator" টাইপ করে সার্ভিস লোকেটার ক্লাসটি খুলুন। আপনার IDE-তে এটি খুলতে ফলাফল প্রাপ্ত Kotlin ফাইলটিতে ক্লিক করুন।

ServiceLocator.kt এর উপরে, ShortcutsRepository এবং SuppressLint প্যাকেজগুলি আমদানি করতে নিম্নলিখিত কোডটি পেস্ট করুন:

সার্ভিসলোকেটর.কেটি

package com.example.android.architecture.blueprints.todoapp

// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
import android.annotation.SuppressLint

ServiceLocator.kt এর বডিতে নিম্নলিখিত কোডটি পেস্ট করে ShortcutRepository পরিষেবা সদস্য এবং পদ্ধতিগুলি যোগ করুন:

সার্ভিসলোকেটর.কেটি

object ServiceLocator {

   // ...
   // Only the code immediately below this comment needs to be copied and pasted
   // into the body of ServiceLocator.kt:

   @SuppressLint("StaticFieldLeak")
   @Volatile
   var shortcutsRepository: ShortcutsRepository? = null


   private fun createShortcutsRepository(context: Context): ShortcutsRepository {
       val newRepo = ShortcutsRepository(context.applicationContext)
       shortcutsRepository = newRepo
       return newRepo
   }

   fun provideShortcutsRepository(context: Context): ShortcutsRepository {
       synchronized(this) {
           return shortcutsRepository ?: shortcutsRepository ?: createShortcutsRepository(context)
       }
   }
 }

শর্টকাট পরিষেবাটি নিবন্ধন করুন

শেষ ধাপ হল আপনার নতুন ShortcutsRepository পরিষেবাটি অ্যাপ্লিকেশনের সাথে নিবন্ধন করা। Android Studio-তে, TodoApplication.kt খুলুন এবং ফাইলের উপরের দিকে নিম্নলিখিত কোডটি অনুলিপি করুন:

TodoApplication.kt সম্পর্কে

package com.example.android.architecture.blueprints.todoapp
/// ... Other import statements

import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

এরপর, ক্লাসের বডিতে নিম্নলিখিত কোডটি যোগ করে পরিষেবাটি নিবন্ধন করুন:

TodoApplication.kt সম্পর্কে

//...
class TodoApplication : Application() {

   //...

   val shortcutsRepository: ShortcutsRepository
       get() = ServiceLocator.provideShortcutsRepository(this)

   //...
}

অ্যাপটি তৈরি করুন এবং নিশ্চিত করুন যে এটি চালু আছে।

৫. একটি নতুন শর্টকাট চাপুন

আপনার শর্টকাট পরিষেবা তৈরি হওয়ার পর, আপনি শর্টকাট পুশ করা শুরু করতে প্রস্তুত। যেহেতু ব্যবহারকারীরা এই অ্যাপে কন্টেন্ট (টাস্ক আইটেম) তৈরি করে এবং পরে সেগুলিতে ফিরে আসতে সক্ষম হবে বলে আশা করে, তাই আমরা প্রতিবার যখনই কোনও ব্যবহারকারী একটি নতুন টাস্ক তৈরি করে তখন GET_THING BII-তে আবদ্ধ একটি ডায়নামিক শর্টকাট পুশ করে এই কন্টেন্টে অ্যাক্সেস ভয়েস-সক্ষম করব। এটি Assistant-কে BII ট্রিগার করার সময় ব্যবহারকারীদের সরাসরি তাদের অনুরোধ করা টাস্ক আইটেমে লঞ্চ করতে সক্ষম করে, যেমন " হে গুগল, স্যাম্পলঅ্যাপে আমার মুদিখানার তালিকা খুলুন"।

আপনি এই পদক্ষেপগুলি সম্পন্ন করে নমুনা অ্যাপে এই কার্যকারিতাটি সক্ষম করতে পারেন:

  1. টাস্ক লিস্ট অবজেক্ট পরিচালনার জন্য দায়ী AddEditTaskViewModel ক্লাসে ShortcutsRepository পরিষেবা আমদানি করা।
  2. ব্যবহারকারী যখন একটি নতুন কাজ তৈরি করে তখন একটি গতিশীল শর্টকাট পুশ করা।

শর্টকাট আমদানি করুন সংগ্রহস্থল

আমাদের প্রথমে ShortcutsRepository পরিষেবাটি AddEditTaskViewModel এ উপলব্ধ করতে হবে। এটি সম্পন্ন করার জন্য, পরিষেবাটি ViewModelFactory তে আমদানি করুন, এটি সেই ফ্যাক্টরি ক্লাস যা অ্যাপটি ViewModel অবজেক্টগুলিকে ইনস্ট্যান্টিয়েট করার জন্য ব্যবহার করে, যার মধ্যে AddEditTaskViewModel ও রয়েছে।

অ্যান্ড্রয়েড স্টুডিওতে Navigate > Class এ গিয়ে "ViewModelFactory" টাইপ করে ক্লাস ব্রাউজারটি খুলুন। আপনার IDE তে এটি খুলতে ফলাফল প্রাপ্ত Kotlin ফাইলটিতে ক্লিক করুন।

ViewModelFactory.kt এর উপরে, ShortcutsRepository এবং SuppressLint প্যাকেজগুলি আমদানি করতে নিম্নলিখিত কোডটি পেস্ট করুন:

ViewModelFactory.kt সম্পর্কে

package com.example.android.architecture.blueprints.todoapp

// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

এরপর, ViewModelFactory এর বডিটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন:

ViewModelFactory.kt সম্পর্কে

/**
 * Factory for all ViewModels.
 */
@Suppress("UNCHECKED_CAST")
class ViewModelFactory constructor(
    private val tasksRepository: TasksRepository,
    private val shortcutsRepository: ShortcutsRepository,
    owner: SavedStateRegistryOwner,
    defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {

    override fun <T : ViewModel> create(
        key: String,
        modelClass: Class<T>,
        handle: SavedStateHandle
    ) = with(modelClass) {
        when {
            isAssignableFrom(StatisticsViewModel::class.java) ->
                StatisticsViewModel(tasksRepository)
            isAssignableFrom(TaskDetailViewModel::class.java) ->
                TaskDetailViewModel(tasksRepository)
            isAssignableFrom(AddEditTaskViewModel::class.java) ->
                AddEditTaskViewModel(tasksRepository, shortcutsRepository)
            isAssignableFrom(TasksViewModel::class.java) ->
                TasksViewModel(tasksRepository, handle)
            else ->
                throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
        }
    } as T
}

এক স্তর উপরে গিয়ে ViewModelFactory পরিবর্তনগুলি সম্পন্ন করুন এবং ShortcutsRepository কে ফ্যাক্টরির কনস্ট্রাক্টরে পাস করুন। Navigate > File এ গিয়ে "FragmentExt.kt" টাইপ করে Android Studio এর ফাইল ব্রাউজার খুলুন। আপনার IDE তে এটি খুলতে util প্যাকেজে অবস্থিত Kotlin ফাইলটিতে ক্লিক করুন।

FragmentExt.kt এর বডিটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন:

fun Fragment.getViewModelFactory(): ViewModelFactory {
   val taskRepository = (requireContext().applicationContext as TodoApplication).taskRepository
   val shortcutsRepository = (requireContext().applicationContext as TodoApplication).shortcutsRepository
   return ViewModelFactory(taskRepository, shortcutsRepository, this)
}

একটি শর্টকাট চাপুন

নমুনা অ্যাপের ViewModel ক্লাসগুলিতে ShortcutsRepository অ্যাবস্ট্রাকশন ক্লাস উপলব্ধ থাকার ফলে, আপনি AddEditTaskViewModel আপডেট করেন, যা নোট তৈরির জন্য দায়ী ViewModel ক্লাস, যাতে ব্যবহারকারী প্রতিবার নতুন নোট তৈরি করার সময় একটি গতিশীল শর্টকাট পুশ করা যায়।

অ্যান্ড্রয়েড স্টুডিওতে, ক্লাস ব্রাউজারটি খুলুন এবং "AddEditTaskViewModel" টাইপ করুন। আপনার IDE তে এটি খুলতে ফলাফল প্রাপ্ত Kotlin ফাইলটিতে ক্লিক করুন।

প্রথমে, নিম্নলিখিত আমদানি বিবৃতি সহ এই ক্লাসে ShortcutsRepository প্যাকেজটি যুক্ত করুন:

package com.example.android.architecture.blueprints.todoapp.addedittask

//Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

এরপর, নিম্নলিখিত কোড ব্যবহার করে ক্লাস কনস্ট্রাক্টর আপডেট করে shortcutsRepository ক্লাস প্রোপার্টি যোগ করুন:

AddEditTaskViewModel.kt সম্পর্কে

//...

/**
* ViewModel for the Add/Edit screen.
*/
class AddEditTaskViewModel(
   private val tasksRepository: TasksRepository,
   private val shortcutsRepository: ShortcutsRepository
) : ViewModel() {

    //...

ShortcutsRepository ক্লাস যোগ করার সাথে সাথে, এই ক্লাসটি কল করার জন্য একটি নতুন ফাংশন, pushShortcut() তৈরি করুন। AddEditTaskViewModel এর বডিতে নিম্নলিখিত private ফাংশনটি পেস্ট করুন:

AddEditTaskViewModel.kt সম্পর্কে

//...
private fun pushShortcut(newTask: Task) = viewModelScope.launch {
   shortcutsRepository.pushShortcut(newTask)
}

অবশেষে, যখনই কোনও টাস্ক তৈরি হবে তখন একটি নতুন ডায়নামিক শর্টকাট চাপুন। saveTask() ফাংশনের বিষয়বস্তু নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন:

AddEditTaskViewModel.kt সম্পর্কে

fun saveTask() {
    val currentTitle = title.value
    val currentDescription = description.value

    if (currentTitle == null || currentDescription == null) {
        _snackbarText.value = Event(R.string.empty_task_message)
        return
    }
    if (Task(currentTitle, currentDescription).isEmpty) {
        _snackbarText.value = Event(R.string.empty_task_message)
        return
    }

    val currentTaskId = taskId
    if (isNewTask || currentTaskId == null) {
        val task = Task(currentTitle, currentDescription)
        createTask(task)
        pushShortcut(task)
    } else {
        val task = Task(currentTitle, currentDescription, taskCompleted, currentTaskId)
        updateTask(task)
    }
}

আপনার কোড পরীক্ষা করুন

আমরা অবশেষে আমাদের কোড পরীক্ষা করার জন্য প্রস্তুত! এই ধাপে, আপনি একটি ভয়েস সক্ষম ডায়নামিক শর্টকাট পুশ করুন এবং Google Assistant অ্যাপ ব্যবহার করে এটি পরীক্ষা করুন।

একটি প্রিভিউ তৈরি করুন

Google Assistant প্লাগইন ব্যবহার করে একটি প্রিভিউ তৈরি করলে আপনার টেস্ট ডিভাইসে Assistant-এ আপনার ডায়নামিক শর্টকাটগুলি দেখা যাবে।

পরীক্ষা প্লাগইন ইনস্টল করুন

যদি আপনার কাছে ইতিমধ্যেই Google Assistant প্লাগইন না থাকে, তাহলে Android Studio-তে এই ধাপগুলি অনুসরণ করে এটি ইনস্টল করুন:

  1. **ফাইল > সেটিংস (Android Studio > MacOS-এ পছন্দসমূহ) এ যান।
  2. প্লাগইন বিভাগে, মার্কেটপ্লেসে যান এবং "গুগল অ্যাসিস্ট্যান্ট" অনুসন্ধান করুন।
  3. টুলটি ইনস্টল করুন এবং অ্যান্ড্রয়েড স্টুডিও পুনরায় চালু করুন।

প্রিভিউ তৈরি করুন

অ্যান্ড্রয়েড স্টুডিওতে এই ধাপগুলি অনুসরণ করে একটি প্রিভিউ তৈরি করুন:

  1. টুলস > গুগল অ্যাসিস্ট্যান্ট > " অ্যাপ অ্যাকশন টেস্ট টুল " এ ক্লিক করুন।
  2. অ্যাপের নাম বাক্সে, "করণীয় তালিকা" এর মতো একটি নাম নির্ধারণ করুন।
  3. প্রিভিউ তৈরি করুন ক্লিক করুন। যদি জিজ্ঞাসা করা হয়, তাহলে অ্যাপ অ্যাকশন নীতি এবং পরিষেবার শর্তাবলী পর্যালোচনা করুন এবং গ্রহণ করুন।

অ্যাপ অ্যাকশন টেস্ট টুলের প্রিভিউ তৈরির ফলক।

চিত্র ৩. অ্যাপ অ্যাকশন টেস্ট টুল প্রিভিউ তৈরির ফলক।

পরীক্ষার সময়, Assistant-এ পুশ করা ডায়নামিক শর্টকাটগুলি Assistant-এ আপনার প্রিভিউতে প্রদত্ত অ্যাপের নাম অনুসারে সাজানো দেখাবে।

একটি শর্টকাট পুশ করুন এবং পরীক্ষা করুন

আপনার পরীক্ষামূলক ডিভাইসে নমুনা অ্যাপটি পুনরায় চালু করুন এবং নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করুন:

  1. "Start codelab" শিরোনাম দিয়ে একটি নতুন টাস্ক তৈরি করুন।
  2. গুগল অ্যাসিস্ট্যান্ট অ্যাপ খুলুন এবং "আমার শর্টকাট" বলুন বা টাইপ করুন।
  3. এক্সপ্লোর ট্যাবে ট্যাপ করুন। আপনি নমুনা শর্টকাটটি দেখতে পাবেন।
  4. শর্টকাটটি চালু করতে এটিতে ট্যাপ করুন। ফিল্টার বাক্সে শর্টকাটের নামটি আগে থেকে পূরণ করে অ্যাপটি লঞ্চ হওয়া দেখতে পাবেন, যার ফলে অনুরোধ করা টাস্ক আইটেমটি খুঁজে পাওয়া সহজ হবে।

৬. (ঐচ্ছিক) একটি শর্টকাট আপডেট করুন এবং মুছে ফেলুন

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

একটি শর্টকাট আপডেট করুন

যখনই কোনও ব্যবহারকারী কোনও টাস্ক আইটেমের বিবরণ পরিবর্তন করে তখন একটি ডায়নামিক শর্টকাট আপডেট করার জন্য AddEditTaskViewModel পরিবর্তন করুন। প্রথমে, আমাদের রিপোজিটরি ক্লাস ব্যবহার করে একটি আপডেট ফাংশন যোগ করতে নিম্নলিখিত কোড দিয়ে ক্লাসের বডি আপডেট করুন:

AddEditTaskViewModel.kt সম্পর্কে

private fun updateShortcut(newTask: Task) = viewModelScope.launch {
   shortcutsRepository.updateShortcuts(listOf(newTask))
}

এরপর, saveTask() ফাংশনটি পরিবর্তন করুন যাতে বিদ্যমান কোনও টাস্ক আপডেট হলে আমাদের নতুন পদ্ধতিটি কল করা যায়।

AddEditTaskViewModel.kt সম্পর্কে

// Called when clicking on fab.
fun saveTask() {
   // ...
   // Note: the shortcuts are created/updated in a worker thread.
   if (isNewTask || currentTaskId == null) {
       //...
   } else {
       //...
       updateShortcut(task)
   }
}

অ্যাপটি পুনরায় চালু করে এবং এই পদক্ষেপগুলি অনুসরণ করে আপনার কোড পরীক্ষা করুন:

  1. আপনার বিদ্যমান টাস্ক আইটেমের শিরোনামের নাম পরিবর্তন করে "কোডল্যাব শেষ করুন" রাখুন।
  2. "হে গুগল, আমার শর্টকাট" বলে গুগল অ্যাসিস্ট্যান্ট খুলুন।
  3. এক্সপ্লোর ট্যাবে ট্যাপ করুন। আপনার টেস্ট শর্টকাটের জন্য একটি আপডেট করা শর্ট লেবেল দেখতে পাবেন।

একটি শর্টকাট সরান

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

ViewModelFactory খুলুন এবং এর কনস্ট্রাক্টর পদ্ধতির বিষয়বস্তু নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন:

//...
class ViewModelFactory constructor(
       private val tasksRepository: TasksRepository,
       private val shortcutsRepository: ShortcutsRepository,
       owner: SavedStateRegistryOwner,
       defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {

   override fun <T : ViewModel> create(
           key: String,
           modelClass: Class<T>,
           handle: SavedStateHandle
   ) = with(modelClass) {
       when {
           isAssignableFrom(StatisticsViewModel::class.java) ->
               StatisticsViewModel(tasksRepository)
           isAssignableFrom(TaskDetailViewModel::class.java) ->
               TaskDetailViewModel(tasksRepository, shortcutsRepository)
           isAssignableFrom(AddEditTaskViewModel::class.java) ->
               AddEditTaskViewModel(tasksRepository, shortcutsRepository)
           isAssignableFrom(TasksViewModel::class.java) ->
               TasksViewModel(tasksRepository, handle)
           else ->
               throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
       }
   } as T
}

এরপর, TaskDetailViewModel খুলুন। ShortcutsRepository মডিউলটি আমদানি করুন এবং নিম্নলিখিত কোড ব্যবহার করে এর জন্য একটি ইনস্ট্যান্স ভেরিয়েবল ঘোষণা করুন:

টাস্কডিটেইলভিউমডেল.কেটি

package com.example.android.architecture.blueprints.todoapp.taskdetail

...
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository


/**
* ViewModel for the Details screen.
*/
class TaskDetailViewModel(
       //...
       private val shortcutsRepository: ShortcutsRepository
   ) : ViewModel() {
...
}

অবশেষে, deleteTask() ফাংশনটি পরিবর্তন করে shortcutsRepository কল করুন যাতে সংশ্লিষ্ট taskId সহ কোনও টাস্ক মুছে ফেলা হলে তার আইডির উপর ভিত্তি করে একটি শর্টকাট সরানো যায়:

টাস্কডিটেইলভিউমডেল.কেটি

fun deleteTask() = viewModelScope.launch {
   _taskId.value?.let {
       //...
       shortcutsRepository.removeShortcutsById(listOf(it))
   }
}

আপনার কোড পরীক্ষা করতে, অ্যাপটি পুনরায় চালু করুন এবং এই পদক্ষেপগুলি অনুসরণ করুন:

  1. তোমার পরীক্ষার কাজটি মুছে ফেলো।
  2. আপনার বিদ্যমান টাস্ক আইটেমের শিরোনামের নাম পরিবর্তন করে "কোডল্যাব শেষ করুন" রাখুন।
  3. "হে গুগল, আমার শর্টকাট" বলে গুগল অ্যাসিস্ট্যান্ট খুলুন।
  4. এক্সপ্লোর ট্যাবে ট্যাপ করুন। নিশ্চিত করুন যে আপনার পরীক্ষার শর্টকাটটি আর প্রদর্শিত হচ্ছে না।

৭. পরবর্তী পদক্ষেপ

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

আমরা যা কভার করেছি

এই কোডল্যাবে, আপনি শিখেছেন কিভাবে:

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

এরপর কি?

এখান থেকে, আপনি আপনার টাস্ক লিস্ট অ্যাপে আরও পরিমার্জন করার চেষ্টা করতে পারেন। সমাপ্ত প্রকল্পটি উল্লেখ করতে, GitHub-এ repo –codelab-complete শাখাটি দেখুন।

অ্যাপ অ্যাকশনের মাধ্যমে এই অ্যাপটি কীভাবে সম্প্রসারিত করা যায় সে সম্পর্কে আরও জানার জন্য এখানে কিছু পরামর্শ দেওয়া হল:

আপনার অ্যাকশনস অন গুগল যাত্রা চালিয়ে যেতে, এই রিসোর্সগুলি ঘুরে দেখুন:

আমাদের সর্বশেষ ঘোষণাগুলি পেতে টুইটারে @ActionsOnGoogle- এ আমাদের অনুসরণ করুন, এবং আপনার তৈরি করা জিনিসগুলি শেয়ার করতে #appActions- এ টুইট করুন!

প্রতিক্রিয়া জরিপ

অবশেষে, এই কোডল্যাবের সাথে আপনার অভিজ্ঞতা সম্পর্কে মতামত জানাতে দয়া করে এই জরিপটি পূরণ করুন।