如何在android小部件中显示rss feed

时间:2012-10-31 12:12:28

标签: java android rss

我有一个非常大的问题。我有一个应用程序从博客中提取和解析RSS提要,但我不知道如何将结果放入我的小部件。

这是RSSListActivity,它在自己的活动中正确显示了RSS:

@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        RSSItem data = itemlist.get(position);

        Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(data.link));

        startActivity(intent);
    }

    private void retrieveRSSFeed(String urlToRssFeed,ArrayList<RSSItem> list)
    {
        try
        {
           URL url = new URL(urlToRssFeed);
           SAXParserFactory factory = SAXParserFactory.newInstance();
           SAXParser parser = factory.newSAXParser();
           XMLReader xmlreader = parser.getXMLReader();
           RSSParser theRssHandler = new RSSParser(list);

           xmlreader.setContentHandler(theRssHandler);

           InputSource is = new InputSource(url.openStream());

           xmlreader.parse(is);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private class RetrieveRSSFeeds extends AsyncTask<Void, Void, Void>
    {
        private ProgressDialog progress = null;

        @Override
        protected Void doInBackground(Void... params) {
            retrieveRSSFeed("http://blog.qubiz.com/index.php/feed",itemlist);

            rssadaptor = new RSSListAdaptor(RSSListActivity.this, R.layout.rssitemview,itemlist);

            return null;
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }

        @Override
        protected void onPreExecute() {
            progress = ProgressDialog.show(
                    RSSListActivity.this, null, "Loading RSS Feed... Please wait");

            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Void result) {
            setListAdapter(rssadaptor);

            progress.dismiss();

            super.onPostExecute(result);
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    }

    private class RSSListAdaptor extends ArrayAdapter<RSSItem>{
        private List<RSSItem> objects = null;

        public RSSListAdaptor(Context context, int textviewid, List<RSSItem> objects) {
            super(context, textviewid, objects);

            this.objects = objects;
        }

        @Override
        public int getCount() {
            return ((null != objects) ? objects.size() : 0);
        }

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

        @Override
        public RSSItem getItem(int position) {
            return ((null != objects) ? objects.get(position) : null);
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;

            if(null == view)
            {
                LayoutInflater vi = (LayoutInflater)RSSListActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = vi.inflate(R.layout.rssitemview, null);
            }

            RSSItem data = objects.get(position);

            if(null != data)
            {
                TextView title = (TextView)view.findViewById(R.id.txtTitle);
                TextView date = (TextView)view.findViewById(R.id.txtDate);
                TextView description = (TextView)view.findViewById(R.id.txtDescription);

                title.setText(data.title);
                date.setText("on " + data.date);
                String prova = android.text.Html.fromHtml(data.description).toString();
                //description.setText(data.description);
                description.setText(prova);
            }

            return view;
        }
    }

    public boolean onCreateOptionsMenu(Menu menu)
    {
        menu.add(1,1,0,"About");
        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch(item.getItemId())
            {
        case 1:

            AlertDialog.Builder conferma_canc = new AlertDialog.Builder(this);
            conferma_canc.setTitle("About");
            conferma_canc.setMessage("Copyright © 2012 Qubiz. All rights reserved. Android version designed and developed by Csosz Gergo Levente, Qubiz Romania.");
            conferma_canc.setPositiveButton("OK", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int id) {
              }
            });
            AlertDialog alert = conferma_canc.create();
            alert.show();
            return true;
            }
        return false;           
    } 

这里是我的RSS解析器,它也可以正常工作:

public class RSSParser extends DefaultHandler {
    private final static String TAG_ITEM = "item";
    private final static String[] xmltags = { "title", "link", "pubDate", "description" };

    private RSSItem currentitem = null;
    private ArrayList<RSSItem> itemarray = null;
    private int currentindex = -1;
    private boolean isParsing = false;
    private StringBuilder builder = new StringBuilder();

    public RSSParser(ArrayList<RSSItem> itemarray) {
        super();

        this.itemarray = itemarray;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);

        if(isParsing && -1 != currentindex && null != builder)
        {
            builder.append(ch,start,length);
        }
    }

    @Override
    public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);

        if(localName.equalsIgnoreCase(TAG_ITEM))
        {
            currentitem = new RSSItem();
            currentindex = -1;
            isParsing = true;

            itemarray.add(currentitem);
        }
        else
        {
            currentindex = itemIndexFromString(localName);

            builder = null;

            if(-1 != currentindex)
                builder = new StringBuilder();
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);

        if(localName.equalsIgnoreCase(TAG_ITEM))
        {
            isParsing = false;
        }
        else if(currentindex != -1)
        {
            if(isParsing)
            {
                switch(currentindex)
                {
                    case 0: currentitem.title = builder.toString();         break; 
                    case 1: currentitem.link = builder.toString();          break;
                    case 2: currentitem.date = builder.toString();          break;
                    case 3: currentitem.description= builder.toString();    break;
                }
            }
        }
    }

    private int itemIndexFromString(String tagname){
        int itemindex = -1;

        for(int index= 0; index<xmltags.length; ++index)
        {
            if(tagname.equalsIgnoreCase(xmltags[index]))
            {
                itemindex = index;

                break;
            }
        }

        return itemindex;
    }
}

