Android App Widget 中按钮单击无法启动服务

发布于 2024-09-03 05:32:32 字数 4111 浏览 1 评论 0原文

我在启动服务来更新我作为练习创建的 AppWidget 时遇到问题。我正在尝试从 DDMS 获取欺骗位置数据的纬度和经度以显示在小部件中。该小部件使用一项服务来更新 TextView,这可能有点过大,但我想遵循在完成更多工作的 AppWidget 中常见的模板(例如 Forecast 小部件或 Wiktionary 小部件)。

现在,我没有收到任何错误消息或奇怪的行为;按下按钮时什么也不会发生。我对可能出了什么问题感到有点困惑。有人能指出我正确的方向吗?

此外,如果我的位置逻辑有错误,我也希望得到相关建议。我看过几个博客、Google 示例和文档,但我对它的工作原理感到有点模糊。

这是小部件的当前状态:

public class Widget extends AppWidgetProvider
{
    static final String TAG = "Widget"; 
    /**
     * {@inheritDoc}
     */
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                        int[] appWidgetIds)
    {
        // Create an intent to launch the service
        Intent serviceIntent = new Intent(context, UpdateService.class);

        // PendingIntent is required for the onClickPendingIntent that actually
        // starts the service from a button click
        PendingIntent pendingServiceIntent = 
            PendingIntent.getService(context, 0, serviceIntent, 0);

        // Get the layout for the App Widget and attach a click listener to the
        // button
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
        views.setOnClickPendingIntent(R.id.address_button, pendingServiceIntent);
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    // To prevent any ANR timeouts, we perform the update in a service;
    // really should have its own thread too
    public static class UpdateService extends Service
    {
        static final String TAG = "UpdateService"; 
        private LocationManager locationManager;
        private Location currentLocation;
        private double latitude;
        private double longitude;

        public void onStart(Intent intent, int startId)
        {
            // Get a LocationManager from the system services
            locationManager = 
                (LocationManager) getSystemService(Context.LOCATION_SERVICE);

            // Register for updates from spoofed GPS
            locationManager.requestLocationUpdates("gps", 30000L, 0.0f, new LocationListener()
            {
                @Override
                public void onLocationChanged(Location location)
                {
                    currentLocation = location;
                }

                @Override
                public void onProviderDisabled(String provider) {}

                @Override
                public void onProviderEnabled(String provider) {}

                @Override
                public void onStatusChanged(String provider, int status,
                        Bundle extras) {}       
            });
            // Get the last known location from GPS
            currentLocation = 
                locationManager.getLastKnownLocation("gps");

            // Build the widget update
            RemoteViews updateViews = buildUpdate(this);

            // Push update for this widget to the home screen
            ComponentName thisWidget = new ComponentName(this, Widget.class);

            // AppWidgetManager updates AppWidget state; gets information about 
            // installed AppWidget providers and other AppWidget related state 
            AppWidgetManager manager = AppWidgetManager.getInstance(this);

            // Updates the views based on the RemoteView returned from the
            // buildUpdate method (stored in updateViews)
            manager.updateAppWidget(thisWidget, updateViews);
        }

        public RemoteViews buildUpdate(Context context)
        {
            latitude = currentLocation.getLatitude();
            longitude = currentLocation.getLongitude();
            RemoteViews updateViews = 
                new RemoteViews(context.getPackageName(), R.layout.main);
            updateViews.setTextViewText(R.id.latitude_text, "" + latitude);
            updateViews.setTextViewText(R.id.longitude_text, "" + longitude);
            return updateViews;
        }

        @Override
        public IBinder onBind(Intent intent) {
            // We don't need to bind to this service
            return null;
        }
    }

}

I'm having trouble starting a Service to update an AppWidget that I'm creating as an exercise. I'm trying to get the latitude and longitude of spoofed location data from DDMS to display in the widget. The widget uses a service to update the TextView, which may be slightly overkill, but I wanted to follow the template that seems to be common in AppWidgets that do more work (like the Forecast widget or the Wiktionary widget).

Right now, I'm not getting any error messages or strange behavior; nothing at all happens when the button is pressed. I'm a bit mystified as to what might be wrong. Could anyone out there point me in the right direction?

Additionally, if my logic for location is faulty, I'd love recommendations on that too. I've looked at several blogs, the Google examples, and the documentation, but I feel a little fuzzy on how it works.

Here is the current state of the widget:

