contador web Saltar al contenido

Android development: How to create your own RSS reader

LV1A3278
Coursera

If you still have the Hello AndroidPIT app project from the first article, you can now continue working with it. Otherwise, you should start a new project in Android Studio.

Rich Site Summary (RSS)

First, what is an RSS feed? Many of you read RSS feeds daily on a reader app on your computer or mobile device. To program an app that can display an RSS feed, you should know a little about the RSS itself. Wikipedia provides a good overview of the subject.

For example, the AndroidPIT RSS feed can be found here.

In short, RSS an XML file. XML made primarily for displaying text, and designed for machine readability. Our first goal is to develop an app that uses the AndroidPIT feeds XML file and display it properly in our Hello AndroidPIT app.

Representing the RSS feed

Next, I will show you how to bring the XML file to your device screen. We will take the app from the first article and modify it for our purposes.

On Android, the layout is usually defined via XML. Therefore, if you plan to devote yourself to development, it is worth learning more about XML, as it is a format that you will continually use.

The layout stored in the folder res/layout. If you open the fragment_main.xml In your project you will be able to see the XML layout and a preview of it.

pi "sizes =" (max-width: 806px) calc (100vw - 24px), (max-width: 995px) 782px, (max-width: 1216px) calc (2 * (100vw - 30px) / 3) + 15px - 24px), 782px "src =" https://fscl01.fonpit.de/userfiles/4471351/image/GalaxyS5/pi-w628.png "srcset =" https://fscl01.fonpit.de/userfiles/4471351/ image / GalaxyS5 / pi-w628.png 628w, https://fscl01.fonpit.de/userfiles/4471351/image/GalaxyS5/pi-w596.png 596w, https://fscl01.fonpit.de/userfiles/4471351/ image / GalaxyS5 / pi-w450.png 450w, https://fscl01.fonpit.de/userfiles/4471351/image/GalaxyS5/pi-w336.png 336w, https://fscl01.fonpit.de/userfiles/4471351/ image / GalaxyS5 / pi-w300.png 300w "class =" lazyload "/>
In the project of the first article. / AndroidPIT
</figure>
<p>We want to replace Hello AndroidPIT! by our RSS feed. To do so, we have to give the <strong>TextView </strong>an identifier about what we want to show. In this case, the attribute <strong>android: id</strong> Go accomplish the task:</p>
<pre>
<TextView
       android:id=

After giving a id to Textviewwe have to find the ones we want to use and add them to our segment Placeholder fragment. For this we use the method findViewById. It should look like this within your method. onCreateView:

@Override
public View onCreateView(
    LayoutInflater inflater, 
    ViewGroup container, 
    Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    mRssFeed = (TextView) rootView.findViewById(R.id.rss_feed);
    return rootView;
}

To retrieve the RSS feed at the beginning of the app, we need the following method. onStart:

       @Override
       public void onStart() {
           super.onStart();
           InputStream in = null;
           try {
               URL url = new URL("https://www.androidpit/feed/main.xml");
               HttpURLConnection conn = (HttpURLConnection) url.openConnection();
               in = conn.getInputStream();
               ByteArrayOutputStream out = new ByteArrayOutputStream();
               byte() buffer = new byte(1024);
               for (int count; (count = in.read(buffer)) != -1; ) {
                   out.write(buffer, 0, count);
               }
               byte() response = out.toByteArray();
               String rssFeed = new String(response, "UTF-8");
               mRssFeed.setText(rssFeed);
           } catch (IOException e) {
               e.printStackTrace();
           } finally {
               if (in != null) {
                   try {
                       in.close();
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
               }
           }
       }

If you don't understand the source code, don't worry and just copy and paste what we did. To understand it, you need to learn Java and the programming language.

If you try to run the app now, it will start compiling but will freeze at some point.

When developing apps, I need to learn how to handle crashes and what they mean. If you open the logcat At the same time as running your app, it will log all error messages issued by the app. In our case, the following appears:

com.rockylabs.androidpitrss E/AndroidRuntime FATAL EXCEPTION: main
    Process: com.rockylabs.androidpitrss, PID: 14367
    java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.rockylabs.androidpitrss/com.rockylabs.androidpitrss.MainActivity}:
android.os.NetworkOnMainThreadException