我的ExampleAppWidgetProvider.java其中是一个示例时钟小部件代码,我想替换它以显示我的RSS提要。

public class ExampleAppWidgetProvider extends AppWidgetProvider {
    static DateFormat df = new SimpleDateFormat("hh:mm:ss");
    private static final String LOG_TAG = "ExampleWidget";

    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        final int N = appWidgetIds.length;
        Log.i("ExampleWidget", "Updating widgets " + Arrays.asList(appWidgetIds));
        for (int i = 0; i < N; i++) {
            int appWidgetId = appWidgetIds[i];
            Intent intent = new Intent(context, ExampleAppWidgetProvider.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget1);
            views.setOnClickPendingIntent(R.id.button, pendingIntent);
            views.setTextViewText(R.id.widget1label, df.format(new Date()));

            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }

    private PendingIntent createClockTickIntent(Context context) {
        Intent intent = new Intent(CLOCK_WIDGET_UPDATE);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        return pendingIntent;
    }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
        Log.d(LOG_TAG, "Widget Provider enabled.  Starting timer to update widget every second");
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.SECOND, 1);
        alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),1000, createClockTickIntent(context));
    }

    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
        Log.d(LOG_TAG, "Widget Provider disabled. Turning off timer");
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(createClockTickIntent(context));
    }

    public static String CLOCK_WIDGET_UPDATE = "com.eightbitcloud.example.widget.8BITCLOCK_WIDGET_UPDATE";

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        Log.d(LOG_TAG, "Received intent " + intent);
        if (CLOCK_WIDGET_UPDATE.equals(intent.getAction())) {
            Log.d(LOG_TAG, "Clock update");
            ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
            int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
            for (int appWidgetID : ids) {updateAppWidget(context, appWidgetManager, appWidgetID);
            }
        }
    }

    public static void updateAppWidget(Context context,AppWidgetManager appWidgetManager, int appWidgetId) {
        String currentTime = df.format(new Date());
        RemoteViews updateViews = new RemoteViews(context.getPackageName(),R.layout.widget1);
        updateViews.setTextViewText(R.id.widget1label, currentTime);
        appWidgetManager.updateAppWidget(appWidgetId, updateViews);
    }

}

any1能为我提供解决方案吗? 我的目标是:用我的rss feed阅读器替换widget的clock java代码。 所以我想在窗口小部件中显示rss解析器解析的最后一个rss项。我怎样才能做到这一点? 请提供代码,不仅仅是一些想法,我对android开发有点新。 提前谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

(假设你有正确的RSS检索和解析) 您只需更改小部件中的一些文本:

    AppWidgetManager manager = AppWidgetManager.getInstance(context);
    RemoteViews views = new RemoteViews(context.getPackageName(), R.name_of_your_widget_layout);
    // set text of some view
    views.setTextViewText(R.id.widget_amount_cameras, amountCameras);
    // and of another view
    views.setTextViewText(R.id.widget_location, locationCity);
    // ... and yet another view
    views.setTextViewText(R.id.locationStatus, locationStatus);

   // get IDs of widgets ,  there could be more than  one
    final int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(YOurWidgetProviderClass.class.getPackage().getName(), YOurWidgetProviderClass.class.getName()));

    // update all hte instances
    manager.updateAppWidget(appWidgetIds, views);

您只能更改小部件的某些属性(由于安全性限制) - 有关详细说明,请参阅RemoteViews的Javadoc