Uygulama İşlemleri ile dinamik kısayolları Google Asistan'a genişletme

1. Genel Bakış

Önceki codelab'de, örnek bir uygulamaya yaygın olarak kullanılan yerleşik amaçları (BII) uygulamak için statik kısayollar kullanıyordunuz. Android geliştiricileri, uygulama işlevlerini Google Asistan'a genişletmek için Uygulama İşlemleri'ni kullanır.

Statik kısayollar bir uygulamayla birlikte sunulur ve yalnızca uygulamanın yeni sürümleri yayınlandığında güncellenebilir. Uygulamalardaki dinamik öğeler (ör. kullanıcı tarafından oluşturulan içerikler) için ses işlevi, dinamik kısayollar kullanılarak etkinleştirilir. Kullanıcılar alakalı işlemleri (ör. görev izleme uygulamasında yeni not oluşturma) gerçekleştirdikten sonra uygulamalar dinamik kısayolları aktarır. Uygulama İşlemleri ile bu kısayolları etkinleştirmek için bunları bir BII'ye bağlayın ve kullanıcıların, "Ok Google, exampleApp'te alışveriş listemi aç" gibi bir komut vererek Asistan'dan içeriklerine erişebilmelerini sağlayın.

Google Asistan'ın dinamik bir kısayolu kullanıma sunduğunu gösteren üç aşamalı ekran.

Şekil 1. Kullanıcı tarafından oluşturulan bir görevi gösteren üç aşamalı ekran ve Google Asistan bu görev öğesi için dinamik bir kısayol başlatıyor.

Neler oluşturacaksınız?

Bu codelab'de, örnek bir Android yapılacaklar listesi uygulamasında ses için dinamik kısayolları etkinleştireceksiniz. Bu sayede kullanıcılar, Asistan'dan uygulamada oluşturdukları görev listesi öğelerini açmasını isteyebilir. Bu işlemi, Android mimari kalıpları, özellikle de depo, hizmet bulucu ve ViewModel kalıpları kullanarak gerçekleştirebilirsiniz.

Ön koşullar

Bu codelab'de, önceki codelab'de ele alınan Uygulama İşlemleri kavramları, özellikle de BII'ler ve statik kısayollar temel alınmıştır. Uygulama İşlemleri'ni kullanmaya yeni başladıysanız devam etmeden önce bu codelab'i tamamlamanızı öneririz.

Ayrıca, devam etmeden önce geliştirme ortamınızın aşağıdaki yapılandırmaya sahip olduğundan emin olun:

  • Git yüklü kabuk komutlarının çalıştırılacağı bir terminal.
  • Android Studio'nun en son kararlı sürümü.
  • İnternet erişimi olan fiziksel veya sanal bir Android cihaz.
  • Android Studio, Google uygulaması ve Google Asistan uygulamasında oturum açmış bir Google Hesabı.

2. İşleyiş şeklini anlayın

Sesli erişim için dinamik bir kısayolu etkinleştirmek için şu adımları uygulayın:

Bağlama kısayolları

Dinamik kısayolun Asistan'dan erişilebilir olması için alakalı bir BII'ye bağlı olması gerekir. Kısayolu olan bir BII tetiklendiğinde Asistan, kullanıcı isteğindeki parametreleri bağlı kısayolda tanımlanan anahtar kelimelerle eşleştirir. Örneğin:

  • GET_THING BII'ye bağlı bir kısayol, kullanıcıların doğrudan Asistan'dan belirli uygulama içi içerikleri istemesine olanak tanıyabilir. * "Ok Google, ExampleApp'te market listemi aç."
  • ORDER_MENU_ITEM BII'sine bağlı bir kısayol, kullanıcıların önceki siparişleri tekrar oynatmasına olanak tanıyabilir. * "Ok Google, ExampleApp'ten her zamanki gibi sipariş ver."

BBI'lerin tam kategorilere ayrılmış listesi için Yerleşik intent'ler referansına bakın.

