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

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

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

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

তিনটি ধারাবাহিক স্ক্রিনে দেখানো হচ্ছে কীভাবে গুগল অ্যাসিস্ট্যান্ট একটি ডাইনামিক শর্টকাট চালু করছে।

চিত্র ১। তিনটি ধারাবাহিক স্ক্রিন, যেখানে ব্যবহারকারীর তৈরি একটি টাস্ক এবং গুগল অ্যাসিস্ট্যান্ট কর্তৃক সেই টাস্ক আইটেমটির জন্য একটি ডাইনামিক শর্টকাট চালু করা দেখানো হচ্ছে।

আপনি যা তৈরি করবেন

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

পূর্বশর্ত

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

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

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

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

ভয়েস অ্যাক্সেসের জন্য একটি ডায়নামিক শর্টকাট সক্রিয় করতে নিম্নলিখিত ধাপগুলি অনুসরণ করতে হয়:

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

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

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

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

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

অ্যাসিস্ট্যান্টে শর্টকাট প্রদান করা

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

৩. আপনার ডেভেলপমেন্ট পরিবেশ প্রস্তুত করুন

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

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

স্যাম্পল অ্যাপটির গিটহাব রিপোজিটরি ক্লোন করতে নিম্নলিখিত কমান্ডটি চালান:

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

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

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

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

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

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

অ্যাপের অ্যাপ্লিকেশন আইডি আপডেট করলে আপনার টেস্ট ডিভাইসে অ্যাপটিকে একটি স্বতন্ত্র পরিচয় দেওয়া যায় এবং প্লে কনসোলে অ্যাপটি আপলোড করার সময় "ডুপ্লিকেট প্যাকেজ নেম" ত্রুটি এড়ানো যায়। অ্যাপ্লিকেশন আইডি আপডেট করতে, app/build.gradle খুলুন:

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

applicationId ফিল্ডে থাকা 'MYUNIQUENAME'-এর পরিবর্তে আপনার নিজস্ব কোনো অনন্য নাম ব্যবহার করুন।

শর্টকাট এপিআই নির্ভরতা যোগ করুন

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-কে কল করবে। কোডের পুনরাবৃত্তি কমাতে, আপনি একটি রিপোজিটরি ইমপ্লিমেন্ট করবেন, যা আপনার প্রোজেক্টের ক্লাসগুলোকে সহজে ডাইনামিক শর্টকাট ম্যানেজ করতে সক্ষম করবে।

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

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

রিপোজিটরি তৈরি করুন

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

অ্যান্ড্রয়েড স্টুডিও উইন্ডোতে ShortcutsRepository ক্লাসের অবস্থান দেখানো হচ্ছে।

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

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

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>) {
       //...
   }
}

এরপরে, pushShortcut মেথডটিকে ShortcutManagerCompat API কল করার জন্য আপডেট করুন। নিম্নলিখিত কোড দিয়ে 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 অনুযায়ী Task অবজেক্টের জন্য আমাদের একটি ShortcutInfoCompat অবজেক্ট পাস করতে হয়। পূর্ববর্তী কোড স্যাম্পলে আমরা createShortcutCompat প্রাইভেট মেথডটি কল করার মাধ্যমে এটি সম্পন্ন করেছি, যেটিকে আমরা একটি 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 ক্লাসটি তৈরি হয়ে গেলে, পরবর্তী ধাপ হলো এই ক্লাসের ইনস্ট্যানসিয়েটেড অবজেক্টগুলোকে অ্যাপের বাকি অংশের জন্য উপলব্ধ করা। এই অ্যাপটি সার্ভিস লোকেটর প্যাটার্ন প্রয়োগ করে ক্লাস ডিপেন্ডেন্সি পরিচালনা করে। অ্যান্ড্রয়েড স্টুডিওর ক্লাস ব্রাউজারে Navigate > Class- এ গিয়ে "ServiceLocator" টাইপ করে সার্ভিস লোকেটর ক্লাসটি খুলুন। আপনার IDE-তে ফাইলটি খোলার জন্য প্রাপ্ত কোটলিন ফাইলটিতে ক্লিক করুন।

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 সার্ভিসটিকে অ্যাপ্লিকেশনের সাথে রেজিস্টার করা। অ্যান্ড্রয়েড স্টুডিওতে, 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-এর সাথে যুক্ত একটি ডাইনামিক শর্টকাট পাঠিয়ে এই কন্টেন্টে ভয়েস-এর মাধ্যমে অ্যাক্সেস সক্ষম করব। এর ফলে, ব্যবহারকারীরা যখন " হে গুগল, SampleApp-এ আমার গ্রোসারি লিস্টটা খোলো" এর মতো কিছু জিজ্ঞাসা করে BII-টি ট্রিগার করবেন, তখন অ্যাসিস্ট্যান্ট তাদের অনুরোধ করা টাস্ক আইটেমটিতে সরাসরি নিয়ে যেতে পারবে।

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

  1. টাস্ক লিস্ট অবজেক্টগুলো পরিচালনার দায়িত্বে থাকা AddEditTaskViewModel ক্লাসে ShortcutsRepository সার্ভিসটি ইম্পোর্ট করা হচ্ছে।
  2. ব্যবহারকারী যখন একটি নতুন টাস্ক তৈরি করেন, তখন একটি ডাইনামিক শর্টকাট পুশ করা হয়।

