অ্যাপকার্ড কোডল্যাব ব্যবহার করে দেখুন

এই পৃষ্ঠাটি বর্ণনা করে কিভাবে একটি AppCard বাস্তবায়ন করতে হয়।

ধাপ 1: সমস্ত আমদানি যোগ করুন

  1. আমদানি যোগ করতে:

    static_libs: [
         …
         "car-app-card",
    ],
    

ধাপ 2: আপনার ম্যানিফেস্টে SimpleAppCardContentProvider যোগ করুন

  1. আপনার প্যাকেজের নামের সাথে android:authorities (বোল্ডে) প্রতিস্থাপন করতে ভুলবেন না।

    <!-- App Card Content Provider that is required to communicate
         relevant App Cards with the system
         android.car.permission.BIND_APP_CARD_PROVIDER is an essential permission
         that will only allow the system to communicate with the
         AppCardContentProvider
         The content provider must also be exported and enabled -->
         <provider android:name=".SimpleAppCardContentProvider"
             android:authorities="com.example.appcard.sample" 
             android:permission="@string/host_permission"
             android:exported="true"
             android:enabled="true">
             <intent-filter>
                <!-- This intent filter will allow the system to find and
                     connect with the application's AppCardContentProvider -->
                 <action android:name="com.android.car.appcard.APP_CARD_PROVIDER" />
                </intent-filter>
         </provider>
    

ধাপ 3: ম্যানিফেস্টে SimpleAppCardContentProvider যোগ করুন

  1. ম্যানিফেস্টে SimpleAppCardContentProvider যোগ করতে:

    class SimpleAppCardContentProvider : AppCardContentProvider() {
      /** Must return same authority as defined in manifest */
      override val authority: String = AUTHORITY
    
      /** Setup [AppCardContentProvider] and its constituents */
      override fun onCreate(): Boolean {
        return super.onCreate()
      }
    
      /** Setup an [AppCard] that is being requested */
      override fun onAppCardAdded(id: String, ctx: AppCardContext): AppCard {
        return when (id) {
          APPCARD_ID -> //TODO: create app card
    
          else -> throw IllegalStateException("Unidentified app card ID: $id")
        }
      }
    
      /** List of supported [AppCard] IDs */
       override val appCardIds: List<String> = listOf(APPCARD_ID).toMutableList()
    
      /** Clean up when an [AppCard] is removed */
      override fun onAppCardRemoved(id: String) {
        when (id) {
          APPCARD_ID -> //TODO: create app card
        }
      }
    
      /** Handle an [AppCardContext] change for a particular [AppCard] ID */
      override fun onAppCardContextChanged(
        id: String,
        appCardContext: AppCardContext
      ) {
         when (id) {
          APPCARD_ID -> //TODO: update AppCardContext
        }
      }
    
      companion object {
        private const val AUTHORITY = "com.example.appcard.sample"
        private const val APPCARD_ID = "sampleAppCard"
      }
    }
    

ধাপ 4: একটি AppCard তৈরি করুন

  1. একটি AppCard তৈরি করতে:

    override fun onAppCardAdded(id: String, ctx: AppCardContext): AppCard {
      return when (id) {
        APPCARD_ID -> createAppCard(ctx)
    
        else -> throw IllegalStateException("Unidentified app card ID: $id")
      }
    }
    
    private fun createAppCard(appCardContext: AppCardContext): ImageAppCard {
      return ImageAppCard.newBuilder(APPCARD_ID)
        .setPrimaryText("Hello")
        .setSecondaryText("World")
        .setHeader(
          Header.newBuilder("header")
            .setTitle("Code Lab")
            .build()
        )
        .addButton(
          Button.newBuilder(
            "button",
            Button.ButtonType.PRIMARY,
            object : OnClickListener {
              override fun onClick() {
                //no-op
              }
            }
          )
            .setText("Click me!")
            .build()
        )
       .build()
    }
    

যেমন:

একটি AppCard তৈরি করুন

চিত্র 1. একটি অ্যাপকার্ড তৈরি করুন।

ধাপ 5: বোতাম ক্লিকার সক্ষম করুন

