2016-02-21 11 views
5

Muszę pobrać kanały z więcej adresów URL, które muszę zebrać i wyświetlić wiadomości w porządku malejącym.Jak scalać, tworzyć znaczniki i umieszczać w kolejności rosnącej kanały z większą liczbą kanałów RSS, takich jak Yahoo Pipes?

Niektóre linki nie mają znacznika xml dla <category>, więc muszę je utworzyć: muszę wiedzieć, skąd pochodzą źródła, aby je sklasyfikować.

To co usiłuję osiągnąć: (dla Źródło n rozumiem kategorię)

[! [Wpisać opis obrazu tutaj] [1]] [1]

użyłem użyć Yahoo!Pipes, aby wprowadzić wszystkie te zmiany.

Moja próba polegała na stworzeniu CustomListView dla każdego adresu URL, a następnie uruchomieniu na raz wszystkich AsyncTasks, ale to nie działa poprawnie - kanały nie są wyświetlane w porządku rosnącym.

główną działalność

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

powinienem wyjaśnił to lepiej: o ile mi wiadomo to nie mogę zrobić programowo. W każdym razie mój plik danych jest zapisany w języku xml. – Rick

+0

Gdzie dokładnie masz problemy? Dlaczego nie możesz po prostu mieć jednej listy do dołączenia wszystkich danych, a następnie zacząć robić żądania. Po zakończeniu tych żądań agreguj nowo otrzymane dane ze starym, a następnie sortuj je w procesie. – Luksprog

+0

Próbowałem już użyć listy i pobrać plik danych z adresów URL, ale nie mogę wyświetlić kategorii kanału, ponieważ muszę utworzyć tag dla każdego adresu URL: – Rick

Odpowiedz

2

rozwiązanie wymaga więcej niż jedną zmianę. Pierwszą rzeczą, którą musisz zrobić, to sprawić, aby każde zadanie Wiadomości, które się zakończyło, dodało dane do jednej dużej listy. Lista ta może być następnie sortowana, co wymaga Comparator.

Potrzebna jest również lista nazwisk wyświetlanych w obrazie zastępczym o nazwie Source n na obrazie, a na końcu, aby można je było porównać, należy przeanalizować daty jako rzeczywiste daty.

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; 
      ... 
     } 
    } 
} 

Wszystko jsut ... „s znaczy zostawić wszystko tak jak było to w tych miejscach

+0

Przepraszam, że nie wiem. t rozumiem tę część, w której dodaję więcej adresów URL – Rick

+0

Muszę pobrać kanał z różnych adresów URL nie tylko jednego, ale w tobie nie widzę gdzie dodaję inne adresy URL. – Rick

+0

Ok teraz mam to, ale jak to działa dla nazwa źródeł? Jak wyświetlać różne źródła? – Rick

Powiązane problemy