2014-02-06 32 views
1

我試着搜索關於StackView Widget的信息,我發現很多,但沒有人用來從url獲取數據。 所以問題是,當我正在處理url時,我的RemoteViews是空的,所以他們不顯示任何東西。一旦這個過程完成,我想更新,從asyntask RemoteViews(有在同一類)。 我該怎麼做?或同步它們?在StackView Widget中使用RemoteViews的AsynTask

這裏是我的小部件服務代碼:

public class RSSService extends RemoteViewsService { 

private ManagerRSS mr; 
private Cursor c; 
private int lenght; 
private List<Provider> mWidgetItems = new ArrayList<Provider>(); 
private RemoteViews rv = null; 
public ArrayList<Item> result = new ArrayList<Item>(); 
private boolean isFinished = false; 

@Override 
public void onCreate() { 
    // TODO Auto-generated method stub 
    mr = new ManagerRSS(this.getApplicationContext()); 
    mr.open(); 
    mr.openRead(); 
    c = mr.getCursor(); 
    lenght = c.getCount(); 
} 

@Override 
public void onDestroy() { 
    // TODO Auto-generated method stub 
    c.close(); 
    mr.close(); 
    super.onDestroy(); 
} 

@Override 
public RemoteViewsFactory onGetViewFactory(Intent intent) { 
    // TODO Auto-generated method stub 
    return new RSSRemoteViewsFactory(this.getApplicationContext(), intent); 
} 

class RSSRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory{ 

    private Context mContext; 
    private int mAppWidgetId; 


    public RSSRemoteViewsFactory(Context applicationContext, Intent intent) { 
     // TODO Auto-generated constructor stub 
     mContext = applicationContext; 
     mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 
       AppWidgetManager.INVALID_APPWIDGET_ID); 
    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return lenght; 
    } 

    @Override 
    public long getItemId(int arg0) { 
     // TODO Auto-generated method stub 
     return arg0; 
    } 

    @Override 
    public RemoteViews getLoadingView() { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public RemoteViews getViewAt(int position) { 
     if(isFinished){ 
      rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item); 
      rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).getTitle()); 
      if(mWidgetItems.get(position).getTitle().equals("El Pais")){ 
       rv.setImageViewResource(R.id.iNotice, R.drawable.elpais); 
      }else if(mWidgetItems.get(position).getTitle().equals("Marca")){ 
       rv.setImageViewResource(R.id.iNotice, R.drawable.marca); 
      }else if(mWidgetItems.get(position).getTitle().equals("As")){ 
       rv.setImageViewResource(R.id.iNotice, R.drawable.as1); 
      }else if(mWidgetItems.get(position).getTitle().equals("Ideal")){ 
       rv.setImageViewResource(R.id.iNotice, R.drawable.ideal); 
      }else{ 
       rv.setImageViewResource(0, R.drawable.undefined); 
      } 
      rv.setTextViewText(R.id.tvLastNotice, result.get(position).getTitle()); 
      rv.setTextViewText(R.id.tvLastNoticePublish, result.get(position).getPubDate()); 
      Bundle extras = new Bundle(); 
      extras.putString(Widget.NAME_DIARY, mWidgetItems.get(position).getTitle()); 
      Intent fillInIntent = new Intent(); 
      fillInIntent.putExtras(extras); 
      rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); 
      try { 
       System.out.println("Loading view " + position); 
       Thread.sleep(500); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      return rv; 
     }else{ 
      return null; 
     } 

    } 

    @Override 
    public int getViewTypeCount() { 
     // TODO Auto-generated method stub 
     return 1; 
    } 

    @Override 
    public boolean hasStableIds() { 
     // TODO Auto-generated method stub 
     return true; 
    } 

    @Override 
    public void onCreate() { 
     while(c.moveToNext()){ 
      String title = c.getString(c.getColumnIndex(Contrato.TableRSS.TITLE)); 
      String link = c.getString(c.getColumnIndex(Contrato.TableRSS.LINK)); 
      long _id = c.getLong(c.getColumnIndex(Contrato.TableRSS._ID)); 
      mWidgetItems.add(new Provider(_id, title, link)); 
      executeThread(link, c.getPosition()); 
     } 
    } 

    void executeThread(String type_link,int position){ 
     myThread exe = new myThread(); 
     exe.setOnlyFirst(true); 
     exe.execute(new String[]{type_link}); 
    } 

    private class myThread extends MyAsyncTask{ 

     @Override 
     protected void onPostExecute(ArrayList<Item> result2) { 
      // TODO Auto-generated method stub 
      super.onPostExecute(result2); 
      for(int i=0;i<result2.size();i++) result.add(result2.get(i)); 
      if(result.size()+1 == c.getCount()) isFinished = true; 
     } 
    } 

    @Override 
    public void onDataSetChanged() { 

    } 

    @Override 
    public void onDestroy() {mWidgetItems.clear();} 

} 

}

這是我WidgetProvider:

public class Widget extends AppWidgetProvider{ 

public static final String ON_TOUCH = "com.cool.nightrss.ON_TOUCH"; 
public static final String ID_DIARY = "com.cool.nightrss.ID_DIARY"; 
public static final String ID_NOTICE = "com.cool.nightrss.ID_NOTICE"; 
public static final String NAME_DIARY = "com.cool.nightrss.NAME_DIARY"; 
public static final String LINK_NOTICE = "com.cool.nightrss.LINK_NOTICE"; 

@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 
    if (intent.getAction().equals(ON_TOUCH)) { 
     int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 
       AppWidgetManager.INVALID_APPWIDGET_ID); 
     String name = intent.getStringExtra(NAME_DIARY); 
     Toast.makeText(context, "Touched view " + name +" ID "+appWidgetId, Toast.LENGTH_SHORT).show(); 
    } 
    super.onReceive(context, intent); 
} 

