微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 android:updatePeriodMillis="0" 时从 Flutter 更新 Android 小部件?

如何解决如何在 android:updatePeriodMillis="0" 时从 Flutter 更新 Android 小部件?

我是新来的。我正在慢慢掌握 Flutter 的窍门,但我完全是 Kotlin/Java 集成方面的新手。我正在尝试制作一个 Flutter 应用程序,其中一些数据在 Flutter istelf 中不定期更新,然后显示在主屏幕小部件上。

我不想定期更新 Android 小部件,因为每天可能不会有任何更改,但只是偶尔更新。在寻找实际制作小部件的方法时,我发现了这个 really helpful answer from bnxm一个很好的 implementation on Github from timobaehr

以此为例,如果我想在应用程序中的按钮被按下(或后台服务运行)时更新主屏幕小部件上显示的“结果”,而不是在一组间隔? Timobaehr 在他的演示中使用了认的 Flutter 计数应用程序,那么我可以对按下按钮时运行的这段代码做什么?

这里是 main.dart 中的更新函数

from sklearn.base import BaseEstimator,TransformerMixin
class data_cleaner(BaseEstimator,TransformerMixin):
    def __init__(self,cat_data,num_data):
        self.cat_data = cat_data
        self.num_data = num_data
        
    def process_data(self,num_data):
        cat_data = []
        num_data = []
        for i,c in enumerate(X.dtypes):
            if c == object:
                cat_data.append(X.iloc[:,i])
            else :
                num_data.append(X.iloc[:,i]
        cat_data = pd.DataFrame(cat_data).transpose()
        num_data = pd.DataFrame(num_data).transpose()
        #filling the missing categorical data
        cat_data = cat_data.apply(lambda value:value.fillna(value.value_counts().index[0]))
        #mapping the data on the loan_status
        target = {'Y': '1','N': '0'}
        loan_status = cat_data['Loan_Status']
        #dropping the loan_status from cat_data
        cat_data.drop('Loan_Status',inplace=True,axis=1)
        #mapping loan_status wrt target
        loan_status = loan_status.map(target)
        #changing the cat_data into numerical values
        from sklearn.preprocessing import LabelEncoder
        encoder = LabelEncoder()
        for value in cat_data:
            cat_data[value] = encoder.fit_transform(cat_data[value])
         # Numerical data
        # Fill every missing value with their prevIoUs value in the same column.

        num_data.fillna(method='bfill',inplace=True)
        #joining the cat_data and num_data
    
    def transform(self,X,y=None):        
        X = pd.concat([cat_data,num_data,loan_status],axis=1)
                                                    
    def fit(self,*_):
        return self

下面是代码中更新值的地方,基于认的 Flutter 启动应用程序。我还将 void onWidgetUpdate() { WidgetsFlutterBinding.ensureInitialized(); const MethodChannel channel = MethodChannel('com.example.app/widget'); channel.setMethodCallHandler( (call) async { final id = call.arguments; print('on Dart ${call.method}!'); return { 'id': id,// Some data of type int - this is what I want to update 'value': counter,}; },); } 移到了 dart 文件的顶部,以便它可以随处使用。

int counter = 0;

是在此处添加一些东西那么简单,还是需要在其他地方更改 Kotlin 代码?感谢您的帮助。

编辑:我应该说,从 increment 函数调用 onWidgetUpdate() 根本不会改变小部件,所以我认为一定有其他事情需要发生,也许在后台 Kotlin 代码中或使用 MethodChannels,我不熟悉。

如果你想自己运行它来测试,我从 timobaehr's Github project 克隆,只是将 'value' 更改为来自 'counter' 并且是 int 而不是 double。

解决方法

好吧,我想我明白了。把它贴在这里,以防它对其他人有帮助。

正如我所怀疑的那样,在 Kotlin 中必须改变一些东西。所以对我来说有点额外的学习!如果您跟随 timobaehr's project on Github,您可以尝试进行如下更改:

我编写了一个名为“updateFromFlutter”的新方法并将其添加到 MainActivity.kt:

when (call.method) {
            "initialize" -> {
                if (call.arguments == null) return
                WidgetHelper.setHandle(this,call.arguments as Long)
            }
            "updateFromFlutter" -> {
                val views = RemoteViews(context.packageName,R.layout.widget_layout).apply {
                    setTextViewText(R.id.text,call.argument("text"))
                }

                val id: Int = call.argument("id")!!

                val manager = AppWidgetManager.getInstance(this)
                manager.updateAppWidget(id,views)
            }
        }

记得在 MainActivity.kt 的顶部导入这些:

import android.widget.RemoteViews
import com.example.flutter_app_android_widget.R
import android.appwidget.AppWidgetManager

并在更新计数器值后从 main.dart 调用它:

const MethodChannel platform = MethodChannel('com.example.flutter_app_android_widget/widget');
platform.invokeMethod("updateFromFlutter",{
    "text": counter.toString(),"id": //get the integer from Shared Preferences - up to you how you do this
          //or feel free to suggest a better way of keeping track of the widget id
  });

然后,您应该可以通过按下 Flutter 应用中的按钮来按需更新主屏幕小部件。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。