3

Это моя настройка, когда я пытаюсь развернуть виджет изначально.Как выполнить обновление виджета службой после нажатия кнопки?

public class WeatherAppWidgetConfigure extends PreferenceActivity{ 
private List<WeatherForecast> weatherData = new ArrayList<WeatherForecast>(); 
private String city_url; 
private String city_key; 
OnSharedPreferenceChangeListener listener; 
int mAppWidgetId; 
WeatherForecast wfObj; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // Set the result to CANCELED. This will cause the widget host to cancel 
    // out of the widget placement if they press the back button. 
    setResult(RESULT_CANCELED); 

    addPreferencesFromResource(R.xml.prefs); 

    // Find the widget id from the intent. 
    Intent intent = getIntent(); 
    Bundle extras = intent.getExtras(); 
    if (extras != null) { 
     //Here I do some PreferenceActivity 
         mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, 
       AppWidgetManager.INVALID_APPWIDGET_ID); 
     System.out.println(mAppWidgetId); 
     SharedPreferences prefs = PreferenceManager. 
             getDefaultSharedPreferences(getBaseContext()); 

     listener = new SharedPreferences.OnSharedPreferenceChangeListener() { 
       public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 
         String key) { 
        SharedPreferences prefs = PreferenceManager. 
               getDefaultSharedPreferences(getBaseContext()); 


        city_url = prefs.getString("cities", 
          "http://www.yr.no/place/Nepal/Bagmati/Kathmandu/forecast.xml"); 
        //System.out.println(city_url); 
        if (city_url.contains("Kathmandu")) city_key = "Kathmandu"; 
        else if(city_url.contains("Växjö")) city_key = "Växjö"; 
        else city_key = "Los Angeles"; 

        try { 

         URL url = new URL(city_url); 
         WeatherReport report = WeatherHandler.getWeatherReport(url); 

         int count = 0; 
         for (WeatherForecast forecast : report) { 
          count++; 
          //System.out.println("Forecast "+count); 
          //System.out.println(forecast.toString()); 
          weatherData.add(forecast); 
         } 

         wfObj = weatherData.get(0); 
        } 
        catch (IOException ioe) { 
         ioe.printStackTrace(); 
        } 

        RemoteViews views = new RemoteViews(getBaseContext().getPackageName(), 
          R.layout.widget_layout); 

        String temp = new Integer(wfObj.getTemp()).toString()+"C"; 
        String date = wfObj.getStartYYMMDD(); 
        String rain = new Double(wfObj.getRain()).toString()+"mm/h"; 
        prefs.edit().putString("temp",temp).commit(); 
        prefs.edit().putString("date",date).commit(); 
        prefs.edit().putString("rain", rain).commit(); 

        views.setTextViewText(R.id.city, city_key); 
        views.setTextViewText(R.id.temp, prefs.getString("temp", "")); 
        views.setTextViewText(R.id.date, prefs.getString("date", "")); 
        views.setTextViewText(R.id.rain, prefs.getString("rain", "")); 
         AppWidgetManager appWidgetManager = AppWidgetManager. 
                  getInstance(getBaseContext()); 
        appWidgetManager.updateAppWidget(mAppWidgetId, views); 
        //System.out.println(temp +" "+date+" "+ rain); 

        // Make sure we pass back the original appWidgetId 
        Intent resultValue = new Intent(); 
        resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); 
        setResult(RESULT_OK, resultValue); 
        finish(); 

       } 
      }; 

     prefs.registerOnSharedPreferenceChangeListener(listener); 
    } 
       // If they gave us an intent without the widget id, just bail. 
    if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { 
     finish(); 
    } 



} 

} 

Теперь у меня есть свой класс провайдера здесь, где я хочу сделать виджет обновления (chhnge в TextView для, например) при нажатии на кнопку. общественного класса MyWeatherAppWidgetProvider расширяет AppWidgetProvider {

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
     int[] appWidgetIds) { 
    // TODO Auto-generated method stub 



    final int N = appWidgetIds.length; 
    Intent intent = new Intent(context.getApplicationContext(), 
             UpdateWeatherAppWidgetService.class); 
     intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); 
     PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(), 0, intent, 
       PendingIntent.FLAG_UPDATE_CURRENT); 
     RemoteViews remoteViews = new RemoteViews(context.getPackageName(), 
       R.layout.widget_layout); 

     remoteViews.setOnClickPendingIntent(R.id.button1, pendingIntent); 
     appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); 
    } 


} 

Далее я использую класс обслуживания, чтобы сделать это обновление. При этом для запуска я просто хочу, чтобы изменить один из этикетки TextView, просто чтобы посмотреть, как это работает

public class UpdateWeatherAppWidgetService extends Service { 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    System.out.println("called"); 
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this 
                  .getApplicationContext()); 
    Bundle extras = intent.getExtras(); 
    int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); 
    //other way 
    //int[] appWidgetIds =intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); 

    for(int widgetId : appWidgetIds){ 
     System.out.println(widgetId); 
    } 



    if (appWidgetIds.length > 0) { 
     for (int widgetId : appWidgetIds) { 
      RemoteViews remoteViews = new RemoteViews(getPackageName(), 
        R.layout.widget_layout); 
      remoteViews.setTextViewText(R.id.city, "BLAh"); 
      appWidgetManager.updateAppWidget(widgetId, remoteViews); 
     } 
     stopSelf(startId); 
    } 
    super.onStart(intent, startId); 
    return START_STICKY; 

} 