Asistan'a kısayollar sağlama

Kısayollarınızı bir BII'ye bağladıktan sonraki adım, Google Kısayolları Entegrasyonu kitaplığını projenize ekleyerek Asistan'ın bu kısayolları almasını sağlamaktır. Bu kitaplık oluşturulduğunda Asistan, uygulamanız tarafından aktarılan her kısayolu fark eder. Böylece kullanıcılar, Asistan'daki kısayolun tetikleyici ifadesini kullanarak bu kısayolları başlatabilir.

3. Geliştirme ortamınızı hazırlama

Bu codelab'de, Android için geliştirilmiş örnek bir yapılacaklar listesi uygulaması kullanılır. Bu uygulamayla kullanıcılar listelere öğe ekleyebilir, kategoriye göre görev listesi öğelerini arayabilir ve görevleri tamamlanma durumuna göre filtreleyebilir. Bu bölümü tamamlayarak örnek uygulamayı indirin ve hazırlayın.

Temel dosyalarınızı indirin

Örnek uygulamanın GitHub deposunu klonlamak için aşağıdaki komutu çalıştırın:

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

Kod deposunu klonladıktan sonra, Android Studio'da açmak için şu adımları uygulayın:

  1. Android Studio'ya hoş geldiniz iletişim kutusunda Projeyi içe aktar'ı tıklayın.
  2. Depoyu klonladığınız klasörü seçin.

Alternatif olarak GitHub deposunun codelab-complete dalını klonlayarak tamamlanmış codelab'i temsil eden örnek uygulamanın bir sürümünü görüntüleyebilirsiniz:

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

Android uygulama kimliğini güncelleme

Uygulamanın uygulama kimliğini güncellemek, test cihazınızda uygulamayı benzersiz bir şekilde tanımlar ve "Yinelenen paket adı"nı önler hatası oluşur. Uygulama kimliğini güncellemek için app/build.gradle dosyasını açın:

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

Değiştir: "MYUNIQUENAME" applicationId alanına bunu benzersiz bir şekilde ekleyebilirsiniz.

Kısayollar API'si bağımlılıkları ekleyin

Aşağıdaki Jetpack kitaplıklarını app/build.gradle kaynak dosyasına ekleyin:

app/build.gradle

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

Uygulamayı cihazınızda test etme

Uygulamada daha fazla değişiklik yapmadan önce, örnek uygulamanın neler yapabileceği hakkında bilgi sahibi olmanız faydalı olacaktır. Uygulamayı emülatörünüzde çalıştırmak için şu adımları izleyin:

  1. Android Studio'da, Çalıştır > Uygulamayı çalıştırın veya araç çubuğunda ÇalıştırAndroid Studio'da uygulama çalıştırma simgesi tıklayın.
  2. Select Deployment Target (Dağıtım Hedefi Seçin) iletişim kutusunda bir cihaz seçip OK'i (Tamam) tıklayın. Önerilen işletim sistemi sürümü Android 10 (API düzeyi 30) veya sonraki sürümlerdir. Ancak Uygulama İşlemleri, Android 5 (API düzeyi 21) öncesine kadarki cihazlarda çalışır.
  3. Asistan'ı kurmak ve çalıştığını doğrulamak için Ana sayfa düğmesine uzun basın. Henüz açmadıysanız cihazınızda Asistan'da oturum açmanız gerekir.

Android sanal cihazlar hakkında daha fazla bilgi için Sanal cihazları oluşturma ve yönetme başlıklı makaleyi inceleyin.

Özelliklerini görmek için uygulamayı kısaca keşfedin. Artı simgesine dokunduğunuzda yeni bir görev öğesi oluşturulur, sağ üstteki menü öğeleri ise görev öğelerini tamamlanma durumuna göre aramanıza ve filtrelemenize olanak tanır.

4. Kısayol deposu sınıfı oluşturma

