【问题标题】:Android - Get value from Service and using it in WidgetAndroid - 从服务中获取价值并在小部件中使用它
【发布时间】:2018-05-28 16:08:23
【问题描述】:

我正在开发一个简单的C# Android 应用程序,它在后台运行并进行特定的计算,我还有一个带有 TexTview 的小部件,我想在其中显示计算结果。

Service.cs

Intent intent = new Intent("TEST");
intent.PutExtra("alltotale", total.ToString());
this.SendBroadcast(intent);

然后在BroadcastReceiver 类中,我有:

Receiver.cs

 public override void OnReceive(Context context, Intent intent)
    {
        string nh = intent.GetStringExtra("alltotale");
        Toast.MakeText(context, nh, ToastLength.Short).Show();
    }

现在我想重新使用此值并将其显示在小部件 TextView 中,但它不起作用,我的 Widget 中什么也没有。

AppWidget.cs

[BroadcastReceiver(Label = "Widget1")]
[IntentFilter(new string[] { "android.appwidget.action.APPWIDGET_UPDATE" })]
[MetaData("android.appwidget.provider", Resource = "@xml/appwidgetprovider")]
public class AppWidget : AppWidgetProvider
{
    Intent intent;
    public override void OnUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
    {
        var me = new ComponentName(context, Java.Lang.Class.FromType(typeof(AppWidget)).Name);
        appWidgetManager.UpdateAppWidget(me, BuildRemoteViews(context, appWidgetIds));

    }
    private RemoteViews BuildRemoteViews(Context context, int[] appWidgetIds)
    {
        var widgetView = new RemoteViews(context.PackageName, Resource.Layout.Widget);

        SetTextViewText(widgetView);
        RegisterClicks(context, appWidgetIds, widgetView);

        return widgetView;
    }
    private void SetTextViewText(RemoteViews widgetView)
    {
        string oo = intent.GetStringExtra("alltotale");
        widgetView.SetTextViewText(Resource.Id.widgetMedium, "Dabboussi");
        widgetView.SetTextViewText(Resource.Id.widgetSmall, oo);
    }
    private static string AnnouncementClick = "AnnouncementClickTag";
    private void RegisterClicks(Context context, int[] appWidgetIds, RemoteViews widgetView)
    {
        var intent = new Intent(context, typeof(AppWidget));
        intent.SetAction(AppWidgetManager.ActionAppwidgetUpdate);
        intent.PutExtra(AppWidgetManager.ExtraAppwidgetIds, appWidgetIds);

        // Register click event for the Background
        var piBackground = PendingIntent.GetBroadcast(context, 0, intent, PendingIntentFlags.UpdateCurrent);
        widgetView.SetOnClickPendingIntent(Resource.Id.widgetAnnouncementIcon, GetPendingSelfIntent(context, AnnouncementClick));
    }
    private PendingIntent GetPendingSelfIntent(Context context, string action)
    {
        var intent = new Intent(context, typeof(AppWidget));
        intent.SetAction(action);
        return PendingIntent.GetBroadcast(context, 0, intent, 0);
    }
    public override void OnReceive(Context context, Intent intent)
    {
        base.OnReceive(context, intent);
        var data = intent.GetStringExtra("alltotale");

        if (data != null)
        {
            var updateViews = new RemoteViews(context.PackageName, Resource.Layout.Widget);
            SetTextViewText(updateViews);
            ComponentName thisWidget = new ComponentName(context, Java.Lang.Class.FromType(typeof(AppWidget)).Name);
            AppWidgetManager manager = AppWidgetManager.GetInstance(context);
            manager.UpdateAppWidget(thisWidget, updateViews);
        }
        if (AnnouncementClick.Equals(intent.Action))
        {
            Toast.MakeText(context, "OPEN", ToastLength.Short).Show();
            // Open another app
        }
    }
}

因此,该值显示在后台的 Toast 消息中,但小部件 textview 中没有任何内容。为什么会这样,我该如何解决?

编辑

我认为也许ISharedPreferences 会成功,所以我做了以下事情:

Service.cs

Intent priceIntent = new Intent("com.xamarin.example.TEST");
priceIntent.PutExtra("alltotale", total.ToString());
this.SendBroadcast(priceIntent);
ISharedPreferences prSer = PreferenceManager.GetDefaultSharedPreferences(this);
ISharedPreferencesEditor prEd = prSer.Edit();
prEd.PutInt("PriceTot", Convert.ToInt32(total));

然后在 AppWidget.cs 文件中,我执行了以下操作:

  [BroadcastReceiver(Label = "Widget1")]
  [IntentFilter(new string[] { "android.appwidget.action.APPWIDGET_UPDATE", "com.xamarin.example.TEST" })]