What happened anyway? Your app tried to access the internet on the main thread, but if the request takes too long, the app stops responding and an error message is issued. To avoid this, Android has been programmed to freeze rather than run infinitely.

On Android, we need to work in a world of asynchronous workflows. This means that when a request is made to the system, it runs in the background and a notification appears to you as soon as the task is complete.

The default for all tasks is user interface thread, called UI thread. In the above case, if you try to access the internet and the server request takes too long, the interface will hang and will not proceed. As a result, you receive an error message that the application is not reacting. This warning also known as Application Not Responding (ANR). This type of message should be avoided in all ways to keep the application functional for the user.

anr dialog
Creative Commons Attribution 2.5

Android provides a very simple way to handle this problem in the form of a different class called AsyncTask. You can run the background task on a background thread and run the result on the UI thread.

In our app we want to run a task with AsyncTask in the background. In the previous step we have the source code for the method onStart inserted into our code. Now we need to separate the network and the user interface, which is why we created the method getAndroidPitRssFeed. This makes it easier to use the source code several times instead of spending a lot of time copying and pasting. The method getAndroidPitRssFeed the next:

       private class GetAndroidPitRssFeedTask extends AsyncTask {

           @Override
           protected String doInBackground(Void... voids) {
               String result = "";
               try {
                   result = getAndroidPitRssFeed();
               } catch (IOException e) {
                   e.printStackTrace();
               }
               return result;
           }

           @Override
           protected void onPostExecute(String rssFeed) {
               mRssFeed.setText(rssFeed);
           }
       }

If we run the app again, we will produce a stop again, but this time for lack of authorization rather than timeout. We saw no permission to access the internet and so we could not get the RSS feed.

If you have opened logcat with the application running, see the following error message:

Caused by: java.lang.SecurityException: Permission denied (missing INTERNET permission?)

To configure internet permissions, you will need to open the file AndroidManifest.xml. There you will see the following lines of code:

We will add the following below them:

And ready! If you run the application, see that it starts showing the XML of your RSS feed. As you may have noticed, it will take some time to load. The entire feed will be loaded. Later we will show you how to improve the user experience by installing a progress indicator. So far so good. You have successfully created your own RSS feed. However, nobody wants to view the XML format, which is rather raw, so we will have to clear it. Also, we can't get past the edge of the screen, and we can't scroll down at this point.

ScrollView

The solution to the above problem is to add the component Scrollview Already available on Android SDK:



        
    

In the next step, you will learn how the XML file is read, so we can modify it a bit and extract the article titles and present them in a list, so that the view is clearer.

android entwickler studio teil zwei rss 01
The fruits of our work: XML shown, but without scrollability. / AndroidPIT

XML read

Our next goal is to make the title of each article show within the tags.

