0

我首先创建一个 LoadingSlice,然后在通过 Rest API 加载切片内容后,使用“sliceUri”刷新切片。


    context.contentResolver.notifyChange(sliceUri, null)

我的代码在 App Action Test Tool 中运行良好,但无法通过 Google 助手运行。Google Assistent 正确创建了正在加载的 Slice,但在 API 调用后不会刷新已创建的 Slice 的内容。

动作.xml

    <?xml version ="1.0" encoding ="utf-8"?>
    <actions>
                  <action intentName="custom.actions.intent.CHECK_IN" queryPatterns="@array/ExampleInQueries">
             <fulfillment
                 fulfillmentMode="actions.fulfillment.SLICE"
                 urlTemplate="content://com.myapp.v3.slices.provider/checkin">
             </fulfillment>
    
         </action>
    
        </actions>

AndroidManifest.xml

<provider
    android:name=".slices.MySliceProvider"
    android:authorities="com.myapp.v3.slices.provider"
    android:grantUriPermissions="true"
    android:exported="true">

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.app.slice.category.SLICE" />
    </intent-filter>

</provider>

MySliceProvider.kt


    class MySliceProvider: SliceProvider()  {
    
        private lateinit var contextNonNull: Context
    
        override fun onCreateSliceProvider(): Boolean {
            contextNonNull = context ?: return false
    
            return true
        }
    
        companion object {
    
            internal const val SLICE_AUTHORITY = "com.myapp.v3.slices.provider"
            var contentLoaded = false
    
        }
    
        private val lastSlices = mutableMapOf<Uri, HCMSlice>()
    
    
        override fun onBindSlice(sliceUri: Uri): Slice {
            return lastSlices.getOrPut(sliceUri) { createNewSlice(sliceUri) }.getSlice()
          
        }
    
        private fun createNewSlice(sliceUri: Uri): HCMSlice {
            loadEnabled = false
    
            when (sliceUri.path) {
                
                DeepLink.CHECKINP -> {
                    return MyCheckSlice(
                        context = contextNonNull,
                        sliceUri = sliceUri
                    )
                }
                        else -> MySlice.Unknown(contextNonNull, sliceUri)
    
                
                
            }
    
        }
    
    }

MyCheckSlice.kt


    class MyCheckSlice(
        context: Context,
        sliceUri: Uri
    ) : MySlice(context, sliceUri), KodeinAware{
    override val kodein by kodein(context)
    private val authDataHandler: AuthDataHandler by instance()
    private val authSettings: AuthSettings by instance()
    private val dashboardRepository: DashboardRepository by instance()
    
    override fun getSlice(): Slice {
    
                fetchLeaveTypes()
    
        return if (contentLoaded) {
                createStatsSlice()
    
        } else {
            createLoadingSlice()
        }
    
    }
    
    private fun createStatsSlice(): Slice {
        return list(context, sliceUri, ListBuilder.INFINITY) {
            
            row {
                setTitle(context.getString(R.string.slice_success),false)
                setSubtitle("", false)
                primaryAction = createActivityAction()
            }
    
        }
    
    }
    
    private fun createLoadingSlice(): Slice = list(context, sliceUri, ListBuilder.INFINITY) {
        row {
              setTitle(context.getString(R.string.slice_processing),true)
              setSubtitle("", true)
    
            primaryAction = createActivityAction()
        }
    }
    
    private fun fetchShift() {
     
        authSettings.checkAuthorizationService(object :
            AuthStateResultListener {
            override fun onStateSuccess() {
    
                Coroutines.main {
                    try {
                        val getCalculateLeaveHoursResponse =  dashboardRepository.getShift(
                            getCurrentDate()!!
                        )
                        getCalculateLeaveHoursResponse.let {
    
                            val jObject = JSONObject(it.data.toString())
                     
                            val jObjShift = jObject.getJSONObject("shift")
                            shiftCode = jObjShift.getInt("shiftCode")
                            contentLoaded = true
                            refresh() 
    
                            return@main
                        }
    
                    } catch (e: ApiException) {
                        Log.e("TAG", "fetchShiftApiException")
                        saveTimeInOut()
                    } catch (e: NoInternetException) {
                        Log.e("TAG", "fetchShiftNoInternetException")
                    } catch (e: HTTPRequestException) {
                        Log.e("TAG", "fetchShiftHTTPRequestException")
                    } catch (e: ApiNocontentException) {
                        Log.e("TAG", "fetchShiftApiNocontentException")
                        saveTimeInOut()
                    }
                }
    
            }
    
            override fun onStateFailure() {
                Log.e("TAG", "fetchShiftonStateFailure")
            }
    
            override fun onStateSignout() {
                Log.e("TAG", "fetchShiftonStateSignout")
            }
    
        })
    
    }
    }