[MetaData("android.appwidget.provider", Resource = "@xml/appwidgetprovider")]
public class AppWidget : AppWidgetProvider
{
    Intent intent;
    public override void OnUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
    {
        var me = new ComponentName(context, Java.Lang.Class.FromType(typeof(AppWidget)).Name);
        appWidgetManager.UpdateAppWidget(me, BuildRemoteViews(context, appWidgetIds));

    }
    private RemoteViews BuildRemoteViews(Context context, int[] appWidgetIds)
    {
        var widgetView = new RemoteViews(context.PackageName, Resource.Layout.Widget);

        //SetTextViewText(widgetView);
        RegisterClicks(context, appWidgetIds, widgetView);

        return widgetView;
    }
    private void SetTextViewText(RemoteViews widgetView)
    {
            widgetView.SetTextViewText(Resource.Id.widgetMedium, "Don Dabboussi");
            widgetView.SetTextViewText(Resource.Id.widgetSmall, "KK");
   }
    private static string AnnouncementClick = "AnnouncementClickTag";
    private void RegisterClicks(Context context, int[] appWidgetIds, RemoteViews widgetView)
    {
        var intent = new Intent(context, typeof(AppWidget));
        intent.SetAction(AppWidgetManager.ActionAppwidgetUpdate);
        intent.PutExtra(AppWidgetManager.ExtraAppwidgetIds, appWidgetIds);

        // Register click event for the Background
        var piBackground = PendingIntent.GetBroadcast(context, 0, intent, PendingIntentFlags.UpdateCurrent);
        //widgetView.SetOnClickPendingIntent(Resource.Id.widgetAnnouncementIcon, GetPendingSelfIntent(context, AnnouncementClick));
    }
    private PendingIntent GetPendingSelfIntent(Context context, string action)
    {
        var intent = new Intent(context, typeof(AppWidget));
        intent.SetAction(action);
        return PendingIntent.GetBroadcast(context, 0, intent, 0);
    }
    public override void OnReceive(Context context, Intent intent)
    {
        base.OnReceive(context, intent);
        ISharedPreferences prSer = PreferenceManager.GetDefaultSharedPreferences(context);
        var data = prSer.GetInt("PriceTot", 0);
        if (data != 0)
        {
            var updateViews = new RemoteViews(context.PackageName, Resource.Layout.Widget);
            SetTextViewText(updateViews);
            ComponentName thisWidget = new ComponentName(context, Java.Lang.Class.FromType(typeof(AppWidget)).Name);
            AppWidgetManager manager = AppWidgetManager.GetInstance(context);
            manager.UpdateAppWidget(thisWidget, updateViews);
        }
        if (AnnouncementClick.Equals(intent.Action))
        {
            Toast.MakeText(context, "OPEN", ToastLength.Short).Show();
            // Open another app
        }
    }

但这没有用,我的小部件的文本视图中没有文本(没有dabboussi 也没有kk)。这是为什么呢?

【问题讨论】:

    标签: c# android visual-studio xamarin widget


    【解决方案1】:

    你输入了一个名为alltotale的字符串,然后你要求一个名为widgetTotale的字符串,所以如果它不起作用是正常的。您必须将widgetTotale 更改为alltotale

    【讨论】:

    • 是的,这是拼写错误,在我的应用程序中我正确询问了alltotale,但它不起作用
    【解决方案2】:

    您需要获取AppWidgetManager 并调用UpdateAppWidget() 方法来更新小部件。

    例如:

        public override void OnReceive(Context context, Intent intent)
        {
            base.OnReceive(context, intent);
    
            var data = intent.GetStringExtra("alltotale");
    
            if(data != null)
            {
                var updateViews = new RemoteViews(context.PackageName, Resource.Layout.widget);
                SetTextViewText(updateViews, intent);
                // Push update for this widget to the home screen
                ComponentName thisWidget = new ComponentName(context, Java.Lang.Class.FromType(typeof(MyWidget)).Name);
                AppWidgetManager manager = AppWidgetManager.GetInstance(context);
                manager.UpdateAppWidget(thisWidget, updateViews);
            }
        }
    
        private void SetTextViewText(RemoteViews widgetView, Intent intent)
        {
            string oo = intent.GetStringExtra("alltotale");
            widgetView.SetTextViewText(Resource.Id.widgetMedium, "Dabboussi");
            widgetView.SetTextViewText(Resource.Id.widgetSmall, oo);
        }
    

    您可以参考此official demo 了解更多信息。

    【讨论】:

    • 没用。我已经编辑了我的代码:我在AppWidget.cs 中添加了“OnReceive”方法,但是当我单击小部件时,什么也没有发生,应该显示一条Toast 消息说打开。怎么了?
    • @Wassim01 您的AppWidget.cs 中的OnReceive() 方法是否在服务发送广播时触发?
    • 不,没有。
    • @Wassim01 您注册了您的小部件吗?
    • 是的,我将为AppWidget.cs 提供我的全部代码。请看一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多