Örnek uygulamamızdaki bazı sınıflar, dinamik kısayolları aktarmak ve yönetmek için ShortcutManagerCompat API'yi çağırır. Kod yedekliliğini azaltmak amacıyla proje sınıflarınızın dinamik kısayolları kolayca yönetebilmesini sağlayacak bir depo uygulayacaksınız.

Depo tasarım kalıbı, kısayolları yönetmek için temiz bir API sağlar. Deponun avantajı, temel API'nin ayrıntılarının minimal bir API'de eşit olarak soyutlanmasıdır. Şu adımları izleyerek depoyu uygulayın:

  1. ShortcutManagerCompat API'yi soyutlamak için bir ShortcutsRepository sınıfı oluşturun.
  2. Uygulamanın hizmet bulma aracına ShortcutsRepository yöntemleri ekleyin.
  3. ShortcutRepository hizmetini ana Uygulamaya kaydedin.

Depoyu oluşturma

com.example.android.architecture.blueprints.todoapp.data.source paketinde ShortcutsRepository adlı yeni bir Kotlin sınıfı oluşturun. Bu paketi app/src/main/java klasöründe düzenlenmiş olarak bulabilirsiniz. Bu sınıfı, codelab kullanım alanımızı kapsayan minimum sayıda yöntem sunan bir arayüz uygulamak için kullanacaksınız.

shortsRepository sınıfının konumunu gösteren Android Studio penceresi.

Şekil 2. shortsRepository sınıfının konumunu gösteren Android Studio Proje Dosyaları penceresi.

Aşağıdaki kodu yeni sınıfa yapıştırın:

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

Ardından, ShortcutManagerCompat API'sini çağırmak için pushShortcut yöntemini güncelleyin. ShortcutsRepository sınıfını aşağıdaki kodla güncelleyin:

ShortcutsRepository.kt

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

Önceki kod örneğinde appContext değerini API'ye ilettik. Bu, Uygulama Bağlamı içeren bir sınıf özelliğidir. Bağlam, ana makine etkinliği yaşam döngüsünden daha uzun süre saklanabileceği için bellek sızıntılarını önlemek amacıyla Uygulama Bağlamı (Etkinlik Bağlamı yerine) kullanmanız önemlidir.

Ayrıca API, Görev nesnesi için bir ShortcutInfoCompat nesnesi iletmemizi gerektirir. Önceki kod örneğinde bunu, createShortcutCompat gizli yöntemini çağırarak gerçekleştiriyoruz. Bu yöntemi, bir ShortcutInfoCompat nesnesi oluşturmak ve döndürmek için güncelleyeceğiz. Bunu yapmak için createShortcutCompat saplamayı aşağıdaki kodla güncelleyin:

ShortcutsRepository.kt

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

Bu sınıftaki geri kalan işlev saplamalarında, dinamik kısayolların güncellenmesi ve silinmesi ele alınır. Aşağıdaki kodla güncelleyerek bu işlevleri etkinleştirin:

ShortcutsRepository.kt

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

Hizmet bulucuya sınıf ekle

ShortcutsRepository sınıfı oluşturulduktan sonraki adım, bu sınıfın örneklendirilmiş nesnelerini uygulamanın geri kalanı için kullanılabilir hale getirmektir. Bu uygulama, hizmet bulucu kalıbını uygulayarak sınıf bağımlılıklarını yönetir. Android Studio'da sınıf tarayıcısını kullanarak Git > Sınıf yazıp "ServiceLocator" yazarak başlayın. Oluşturulan Kotlin dosyasını tıklayarak IDE'nizde açın.

ShortcutsRepository ve SuppressLint paketlerini içe aktarmak için ServiceLocator.kt öğesinin üstüne şu kodu yapıştırın:

ServiceLocator.kt

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

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

Aşağıdaki kodu ServiceLocator.kt gövdesine yapıştırarak ShortcutRepository hizmet üyelerini ve yöntemleri ekleyin:

ServiceLocator.kt

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

Kısayol hizmetini kaydedin

