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爲eg)。 公共類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(intent)時,服務類被調用。但是,這個widget上的這個textview也不會改變。我還沒有看過解釋配置(在啓動時)和稍後在用戶單擊時更新小部件的教程。所以我不確定我的方法。我有我的清單文件作爲

<?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

所以我說的是你能夠啓動服務,但服務工作不正常? – 2012-01-08 16:27:58

+0

當我在提供者類中使用context.startService(intent)時,服務類在試圖部署widget時被調用。當我點擊按鈕時它不起作用。 – SASM 2012-01-08 16:34:22

回答

0

它必須與這條線在你的微件提供者的一個問題

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

最有可能與「context.getApplicationContext()」 嘗試一個問題使用一些不同的值,例如「Context」,「context」,「getBaseContext()」或「this」。我不完全確定哪個是正確的,在我的應用程序的類似情況下,我使用「上下文」,這對我很有用。

也可以嘗試改變

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

到:

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

我使用PendingIntent pendingIntent = PendingIntent.getService(context,0,intent,0);但這一個沒有工作 – SASM 2012-01-08 16:55:06

+0

編輯與另一個建議,如果這不起作用我出來的想法,對不起! – 2012-01-08 17:02:17

0

嘿,我是在你的Android當然這裏韋克舍: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); 
    } 

而在你的微件提供

@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