. If we look at the RSS feed (image above), it is inside the pore <rss> do code and right after the tag <channel>. For simplicity, we will ignore all other tags for now. Once we have worked through the entire XML file, we will better understand what they are used for. <p>To deal with an XML file, we need to look through the tangle of things and get the information we need from it. Fortunately for us, someone has already created a tool for this. As such, we will use a parser to extract the information we need and we will use XmlPullParser from the Android SDK.</p> <p>The XML file analysis follows the following stages:</p> <p><strong>START_DOCUMENT</strong> to start the document when the parser has not read anything yet.</p> <p><strong>START_TAG</strong> what starts the parser</p> <p><strong>TEXT </strong> when the parser is busy with content</p> <p><strong>ENG_TAG</strong> when the parser is in the final tag</p> <p><strong>END_DOCUMENT</strong> when the document is finished and no further analysis options are available.</p> <p>First, we need the parser to create:</p> <pre> XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser xpp = factory.newPullParser();</pre> <p>Next we have to give the parser a source to parse. Let's assign it to the string we downloaded from the server and it's being shown via <strong>TextView</strong>.</p> <p>As we mentioned earlier, we want to read the RSS feed, channel, open item, and title tags to read the article title. Let's ignore everything else. So we added <strong>readRSS</strong>,<strong> read channel</strong>, <strong>ReadItem</strong>, and <strong>read title</strong>. For this we emit the following code:</p> <pre> private List<string> readRss(XmlPullParser parser) throws XmlPullParserException, IOException { List<string> items = new ArrayList(); parser.require(XmlPullParser.START_TAG, null, "rss"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); if (name.equals("channel")) { items.addAll(readChannel(parser)); } else { skip(parser); } } return items; }</string></string></pre> <p>Now we need to implement the read channel to read the contents, the rest we put aside:</p> <pre> private List<string> readChannel(XmlPullParser parser) throws IOException, XmlPullParserException { List<string> items = new ArrayList(); parser.require(XmlPullParser.START_TAG, null, "channel"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); if (name.equals("item")) { items.add(readItem(parser)); } else { skip(parser); } } return items; }</string></string></pre> <p><strong>ReadItem</strong> Also required:</p> <pre> private String readItem(XmlPullParser parser) throws XmlPullParserException, IOException { String result = null; parser.require(XmlPullParser.START_TAG, null, "item"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); if (name.equals("title")) { result = readTitle(parser); } else { skip(parser); } } return result; }</pre> <p>We're almost there, we just need to get <strong>read title</strong> to pull the title:</p> <pre> // Processes title tags in the feed. private String readTitle(XmlPullParser parser) throws IOException, XmlPullParserException { parser.require(XmlPullParser.START_TAG, null, "title"); String title = readText(parser); parser.require(XmlPullParser.END_TAG, null, "title"); return title; }</pre> <p>And the text on the day </p><title> : <pre> private String readText(XmlPullParser parser) throws IOException, XmlPullParserException { String result = ""; if (parser.next() == XmlPullParser.TEXT) { result = parser.getText(); parser.nextTag(); } return result; }</pre> <p>With this method, the rest of the tags will be skipped:</p> <pre> private void skip(XmlPullParser parser) throws XmlPullParserException, IOException { if (parser.getEventType() != XmlPullParser.START_TAG) { throw new IllegalStateException(); } int depth = 1; while (depth != 0) { switch (parser.next()) { case XmlPullParser.END_TAG: depth; break; case XmlPullParser.START_TAG: depth++; break; } } }</pre> <p>We are now almost professional with regard to the XML parser! In the next step we will issue the item title in a list.</p> <h2>List Fragment</h2> <p>In the Android SDK there is a class called <em>ListFragment </em>that will help us deal with lists.</p> <p>Since we already have many lines of text extracted from the XML file, we can use a standard Android function to represent the title. An adapter is a bridge type between the data we want to present and the <strong>TextViews </strong>that represent the data.</p> <p>With an adapter we can use a method <strong>TextView</strong> for each title on our list. You need to use the <strong>Placeholder fragment </strong>to achieve this:</p> <pre> public static class PlaceholderFragment extends ListFragment {</pre> <p>Finally, we still need to use the <strong>AsyncTask</strong> so our analyzer can work:</p> <pre> @Override protected List<string> doInBackground(Void... voids) { List<string> result = null; try { String feed = getAndroidPitRssFeed(); result = parse(feed); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } @Override protected void onPostExecute(List<string> rssFeed) { setListAdapter(new ArrayAdapter( getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, rssFeed)); }</string></string></string></pre> <p>If you try to run the app now, you should first see a progress indicator while the RSS feed is downloaded from the server and then a list of all feed titles will be shown as below:</p> <figure><img alt="android entwickler studio teil zwei rss 04" src="https://dnetc.net/wp-content/uploads/2019/11/1574337488_10_Android-development-How-to-create-your-own-RSS-reader.jpg" class="lazyload"><br> Here it is! A progress indicator is the title of the XML file. / AndroidPIT<br> </figure> <h2>Conclusion</h2> <p>UFA! We know this guide is a big step compared to the first exercise. But if you have been through all the stages, you should be proud of what you have done and what you have learned. Even if you don't understand all the details, your understanding of how to program within Android will grow over time. The more you practice Android development, the more you understand about this kind of thing.</p> <p>The feed you have programmed works, but it is not very useful as it currently only shows article titles. In our next exercise, we will extend the functionality and let us read the introduction of articles when we click on the title.</p> <p>What do you think? What improvements would you like to see in the RSS tutorial?</p> <p> . (tagsToTranslate) development android (t) rss feed (t) reader (t) app (t) app (t) program<br></p>