Son adım, yeni ShortcutsRepository hizmetinizi Uygulama'ya kaydetmektir. Android Studio'da TodoApplication.kt dosyasını açın ve dosyanın üst kısmına yakın bir yerde bulunan şu kodu kopyalayın:

TodoApplication.kt

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

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

Ardından, aşağıdaki kodu sınıfın gövdesine ekleyerek hizmeti kaydedin:

TodoApplication.kt

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

   //...

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

   //...
}

Uygulamayı derleyin ve çalışmaya devam ettiğinden emin olun.

5. Yeni kısayol aktarma

Kısayol hizmetiniz oluşturulduktan sonra kısayolları aktarmaya başlayabilirsiniz. Kullanıcılar bu uygulamada içerik (görev öğeleri) oluşturduğundan ve bunlara daha sonra geri dönmeyi beklediğinden, her yeni görev oluşturduğunda GET_THING BII'ye bağlı dinamik bir kısayolu aktararak bu içeriğe erişimi sesli olarak etkinleştireceğiz. Bu sayede Asistan, kullanıcılar BII'yi tetiklediğinde "Ok Google, SampleApp'te alışveriş listemi aç" gibi sorular sorarak kullanıcıları doğrudan istedikleri görev öğesine yönlendirebilir.

Aşağıdaki adımları uygulayarak örnek uygulamada bu işlevi etkinleştirebilirsiniz:

  1. Görev listesi nesnelerinin yönetiminden sorumlu olan ShortcutsRepository hizmeti AddEditTaskViewModel sınıfına aktarılıyor.
  2. Kullanıcı yeni bir görev oluşturduğunda dinamik bir kısayol aktarılıyor.

shortsRepository'yi İçe Aktar

Öncelikle ShortcutsRepository hizmetini AddEditTaskViewModel tarafından kullanılabilir hale getirmemiz gerekiyor. Bunu yapmak için hizmeti, AddEditTaskViewModel dahil olmak üzere ViewModel nesnelerini örneklendirmek için uygulamanın kullandığı fabrika sınıfı ViewModelFactory ürününe aktarın.

Android Studio'da Git > Sınıf'a gidin ve "ViewModelFactory" yazın. Oluşturulan Kotlin dosyasını tıklayarak IDE'nizde açın.

ShortcutsRepository ve SuppressLint paketlerini içe aktarmak için ViewModelFactory.kt öğesinin üstüne şu kodu yapıştırın:

ViewModelFactory.kt

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

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

Sonra, ViewModelFactory gövdesini aşağıdaki kodla değiştirin:

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
}

Bir katman yukarıya giderek ViewModelFactory değişikliklerini tamamlayın ve ShortcutsRepository değerini fabrikanın kurucusuna iletin. Git > Dosya'yı tıklayın ve "FragmentExt.kt" yazın. IDE'nizde açmak için util paketinde bulunan Kotlin dosyasını tıklayın.

FragmentExt.kt gövdesini aşağıdaki kodla değiştirin:

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

Kısayol aktarma

Örnek uygulamanın ViewModel sınıfında kullanılabilen ShortcutsRepository soyutlama sınıfını kullanarak, kullanıcı her yeni not oluşturduğunda dinamik bir kısayol aktarmak için not oluşturmaktan sorumlu ViewModel sınıfını (AddEditTaskViewModel) güncellersiniz.

Android Studio'da sınıf tarayıcısını açın ve "AddEditTaskViewModel" yazın. Oluşturulan Kotlin dosyasını tıklayarak IDE'nizde açın.

Öncelikle ShortcutsRepository paketini aşağıdaki içe aktarma deyimiyle bu sınıfa ekleyin:

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

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

Daha sonra, sınıf oluşturucuyu aşağıdaki kodla güncelleyerek shortcutsRepository sınıf özelliğini ekleyin:

AddEditTaskViewModel.kt

//...

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

    //...

