2016-02-21 1 views
5

Мне нужно взять каналы более RSS Feed URL-адресов, которые мне нужно заполнить и показать новости в порядке убывания.Как объединить, создать теги и поместить восходящий порядок в каналы большего количества RSS-каналов, например, на Yahoo Pipes?

Некоторые ссылки не содержат тег xml для <category>, поэтому мне нужно его создать: я должен знать, откуда поступают фиды, чтобы я мог их классифицировать.

Это то, что я пытаюсь добиться: (для Источник п я имею в виду категорию)

[! [Введите описание изображения здесь] [1]] [1]

Я использовать Yahoo!Pipes, чтобы внести все эти изменения.

Моя попытка состояла в том, чтобы создать CustomListView для каждого URL-адреса, а затем выполнить AsyncTasks все сразу, но это работает неправильно - каналы не отображаются в порядке возрастания.

MainActivity

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener { 
    private RSSFeed myRssFeed = null; 
    String[] urlFeed = {"url1", "url2"}; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     for (int i = 0; i < urlFeed.length; i++) { 
      News news = new News(i); 
      news.execute(); 
     } 
    } 

    @Override 
    public void onRefresh() { 
     for (int i = 0; i < urlFeed.length; i++) { 
      News news = new News(i); 
      news.execute(); 
     } 
    } 

    private class News extends AsyncTask<Object, Void, Void> { 
     protected int number; 
     public News(int urlNumber) { 
      number = urlNumber; 
     } 

     @Override 
     protected Void doInBackground(Object... arg0) { 

      String data = ""; 
      InputStream iStream; 

      try{ 
       URL url = new URL(urlFeed[number]); 

       // Creating an http connection to communicate with url 
       HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 

       // Connecting to url 
       urlConnection.connect(); 

       // Reading data from url 
       iStream = urlConnection.getInputStream(); 

       BufferedReader br = new BufferedReader(new InputStreamReader(iStream)); 

       StringBuilder sbf = new StringBuilder(); 

       String line; 
       while((line = br.readLine()) != null){ 
        sbf.append(line); 
       } 

       data = sbf.toString(); 

       br.close(); 

       SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance(); 
       SAXParser mySAXParser = mySAXParserFactory.newSAXParser(); 
       XMLReader myXMLReader = mySAXParser.getXMLReader(); 
       RSSHandler myRSSHandler = new RSSHandler(); 
       myXMLReader.setContentHandler(myRSSHandler); 
       InputSource myInputSource = new InputSource(url.openStream()); 
       myXMLReader.parse(myInputSource); 

       myRssFeed = myRSSHandler.getFeed(); 

      } catch (ParserConfigurationException | IOException | SAXException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      return null; 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 

      if (myRssFeed != null) { 

       NestedListView list = (NestedListView)findViewById(android.R.id.list); 
       list.setVisibility(View.VISIBLE); 
       CustomList adapter = new CustomList(MainActivity.this, myRssFeed.getList()); 
       adapter.addAll(); 
       list.setAdapter(adapter); 

      } else 
       Toast.makeText(MainActivity.this, "Error", 
        Toast.LENGTH_LONG).show(); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 
} 

RssFeed

public class RSSFeed { 
    private String title = null; 
    private String description = null; 
    private String link = null; 
    private String pubdate = null; 
    private String image = null; 
    private String enclosure = null; 
    private String author = null; 
    private List<RSSItem> itemList; 

    RSSFeed(){ 
     itemList = new Vector<RSSItem>(0); 
    } 

    void addItem(RSSItem item){ 
     itemList.add(item); 
    } 
    RSSItem getItem(int location){ 
     return itemList.get(location); 
    } 
    List<RSSItem> getList(){ 
     return itemList; 
    } 

} 

RSSItem

public class RSSItem { 

    private String title = null; 
    private String description = null; 
    private String link = null; 
    private String pubdate = null; 
    private String image = null; 
    private String enclosure = null; 
    private String author = null; 
} 

CustomList

public class CustomList extends ArrayAdapter<RSSItem> { 

    private static Activity context = null; 
    private final List<RSSItem> web; 

    public CustomList(Activity context, List<RSSItem> web) { 
     super(context, R.layout.new_listview, web); 
     CustomList.context = context; 
     this.web = web; 
    } 

    @SuppressLint("SetTextI18n") 
    @Override 
    public View getView(final int position, View view, ViewGroup parent) { 
     LayoutInflater inflater = context.getLayoutInflater(); 
     @SuppressLint({"ViewHolder", "InflateParams"}) final View rowView = inflater.inflate(R.layout.new_listview, null, true); 
     ImageView imageView = (ImageView)rowView.findViewById(R.id.image); 
      Picasso.with(context).load(web.get(position).getImage()).into(imageView); 

     TextView textView = (TextView)rowView.findViewById(R.id.title); 
     textView.setText(Html.fromHtml(web.get(position).getTitle())); 

     TextView textView1 = (TextView)rowView.findViewById(R.id.description); 
     textView1.setText(web.get(position).getDescription()); 

     TextView textView2 = (TextView)rowView.findViewById(R.id.pubdate); 
     textView2.setText(pubdate); 

     return rowView; 

    } 

} 

RSSHandler

public class RSSHandler extends DefaultHandler { 

    final int state_unknown = 0; 
    final int state_title = 1; 
    final int state_description = 2; 
    final int state_link = 3; 
    final int state_pubdate = 4; 
    final int state_enclosure = 6; 
    final int state_image = 5; 
    final int state_author = 7; 
    int currentState = state_unknown; 
    String url; 

    RSSFeed feed; 
    RSSItem item; 

    boolean itemFound = false; 

    RSSHandler(){ 
    } 

    RSSFeed getFeed(){ 
     return feed; 
    } 

    @Override 
    public void startDocument() throws SAXException { 
     // TODO Auto-generated method stub 
     feed = new RSSFeed(); 
     item = new RSSItem(); 

    } 

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

     // TODO Auto-generated method stub 

     if (localName.equalsIgnoreCase("item")){ 
      itemFound = true; 
      item = new RSSItem(); 
      currentState = state_unknown; 
     } 
     else if (localName.equals("enclosure")) { 
      url = attributes.getValue("url"); 
      currentState = state_image; 
     } 
     else if (localName.equalsIgnoreCase("title")){ 
      currentState = state_title; 
     } 
     else if (localName.equalsIgnoreCase("description")){ 
      currentState = state_description; 
     } 
     else if (localName.equalsIgnoreCase("link")){ 
      currentState = state_link; 
     } 
     else if (localName.equalsIgnoreCase("pubdate")){ 
      currentState = state_pubdate; 
     } 
     else if (localName.equalsIgnoreCase("author")){ 
      currentState = state_author; 
     } 
     else{ 
      currentState = state_unknown; 
     } 

    } 

    @Override 
    public void endElement(String uri, String localName, String qName) 
      throws SAXException { 
     // TODO Auto-generated method stub 
     if (localName.equalsIgnoreCase("item")){ 
      feed.addItem(item); 
     } 
    } 

    @Override 
    public void characters(char[] ch, int start, int length) 
     throws SAXException { 
     // TODO Auto-generated method stub 

     String strCharacters = new String(ch,start,length); 

     if (itemFound){ 
      // "item" tag found, it's item's parameter 
      switch(currentState){ 
       case state_enclosure: 
        item.setEnclosure(strCharacters); 
        break; 
       case state_title: 
        item.setTitle(strCharacters); 
        break; 
       case state_image: 
        item.setImage(url); 
        break; 
       case state_description: 
        item.setDescription(strCharacters); 
        break; 
       case state_link: 
        item.setLink(strCharacters); 
        break; 
       case state_pubdate: 
        item.setPubdate(strCharacters); 
        break; 
       case state_author: 
        item.setAuthor(strCharacters); 
        break; 
       default: 
        break; 
      } 
     } 
     else{ 
      // not "item" tag found, it's feed's parameter 
      switch(currentState){ 
       case state_enclosure: 
        feed.setEnclosure(strCharacters); 
        break; 
       case state_title: 
        feed.setTitle(strCharacters); 
        break; 
       case state_image: 
        feed.setImage(url); 
        break; 
       case state_description: 
        feed.setDescription(strCharacters); 
        break; 
       case state_link: 
        feed.setLink(strCharacters); 
        break; 
       case state_pubdate: 
        feed.setPubdate(strCharacters); 
        break; 
       case state_author: 
        feed.setAuthor(strCharacters); 
        break; 
       default: 
        break; 
      } 
     } 

     currentState = state_unknown; 
    } 
+0

я должен был объяснить это лучше: Насколько мне известно, я не могу сделать это программно. В любом случае мой канал написан в xml. – Rick

+0

Где именно возникают проблемы? Почему вы не можете просто добавить один список для добавления всех данных и затем начать выполнение запросов. По завершении этих запросов суммируйте вновь полученные данные со старым, а затем сортируйте их в процессе. – Luksprog

+0

Я уже пытался использовать список и получать фид с URL-адресов, но я не могу показать категорию фида, поскольку мне нужно создать тег для каждого URL-адреса – Rick

ответ

2

Решение требует больше, чем одно изменение. Первое, что вам нужно сделать, - это завершить каждую задачу новостей, добавив ее данные в один большой список. Затем этот список можно отсортировать, что требует Comparator.

Вам также нужен список имен, которые будут отображаться в заполнителе, который вы назвали Source n, и, наконец, чтобы вы могли их сравнить, вам нужно проанализировать даты как фактические даты.

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener { 

    private List<RSSItem> totalRssFeed = new ArrayList<>(); 
    String[] urlFeed = {"MyURL", "MyUrl2", "MyUrl3"}; 
    String[] names = {"Name", "Name2", "Name3"} 
    private CustomList adapter; 

    @Override 
    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) { 
     super.onCreate(savedInstanceState, persistentState); 
     ListView list = (ListView) findViewById(android.R.id.list); 
     adapter = new CustomList(MainActivity.this); 
     list.setAdapter(adapter); 
    } 

    @Override 
    protected void onResume() { 
     // do this here and you dont need to repeat it in refresh and create 
     for (int i = 0; i < urlFeed.length; i++) { 
      News news = new News(i); 
      news.execute(); 
     } 
    } 

    public class CustomList extends ArrayAdapter<RSSItem> { 

     ... 

     public CustomList(Activity context) { //dont start with default data 
      super(context, R.layout.new_listview, null); 
     } 

     ... 

    } 

    private class News extends AsyncTask<Object, Void, Void> { 

     protected int number; 

     public News(int urlNumber) { 
      number = urlNumber; 
     } 

     @Override 
     protected Void doInBackground(Object... arg0) { 
      try { 

       //no need to do the input stuff you were doing before here? 
       URL url = new URL(urlFeed[number]); 
       SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance(); 
       SAXParser mySAXParser = mySAXParserFactory.newSAXParser(); 
       XMLReader myXMLReader = mySAXParser.getXMLReader(); 
       RSSHandler myRSSHandler = new RSSHandler(names[number]); 
       myXMLReader.setContentHandler(myRSSHandler); 
       InputSource myInputSource = new InputSource(url.openStream()); 
       myXMLReader.parse(myInputSource); 
       totalRssFeed.addAll(myRSSHandler.getFeed()); 
       Collections.sort(totalRssFeed); 

      } catch (ParserConfigurationException | IOException | SAXException e) { /* stuff */ } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 
      adapter.clear(); 
      adapter.addAll(totalRssFeed); 
     } 

    } 

    public class RSSItem implements Comparable<RSSItem> { 

     public String tag; 
     public Date pubdate; //just public so i didnt need setters in this example 

     public RSSItem(String defaultTagToUse) { 
      //You should set the default to whatever you want displayed 
      //when the tag for <category> is missing, and just update it normally otherwise 
      tag = defaultTagToUse; 
     } 

     void setPubDate(Date date) { 
      pubdate = date; 
     } 

     ... 

     @Override 
     public int compareTo(@NonNull RSSItem another) { 
      int res; 
      if (pubdate == null) { 
       if (another.pubdate == null) { 
        res = 0; 
       } else { 
        res = -1; 
       } 
      } else { 
       if (another.pubdate == null || pubdate.getTime() > another.pubdate.getTime()) { 
        res = 1; 
       } else { 
        res = -1; 
       } 
      } 
      return res; 
     } 

    } 

    public class RSSHandler extends DefaultHandler { 

     ... 
     List<RSSItem> feed; 
     RSSItem item; 
     String mName; 

     public RssHandler(String name) { 
      mName = name; 
     } 

     List<RSSItem> getFeed() { 
      return feed; 
     } 

     @Override 
     public void startDocument() throws SAXException { 
      feed = new ArrayList<>(); 
     } 

     @Override 
     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 
      if (localName.equalsIgnoreCase("item")) { 
       itemFound = true; 
       item = new RSSItem(name); 
       currentState = state_unknown; 
      } else ... 
     } 

     @Override 
     public void endElement(String uri, String localName, String qName) throws SAXException { 
      if (localName.equalsIgnoreCase("item")) { 
       feed.add(item); 
      } 
     } 

     @Override 
     public void characters(char[] ch, int start, int length) throws SAXException { 
      ... 
      case state_pubdate: 
       SimpleDateFormat formatter = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); //make sure you match the format from your XML 
       item.setPubdate(formatter.parse(stringCharacters)); 
      break; 
      ... 
     } 
    } 
} 

Все ... этого нужно просто «s значит оставить все, как это было в тех местах,

+0

Прости, t понять часть, где я добавляю больше Urls – Rick

+0

Мне нужно получить канал с разными URL-адресами не один, но в вашем коде я не вижу, где я добавляю другие URL-адреса. – Rick

+0

Хорошо, теперь я получил его, но как он работает для название источников? Как я показываю разные источники? – Rick

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