@Override 
public IBinder onBind(Intent arg0) { 
    // TODO Auto-generated method stub 
    return null; 
} 

}

Но я как-то не могу получить это сделать. Когда я использую context.startService (намерение) в классе провайдера, вызывает вызов класса сервиса. Но опять-таки этот текст в виджетах не меняется. Я не видел учебника, объясняющего как configure (при запуске), так и обновление виджета позже при щелчке пользователя. Поэтому я не уверен в моем подходе. У меня есть файл манифеста, как

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="assignment3.demos" 
    android:versionCode="1" 
    android:versionName="1.0"> 
<uses-sdk android:minSdkVersion="10" /> 


<application android:icon="@drawable/icon" android:label="@string/app_name"> 
    <uses-library android:name="com.google.android.maps"/> 
    <activity android:name=".MainListActivity" 
       android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <activity android:name="TheCityMap"></activity> 
    <activity android:name=".RoadMapActivity"></activity> 
    <activity android:name=".TheRoadMap"></activity> 
    <!-- <activity android:name="assignment3.demos.EditPrefs" android:label="Edit Preferences"/> --> 
    <!-- <activity android:name=".VaxjoWeather" android:label="Vaxjo Weather"/> --> 

    <activity android:name=".WeatherAppWidgetConfigure"> 
     <intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> 
     </intent-filter> 
    </activity> 

    <service android:enabled="true" android:name=".UpdateWeatherAppWidgetService"></service> 
    <receiver android:name="MyWeatherAppWidgetProvider"> 
     <intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
     </intent-filter> 
     <meta-data android:name="android.appwidget.provider" 
      android:resource="@xml/widgetproviderinfo" /> 
    </receiver> 


</application> 
<uses-permission android:name="android.permission.INTERNET" > </uses-permission> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" > </uses-permission> 
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" > </uses-permission> 

+0

Так я правильно говорю, что вы можете запустить Сервис, но Служба работает некорректно? –

+0

Когда я использую context.startService (намерение) в классе провайдера, класс сервиса вызывается при попытке развернуть виджет изначально. Позднее, когда я нажимаю кнопку, он не работает. – SASM

ответ

0

Это должно быть проблемой с этой линией поставщика виджетов

PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(), 0, intent, 
      PendingIntent.FLAG_UPDATE_CURRENT); 

Скорее всего проблема с «context.getApplicationContext()» Try используя несколько разных значений, таких как «Контекст», «Контекст», «getBaseContext()» или «this». Я не совсем уверен, что правильно, в подобной ситуации в моем приложении я использую «контекст», который работает для меня.

попробовать Также изменения

Intent intent = new Intent(context.getApplicationContext(), 
            UpdateWeatherAppWidgetService.class); 

к:

Intent intent = new Intent(context, UpdateWeatherAppWidgetService.class); 
+0

Я использовал PendingIntent pendingIntent = PendingIntent.getService (контекст, 0, намерение, 0); но этот тоже не работал – SASM

+0

Отредактировано с другим предложением, если это не работает, я из идей, извините! –

0

Эй я в андроид конечно здесь, в Ваксьо: D Для Вашего вопроса: я решил, что в AppWidgetProvider, а затем «переданы это к сервису "с некоторыми незначительными изменениями.

private static final String WIDGET_BUTTON = "com.example.ass3.WIDGET_BUTTON"; 

@Override 
    public int onStartCommand(Intent intent,int flag, int startId) { 


    System.out.println("inService"); 
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this 
      .getApplicationContext()); 

    RemoteViews views = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.main); 
    ComponentName watchWidget = new ComponentName(this.getApplicationContext(), WeatherWidget.class); 

     views.setOnClickPendingIntent(R.id.widget_refresh, myIntent(WIDGET_BUTTON,this.getApplicationContext())); 
     appWidgetManager.updateAppWidget(watchWidget, views); 





     stopSelf(startId); 

    return START_STICKY; 

    } 

protected PendingIntent myIntent(String button,Context context) { 
     Intent intent = new Intent(context, WeatherWidget.class); 
     intent.setAction(button); 
     return PendingIntent.getBroadcast(context, 0, intent, 0); 
    } 

И в виджете Provider

@Override 
    public void onReceive(Context context, Intent intent) { 
      super.onReceive(context, intent); 

      //Toast.makeText(context, "onReceiver()", Toast.LENGTH_LONG).show(); 
      //System.out.println("Intent get Action"+ intent.getAction()); 
     if (WIDGET_BUTTON.equals(intent.getAction())) { 

      AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 

       RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main); 
       ComponentName widget = new ComponentName(context, WeatherWidget.class); 


       remoteViews.setTextViewText(R.id.widget_curtemp, "20"); 
       remoteViews.setTextViewText(R.id.widget_minmaxtemp, "10/30"); 
       remoteViews.setImageViewResource(R.id.widget_image, R.drawable.sun); 
       remoteViews.setTextViewText(R.id.widget_city, "vaxjo"); 
       remoteViews.setTextViewText(R.id.widget_desc,"trying to refreshs"); 
       appWidgetManager.updateAppWidget(widget, remoteViews); 
      } 

    } 

и разрешение на обслуживание и разрешение принимать широковещательные в манифесте. Пожалуйста, не судите о моих устаревших значениях, которые я обновляю, я все еще пытаюсь выяснить, как правильно получить данные: D

Смежные вопросы