ShortcutsRepository sınıfı eklendikten sonra, bu sınıfı çağırmak için pushShortcut() adlı yeni bir işlev oluşturun. Aşağıdaki özel işlevi AddEditTaskViewModel gövdesine yapıştırın:

AddEditTaskViewModel.kt

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

Son olarak, bir görev oluşturulduğunda yeni bir dinamik kısayol aktarın. saveTask() işlevinin içeriğini aşağıdaki kodla değiştirin:

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

Kodunuzu test etme

Nihayet kodumuzu test etmeye hazırız! Bu adımda ses özellikli bir dinamik kısayolu aktarıp Google Asistan uygulamasını kullanarak bu kısayolu incelersiniz.

Önizleme oluşturma

Google Asistan eklentisini kullanarak önizleme oluşturmak, dinamik kısayollarınızın test cihazınızdaki Asistan'da görünmesini sağlar.

Test eklentisini yükleyin

Cihazınızda Google Asistan eklentisi yoksa Android Studio'da aşağıdaki adımları uygulayarak eklentiyi yükleyin:

  1. **Dosya > Ayarlar (MacOS'te Android Studio > Tercihler).
  2. Eklentiler bölümünde Marketplace'e gidin ve "Google Assistant" araması yapın.
  3. Aracı yükleyin ve Android Studio'yu yeniden başlatın.

Önizlemeyi oluşturma

Android Studio'da aşağıdaki adımları uygulayarak bir önizleme oluşturun:

  1. Araçlar'ı tıklayın > Google Asistan > "Uygulama İşlemleri Test Aracı".
  2. Uygulama adı kutusuna "Yapılacaklar Listesi" gibi bir ad tanımlayın.
  3. Önizleme Oluştur'u tıklayın. Sizden istenirse Uygulama İşlemleri politikalarını ve hizmet şartlarını inceleyip kabul edin.

Uygulama İşlemleri Test Aracı önizleme oluşturma bölmesi.

Şekil 3. Uygulama İşlemleri Test Aracı önizleme oluşturma bölmesi.

Test sırasında Asistan'a aktardığınız dinamik kısayollar, Asistan'da, önizleme için sağladığınız Uygulama adı'na göre düzenlenmiş olarak görünür.

Kısayolu aktarma ve inceleme

Test cihazınızda örnek uygulamayı yeniden başlatın ve aşağıdaki adımları uygulayın :

  1. "Codelab'i başlat" başlıklı yeni bir görev oluşturma
  2. Google Asistan uygulamasını açıp "Kısayollarım" deyin veya yazın.
  3. Keşfet sekmesine dokunun. Örnek kısayolu göreceksiniz.
  4. Çağrıyı başlatmak için kısayola dokunun. Uygulama, kısayolun adı filtre kutusuna önceden doldurulmuş olarak başlatılır. Böylece, istenen görev öğesini bulmanız kolaylaşır.

6. (İsteğe bağlı) Bir kısayolu güncelleme ve silme

Uygulamanız, çalışma zamanında yeni dinamik kısayollar aktarmanın yanı sıra bunları kullanıcı içeriğinizin ve tercihlerinizin mevcut durumunu yansıtacak şekilde güncelleyebilir. Kullanıcı hedef öğede değişiklik yaptığında (ör. örnek uygulamamızda bir görevi yeniden adlandırmak) mevcut kısayolları güncellemek iyi bir uygulamadır. Ayrıca kullanıcıya bozuk kısayollar gösterilmesini önlemek için hedef kaynak kaldırıldığında karşılık gelen bir kısayolu da silmeniz gerekir.

Kısayolu güncelleme

Kullanıcı bir görev öğesinin ayrıntılarını değiştirdiğinde dinamik kısayolu güncellemek için AddEditTaskViewModel politikasını değiştirin. Öncelikle, depo sınıfımızdan yararlanan bir güncelleme işlevi eklemek için sınıfın gövdesini aşağıdaki kodla güncelleyin:

AddEditTaskViewModel.kt

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

Ardından, mevcut bir görev güncellendiğinde yeni yöntemimizi çağırmak için saveTask() işlevini değiştirin.

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

Uygulamayı yeniden başlatıp aşağıdaki adımları uygulayarak kodunuzu test edin:

  1. Mevcut görev öğenizin başlığını "Codelab'i tamamla" olarak değiştirin.
  2. "Ok Google, kısayollarım" diyerek Google Asistan'ı açın.
  3. Keşfet sekmesine dokunun. Test kısayolunuz için güncellenmiş kısa bir etiket göreceksiniz.

Kısayolu kaldırma

Örnek uygulama kısayollarımız, kullanıcılar bir görevi sildiğinde kaldırılmalıdır. Örnek uygulamada, görev silme mantığı TaskDetailViewModel sınıfındadır. Bu sınıfı güncellemeden önce, shortcutsRepository sınıfını TaskDetailViewModel içine iletmek üzere ViewModelFactory uygulamasını tekrar güncellememiz gerekiyor.

ViewModelFactory klasörünü açın ve oluşturucu yönteminin içeriğini aşağıdaki kodla değiştirin:

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

Sonra TaskDetailViewModel uygulamasını açın. ShortcutsRepository modülünü içe aktarın ve aşağıdaki kodu kullanarak bir örnek değişkeni tanımlayın:

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

Son olarak, karşılık gelen taskId içeren bir görev silindiğinde kimliğine göre kısayolu kaldırmak için deleteTask() işlevini shortcutsRepository çağrısı yapacak şekilde değiştirin:

TaskDetailViewModel.kt

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

Kodunuzu test etmek için uygulamayı yeniden başlatın ve aşağıdaki adımları uygulayın:

  1. Test görevinizi silin.
  2. Mevcut görev öğenizin başlığını "Codelab'i tamamla" olarak değiştirin.
  3. "Ok Google, kısayollarım" diyerek Google Asistan'ı açın.
  4. Keşfet sekmesine dokunun. Test kısayolunuzun artık gösterilmediğinden emin olun.

7. Sonraki adımlar

Tebrikler! Sayenizde örnek uygulamamızın kullanıcıları, Asistan'a "Ok Google, exampleApp'te alışveriş listemi aç" gibi sorular sorarak oluşturdukları notlara kolayca geri dönebiliyor. Kısayollar, kullanıcıların uygulamanızda sık kullanılan işlemleri tekrar oynatmalarını kolaylaştırarak daha derin kullanıcı etkileşimini teşvik eder.

İşlediklerimiz

Bu codelab'de şunları öğrendiniz:

  • Bir uygulamada dinamik kısayolları aktarmaya ilişkin kullanım alanlarını tanımlayın.
  • Depo, bağımlılık ekleme ve hizmet konum belirleyicisi tasarım kalıplarını kullanarak kod karmaşıklığını azaltın.
  • Sesle etkinleştirilen dinamik kısayolları, kullanıcı tarafından oluşturulan uygulama içeriklerine aktarın.
  • Mevcut kısayolları güncelleyin ve kaldırın.

Sırada ne var?

Buradan Görev Listesi uygulamanızda daha fazla hassaslaştırma yapmayı deneyebilirsiniz. Bitmiş projeye referans vermek için GitHub'da kod deposunun –codelab-complete dalına bakın.

Aşağıda, Uygulama İşlemleri ile bu uygulamanın kapsamını genişletme hakkında daha fazla bilgi için bazı öneriler verilmiştir:

Actions on Google yolculuğunuza devam etmek için aşağıdaki kaynakları inceleyin:

En son duyurularımızı kaçırmamak için bizi @ActionsOnGoogle Twitter'da takip edin ve oluşturduğunuz içerikleri paylaşmak için #appActions'a tweet atın!

Geri bildirim anketi

Son olarak, bu codelab'deki deneyiminiz hakkında geri bildirimde bulunmak için lütfen bu anketi doldurun.