public class Widget extends AppWidgetProvider
{
    static final String TAG = "Widget"; 
    /**
     * {@inheritDoc}
     */
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                        int[] appWidgetIds)
    {
        // Create an intent to launch the service
        Intent serviceIntent = new Intent(context, UpdateService.class);

        // PendingIntent is required for the onClickPendingIntent that actually
        // starts the service from a button click
        PendingIntent pendingServiceIntent = 
            PendingIntent.getService(context, 0, serviceIntent, 0);

        // Get the layout for the App Widget and attach a click listener to the
        // button
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
        views.setOnClickPendingIntent(R.id.address_button, pendingServiceIntent);
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    // To prevent any ANR timeouts, we perform the update in a service;
    // really should have its own thread too
    public static class UpdateService extends Service
    {
        static final String TAG = "UpdateService"; 
        private LocationManager locationManager;
        private Location currentLocation;
        private double latitude;
        private double longitude;

        public void onStart(Intent intent, int startId)
        {
            // Get a LocationManager from the system services
            locationManager = 
                (LocationManager) getSystemService(Context.LOCATION_SERVICE);

            // Register for updates from spoofed GPS
            locationManager.requestLocationUpdates("gps", 30000L, 0.0f, new LocationListener()
            {
                @Override
                public void onLocationChanged(Location location)
                {
                    currentLocation = location;
                }

                @Override
                public void onProviderDisabled(String provider) {}

                @Override
                public void onProviderEnabled(String provider) {}

                @Override
                public void onStatusChanged(String provider, int status,
                        Bundle extras) {}       
            });
            // Get the last known location from GPS
            currentLocation = 
                locationManager.getLastKnownLocation("gps");

            // Build the widget update
            RemoteViews updateViews = buildUpdate(this);

            // Push update for this widget to the home screen
            ComponentName thisWidget = new ComponentName(this, Widget.class);

            // AppWidgetManager updates AppWidget state; gets information about 
            // installed AppWidget providers and other AppWidget related state 
            AppWidgetManager manager = AppWidgetManager.getInstance(this);

            // Updates the views based on the RemoteView returned from the
            // buildUpdate method (stored in updateViews)
            manager.updateAppWidget(thisWidget, updateViews);
        }

        public RemoteViews buildUpdate(Context context)
        {
            latitude = currentLocation.getLatitude();
            longitude = currentLocation.getLongitude();
            RemoteViews updateViews = 
                new RemoteViews(context.getPackageName(), R.layout.main);
            updateViews.setTextViewText(R.id.latitude_text, "" + latitude);
            updateViews.setTextViewText(R.id.longitude_text, "" + longitude);
            return updateViews;
        }

        @Override
        public IBinder onBind(Intent intent) {
            // We don't need to bind to this service
            return null;
        }
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

临风闻羌笛 2024-09-10 05:32:32

尝试将最后一个参数设置为

  PendingIntent.getService(context, 0, serviceIntent, 0);

  PendingIntent.getService(context, 0, serviceIntent, Intent.FLAG_ACTIVITY_NEW_TASK);

另外,有时您需要将 addData 添加到您的 Android 意图中,以将其区分为新内容,这有点 hacky,但似乎可行,因此添加:

  serviceIntent.setData(Uri.parse("uri::somethingrandomandunique");

Try setting the last parameter of

  PendingIntent.getService(context, 0, serviceIntent, 0);

to:

  PendingIntent.getService(context, 0, serviceIntent, Intent.FLAG_ACTIVITY_NEW_TASK);

Also sometimes you need to addData to your intent for Android to distinguish it as something new, this is a bit hacky but seems to work so add:

  serviceIntent.setData(Uri.parse("uri::somethingrandomandunique");
爱已欠费 2024-09-10 05:32:32
 PendingIntent pendingIntent = PendingIntent.getService(context, 0, startServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    remoteViews.setOnClickPendingIntent(R.id.start_service_btn_widget, pendingIntent);

appWidgetManager.updateAppWidget必须调用,否则点击事件不会响应

    appWidgetManager.updateAppWidget(componentName, remoteViews); 
 PendingIntent pendingIntent = PendingIntent.getService(context, 0, startServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    remoteViews.setOnClickPendingIntent(R.id.start_service_btn_widget, pendingIntent);

appWidgetManager.updateAppWidgetmust be call , or click event won't response

    appWidgetManager.updateAppWidget(componentName, remoteViews); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文