ক্লিকার সক্ষম করতে:

   private var clickCounter = 0

   private fun createAppCard(appCardContext: AppCardContext): ImageAppCard {
      ...
       .addButton(
        Button.newBuilder(
          "button",
           Button.ButtonType.PRIMARY,
           object : OnClickListener {
             override fun onClick() {
               clickCounter++
               sendAppCardUpdate(createAppCard(appCardContext))
             }
           }
         )
           .setText(
             if (clickCounter == 0) "Click me!" else "Clicked: $clickCounter"
           )
           .build()
         )
      ...
    }

    override fun onAppCardRemoved(id: String) {
      when (id) {
        APPCARD_ID -> clickCounter = 0
      }
    }

যেমন:

বোতাম ক্লিকার সক্ষম করুন

চিত্র 2. বোতাম ক্লিকার সক্রিয় করুন।

ধাপ 6: হেডার ইমেজ আপডেট করুন

  1. হেডারে ইমেজ আপডেট করতে:

      private fun createAppCard(appCardContext: AppCardContext): ImageAppCard {
        val headerImageSize = appCardContext.imageAppCardContext.getMaxImageSize(Header::class.java)
        val logo = resToBitmap(
         android.R.drawable.ic_menu_compass,
           headerImageSize.width,
           headerImageSize.height
        )
    
     ...
       .setHeader(
         Header.newBuilder("header")
           .setTitle("Code Lab")
           .setImage(
             Image.newBuilder("image")
               .setContentScale(Image.ContentScale.FILL_BOUNDS)
               .setColorFilter(Image.ColorFilter.TINT)
               .setImageData(logo)
               .build()
           )
           .build()
        )
      ...
      }
    
      private fun resToBitmap(res: Int, width: Int, height: Int): Bitmap {
        val drawable = context?.getDrawable(res)
    
        return drawableToBitmap(drawable!!, width, height)
      }
    
      private fun drawableToBitmap(d: Drawable, width: Int, height: Int): Bitmap {
        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    
        val canvas = Canvas(bitmap)
        val left = 0
        val top = 0
        d.setBounds(left, top, canvas.width, canvas.height)
        d.draw(canvas)
    
        return bitmap
     }
     ```
    
    For example:
    
    ![Change the image in the header](/docs/automotive/unbundled_apps/appcards/images/ceramic-06.png)
    
    **Figure 3.** Change the name to the header.
    
  2. এটি সমর্থন করে এমন কোনও উপাদানে একটি চিত্র যুক্ত করতে এই প্রক্রিয়াটি পুনরাবৃত্তি করুন।

ধাপ 7: আরও মিথস্ক্রিয়া যোগ করুন

  1. নিয়ন্ত্রণ সহ একটি অগ্রগতি বার তৈরি করতে:

     private var progressOn = false
    
     private var progressTimer: Timer? = null
    
     private var progressCounter = 0
    
     override fun onAppCardRemoved(id: String) {
       when (id) {
         APPCARD_ID -> {
           clickCounter = 0
           progressCounter = 0
           progressTimer?.cancel()
         }
       }
     }
    
     private fun createAppCard(appCardContext: AppCardContext): ImageAppCard {
       val buttonImageSize = appCardContext.imageAppCardContext.getMaxImageSize(Button::class.java)
       val progressPlayPauseImage = resToBitmap(
         if (progressOn) {
           android.R.drawable.ic_media_pause
         } else {
           android.R.drawable.ic_media_play
         },
         buttonImageSize.width,
         buttonImageSize.height
       )
       ...
         .setProgressBar(
           createProgressBar()
         )
         .addButton(
           Button.newBuilder(
             "progressButton",
             Button.ButtonType.NO_BACKGROUND,
             object : OnClickListener {
               override fun onClick() {
                 progressOn = !progressOn
                 if (progressOn) {
                   progressTimer = Timer()
                   progressTimer?.scheduleAtFixedRate(object : TimerTask() {
                     override fun run() {
                     progressCounter++
                     if (progressCounter > 60) progressCounter = 0
                     sendAppCardComponentUpdate(APPCARD_ID, createProgressBar())
                   }
                 }, SECONDS_TO_MS, SECONDS_TO_MS)
               } else {
                 progressTimer?.cancel()
                 progressTimer = null
               }
               sendAppCardUpdate(createAppCard(appCardContext))
             }
           }
         )
           .setImage(
             Image.newBuilder("buttonImage")
               .setContentScale(Image.ContentScale.FILL_BOUNDS)
               .setColorFilter(Image.ColorFilter.TINT)
               .setImageData(progressPlayPauseImage)
               .build()
           )
           .build()
       )
     ...
     }
    
     private fun createProgressBar(): ProgressBar {
       return ProgressBar.newBuilder(PROGRESS_BAR_ID, 0, 60)
         .setProgress(progressCounter)
         .build()
     }
    
     companion object {
       ...
       private const val PROGRESS_BAR_ID = "progress"
       private const val SECONDS_TO_MS = 1000L
     }
    

আমরা অগ্রগতি বারে একটি প্লে বা পজ বোতাম যোগ করেছি যা প্রতি সেকেন্ডে আপডেট করা যেতে পারে। আকারের সীমাবদ্ধতার কারণে, ক্লিকের সংখ্যা প্রতিফলিত করতে ক্লিকার বোতামে setText দেখুন, .setText("$clickCounter")

চিত্র 4. একটি বোতাম যোগ করুন।

চিত্র 5. রেন্ডার করা বোতাম।

ধাপ 8: কার্যকলাপ চালু করুন

  1. যদি আপনার অ্যাপটি background-starts#exceptions সাথে সম্মত হয়, তাহলে আপনি বোতামের onClickListener থেকে একটি কার্যকলাপ চালু করতে পারেন।

    class SampleRoutingActivity : AppCompatActivity() {
      override fun onStart() {
        super.onStart()
        val intent = Intent(ACTION_LOCATION_SOURCE_SETTINGS).apply {
          setFlags(FLAG_ACTIVITY_CLEAR_TOP)
        }
        startActivity(intent)
        finish()
      }
    }
    
  2. কার্যকলাপ শুরু করতে, AppCard এ একটি বোতাম যোগ করুন। যদি কোনোটিই না থাকে, তাহলে আপনার অ্যাপে একটি রাউটিং কার্যকলাপ যোগ করুন:

    override fun onStart() {
    super.onStart()
    val intent = Intent(ACTION_LOCATION_SOURCE_SETTINGS).apply {
      setFlags(FLAG_ACTIVITY_CLEAR_TOP)
    }
    startActivity(intent)
    finish()
     }
    }
    

    যখন ক্লাস কল করা হয়, ব্যবহারকারীকে লোকেশন সেটিংসে পুনঃনির্দেশিত করা হয়। setFlags(FLAG_ACTIVITY_CLEAR_TOP) প্রয়োগ করা হয়েছে নিশ্চিত করার জন্য যে ব্যবহারকারী আসল কার্যকলাপে ফিরে যেতে না পারে।

  3. কার্যকলাপ শুরু করতে AppCard এ একটি বোতাম যোগ করুন:

     private fun createAppCard(appCardContext: AppCardContext): ImageAppCard {
       val locationImage = resToBitmap(
         android.R.drawable.ic_menu_call,
         buttonImageSize.width,
         buttonImageSize.height
       )
       ...
         .addButton(
           Button.newBuilder(
            "activityButton",
            Button.ButtonType.SECONDARY,
            object : OnClickListener {
              override fun onClick() {
                // no-op
              }
            }
           )
            .setImage(
              Image.newBuilder("locationButtonImage")
                .setContentScale(Image.ContentScale.FILL_BOUNDS)
                .setColorFilter(Image.ColorFilter.TINT)
                .setImageData(locationImage)
                .build()
            )
            .setIntent(
              RoutingActivityIntent
                .newBuilder("com.example.appcard.sample.SampleRoutingActivity")
                .build()
            )
            .build()
          )
        ...
    }
    

স্থানের সীমাবদ্ধতার কারণে, AppCard হোস্টে ক্লিকার বোতামটি সরানো হয়েছে। AppCard নিম্নরূপ প্রদর্শিত হয়:

বোতাম সরানো হয়েছে

চিত্র 6. ক্লিকার বোতাম ছাড়াই অ্যাপকার্ড।