শর্টকাট রিপোজিটরি আমদানি করুন

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

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

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 অ্যাবস্ট্রাকশন ক্লাসটি উপলব্ধ থাকায়, আপনি নোট তৈরির জন্য দায়ী ViewModel ক্লাস AddEditTaskViewModel আপডেট করেন, যাতে প্রতিবার কোনো ব্যবহারকারী একটি নতুন নোট তৈরি করার সাথে সাথে একটি ডাইনামিক শর্টকাট পুশ করা হয়।

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

প্রথমে, নিম্নলিখিত ইম্পোর্ট স্টেটমেন্ট ব্যবহার করে এই ক্লাসে 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() নামে একটি নতুন ফাংশন তৈরি করুন। নিম্নলিখিত private ফাংশনটি AddEditTaskViewModel এর বডিতে পেস্ট করুন:

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)
    }
}

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

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

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

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

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

আপনার কাছে যদি আগে থেকে গুগল অ্যাসিস্ট্যান্ট প্লাগইন না থাকে, তাহলে অ্যান্ড্রয়েড স্টুডিওতে এই ধাপগুলো অনুসরণ করে এটি ইনস্টল করুন:

  1. ফাইল > সেটিংস-এ যান (ম্যাকওএস-এ অ্যান্ড্রয়েড স্টুডিও > প্রেফারেন্সেস)।
  2. প্লাগইন বিভাগে, মার্কেটপ্লেসে যান এবং 'Google Assistant' লিখে অনুসন্ধান করুন।
  3. টুলটি ইনস্টল করুন এবং অ্যান্ড্রয়েড স্টুডিও পুনরায় চালু করুন।

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

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

  1. টুলস > গুগল অ্যাসিস্ট্যান্ট > " অ্যাপ অ্যাকশনস টেস্ট টুল "-এ ক্লিক করুন।
  2. অ্যাপের নামের বক্সে "Todo List"-এর মতো একটি নাম দিন।
  3. 'Create Preview'-তে ক্লিক করুন। জিজ্ঞাসা করা হলে, অ্যাপ অ্যাকশন নীতিমালা এবং পরিষেবার শর্তাবলী পর্যালোচনা করে গ্রহণ করুন।

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

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

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

একটি শর্টকাট ঠেলে দিন এবং পরীক্ষা করুন।

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

  1. "স্টার্ট কোডল্যাব" শিরোনামে একটি নতুন টাস্ক তৈরি করুন।
  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 ক্লাসের মধ্যে রয়েছে। এই ক্লাসটি আপডেট করার আগে, TaskDetailViewModelshortcutsRepository পাস করার জন্য আমাদের ViewModelFactory আবার আপডেট করতে হবে।

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 মডিউলটি ইম্পোর্ট করুন এবং নিচের কোডটি ব্যবহার করে এর জন্য একটি ইনস্ট্যান্স ভেরিয়েবল ডিক্লেয়ার করুন:

TaskDetailViewModel.kt

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() ফাংশনটি পরিবর্তন করুন যাতে সংশ্লিষ্ট taskId সহ কোনো টাস্ক ডিলিট করা হলে, শর্টকাটটি তার আইডির উপর ভিত্তি করে সরিয়ে ফেলার জন্য shortcutsRepository কল করা হয়:

TaskDetailViewModel.kt

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

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

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

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

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

আমরা যা আলোচনা করেছি

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

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

এরপর কী?

এখান থেকে, আপনি আপনার টাস্ক লিস্ট অ্যাপটিতে আরও কিছু পরিমার্জন করার চেষ্টা করতে পারেন। সম্পূর্ণ প্রজেক্টটি দেখতে, গিটহাবে থাকা রিপোটির –codelab-complete ব্রাঞ্চটি দেখুন।

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

আপনার ‘অ্যাকশনস অন গুগল’ যাত্রা অব্যাহত রাখতে, এই রিসোর্সগুলো অন্বেষণ করুন:

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

মতামত সমীক্ষা

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