我的切片.kt


    abstract class MySlice(val context: Context, val sliceUri: Uri) {
        protected val handler = Handler(Looper.getMainLooper())
        abstract fun getSlice(): Slice
    
        
        protected fun refresh() {
            context.contentResolver.notifyChange(sliceUri, null)
        }
    
        protected fun createActivityAction(): SliceAction {
            val intent = Intent(context, MainActivity::class.java)
            return SliceAction.create(
                PendingIntent.getActivity(context, 0, intent, 0),
                IconCompat.createWithResource(context, R.drawable.ic_launcher),
                ListBuilder.SMALL_IMAGE,
                context.getString(R.string.slice_enter_app_hint)
            )
        }
    
        class Unknown(context: Context, sliceUri: Uri) : MySlice(context, sliceUri) {
    
            override fun getSlice(): Slice = list(context, sliceUri, ListBuilder.INFINITY) {
                
    
                row {
                    
                    title = context.getString(R.string.slice_uri_not_found)
                    
                    primaryAction = createActivityAction()
                }
    
                
                setIsError(true)
            }
        }
    }

使用 App Action Test 工具时的示例 LOG


    2021-05-21 18:09:19.780 11102-11120/com.myapp.v3 E/TAG: onSlicePinned
    2021-05-21 18:09:19.786 11102-11125/com.myapp.v3 E/TAG: onBindSlice
    2021-05-21 18:09:19.786 11102-11125/com.myapp.v3 E/TAG: createNewSlice
    2021-05-21 18:09:19.786 11102-11125/com.myapp.v3 E/TAG: content://com.myapp.v3.slices.provider/checkin
    2021-05-21 18:09:20.029 11102-11125/com.myapp.v3 E/TAG: contentLoaded=false
    2021-05-21 18:09:20.034 11102-11125/com.myapp.v3 E/TAG: createLoadingSlice
    2021-05-21 18:09:29.743 11102-11102/com.myapp.v3 E/TAG: fetchShift
    2021-05-21 18:09:29.752 11102-11125/com.myapp.v3 E/TAG: onBindSlice
    2021-05-21 18:09:29.753 11102-11125/com.myapp.v3 E/TAG: contentLoaded=true
    2021-05-21 18:09:29.753 11102-11125/com.myapp.v3 E/TAG: createStatsSlice

示例 LOG 使用 Google 助手时

 

    2021-05-21 18:10:26.831 11102-11120/com.myapp.v3 E/TAG: onSlicePinned
    2021-05-21 18:10:26.833 11102-11125/com.myapp.v3 E/TAG: onBindSlice
    2021-05-21 18:10:26.833 11102-11125/com.myapp.v3 E/TAG: createNewSlice
    2021-05-21 18:10:26.833 11102-11125/com.myapp.v3 E/TAG: content://com.myapp.v3.slices.provider/check?name=idcheckin
    2021-05-21 18:10:26.864 11102-11125/com.myapp.v3 E/TAG: contentLoaded=false
    2021-05-21 18:10:26.864 11102-11125/com.myapp.v3 E/TAG: createLoadingSlice
    2021-05-21 18:10:26.929 11102-11125/com.myapp.v3 E/TAG: onSliceUnpinned
    2021-05-21 18:10:27.542 11102-11102/com.myapp.v3 E/TAG: fetchShift

4

0 回答 0