@SuppressWarnings("deprecation") 
@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
     int[] appWidgetIds) { 
    // TODO Auto-generated method stub 
    for (int i = 0; i < appWidgetIds.length; ++i) { 

     Intent intent = new Intent(context, RSSService.class); 
     intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); 

     intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); 
     RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout); 
     rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent); 

     Intent toastIntent = new Intent(context, Widget.class); 
     toastIntent.setAction(Widget.ON_TOUCH); 
     toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); 
     intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); 
     PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent, 
       PendingIntent.FLAG_UPDATE_CURRENT); 
     rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent); 

     appWidgetManager.updateAppWidget(appWidgetIds[i], rv); 
    } 
    super.onUpdate(context, appWidgetManager, appWidgetIds); 
} 

}

回答

6

您可以使用該方法onDataSetChanged在c lass RSSRemoteViewsFactory。當您在與此工廠相對應的集合視圖上調用AppWidgetManager notifyAppWidgetViewDataChanged時,會觸發此操作。你可以在這裏同步舉重。例如,如果您需要處理圖像,從網絡獲取某些內容等,則可以在此同步執行此操作。在這裏完成工作時,小部件將保持當前狀態,因此您不必擔心鎖定小部件。

class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { 
private final String TAG = StackRemoteViewsFactory.class.getSimpleName(); 

private Context mContext; 
private int mAppWidgetId; 

private List<Game> mGameItems = new ArrayList<Game>(); 

public StackRemoteViewsFactory(Context context, Intent intent) { 
    mContext = context; 
    mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 
      AppWidgetManager.INVALID_APPWIDGET_ID); 
} 

public void onCreate() { 
} 

public void onDestroy() { 
    mGameItems.clear(); 
} 

public int getCount() { 
    return mGameItems.size(); 
} 

public RemoteViews getViewAt(int position) { 
    Game game = mGameItems.get(position); 

    Bundle extras = new Bundle(); 
    extras.putString(StackWidgetProvider.EXTRA_ITEM, game.getGameUrl()); 
    Intent fillInIntent = new Intent(); 
    fillInIntent.putExtras(extras); 
    rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); 


    Bitmap bitmap = null; 
    try { 
     URL imageUrl = new URL(game.getImageUrl()); 
     bitmap = BitmapFactory.decodeStream(imageUrl.openConnection().getInputStream()); 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    rv.setImageViewBitmap(R.id.widget_item, bitmap); 
    return rv; 
} 

public RemoteViews getLoadingView() { 
    return null; 
} 

public int getViewTypeCount() { 
    return 1; 
} 

public long getItemId(int position) { 
    return position; 
} 

public boolean hasStableIds() { 
    return true; 
} 

public void onDataSetChanged() { 

    final String uri = <set your url> 

    DefaultHttpClient httpClient = new DefaultHttpClient(); 
    HttpGet httpGet = new HttpGet(uri); 

    String jsonData = null; 

    /** 
    * Fetch JSON from web service 
    * TODO: try to call a AsyncTask 
    */ 
    try { 
     HttpResponse httpResponse = httpClient.execute(httpGet); 
     HttpEntity httpEntity = httpResponse.getEntity(); 
     InputStream inputStream = httpEntity.getContent(); 

     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 
     StringBuilder data = new StringBuilder(); 
     String line; 
     while ((line = bufferedReader.readLine()) != null) { 
      data.append(line); 
     } 
     jsonData = new String(data); 
     Log.d(TAG, String.format("JSON: %s", jsonData)); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    /** 
    * Mapping JSON String to objects 
    * TODO: Probably move the code to a dedicated class and use GSON to do the mapping????? 
    */ 
    if(jsonData != null && !jsonData.equals("")) { 
     try { 
      JSONArray jsonArray = new JSONArray(jsonData); 
      for(int index = 0; index < jsonArray.length(); index++) { 
       JSONObject jsonObject = jsonArray.getJSONObject(index); 
       String id = jsonObject.getString("id"); 
       String imageUrl = jsonObject.getString("imageUrl"); 
       String gameUrl = jsonObject.getString("gameUrl"); 

       mGameItems.add(
         new Game(id, imageUrl, gameUrl) 
       ); 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 
    Log.d(TAG, String.format("List of games: %s", mGameItems)); 
} 

}

在下面的例子中,我從一個網絡服務器獲取一個JSON,然後我取從每個項目的圖像。 onDataSetChanged用於獲取json內容,並在getViewAt我獲取圖像。

檢查在谷歌提供的StackView例如評論 - http://docs.huihoo.com/android/3.0/resources/samples/StackWidget/index.html

希望它可以幫助你

+0

我試過,但我的'getCount將()'始終爲0,你能不能幫我請http:/ /stackoverflow.com/questions/39266206/items-on-listview-in-widget-doesnt-display-android謝謝。 – natsumiyu

+0

我有!而不是調用'onDataSetChanged'中的'AsyncTask',我只是將代碼放在'onDataSetChanged'中,我將其稱爲我的Web服務。非常感謝 – natsumiyu