Android App Development Series #2 - Web Requests and Parsing JSON ObjectssteemCreated with Sketch.

in #utopian-io6 years ago (edited)

Repository

https://github.com/aosp-mirror/platform_build

What Will I Learn?

  • You will learn how to make http/https web requests to a target server.
  • You will learn how to parse JSON objects, as well as to display the parsed data.

Requirements

  • Basic knowledge of Java, and XML.
  • Android Studio installed on your operating system of choice.
  • A device to run the application within, can be a physical device, or a VM like the one included in Android Studio's 'Device Manager'.

Difficulty

  • Basic

Tutorial Contents

Introduction

In this tutorial, we will be learning to make requests to a website, and retrieve and parse JSON Object Data. We will be carrying on with our previous project, and for the purposes of our application, we will be extracting user data from Steemit.com. Finally, this data will be displayed within a 3rd activity.

We should have two activities already existing in our project from before which will make this much simpler, though this can be done in a new project as well, should you prefer. If you are carrying on from the previous tutorial, simply create a new empty activity now. I have named mine 'activity_followers.xml'.

In this activity, we will need several different text views, essentially in regards to how many bits of data you would like to display to the user. I have used 6 Textviews, as well as 2 Image views on my 'followers.java' XML file.

Setting the Layout: activity_followers.xml

The following code is some XML that can be used to create both an ImageView, as well as a TextView, when entered into your activity_followers.xml Layout File.

<ImageView
    android:id="@+id/imageView5"
    android:layout_width="259dp"
    android:layout_height="72dp"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="200dp"
    app:srcCompat="@drawable/cooltext295204046785396" />
        
<TextView
    android:id="@+id/followersTVname"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_alignStart="@+id/followersTVid"
    android:layout_marginTop="124dp"
    android:background="#ebfd4d"
    android:maxLength="9000"
    android:maxLines="300"
    android:text="name"
    android:textColor="@android:color/black"
    android:textSize="18sp" />

main7.PNG
Screenshot

As I mentioned above, you will want 6 TextViews, and 2 ImageViews to carry along with this tutorial. The full code can be found in the link below to the entire project hosted on github. For now, lets carry on with the steps. Next we will need to create another activity.

aSyncTask: Running Tasks in Background

This will be slightly different from what we have done in the past, and this is because we will not be using this 'activity' to display data to the screen. We will instead be extending the aSyncTask class, so that we can have some code run in the background. This is where we will fetch, and parse our JSON data. First, create a new empty activity, and call it something like 'fetchdata.java'.

We will not need to implement anything in this layout file, as we will not be setting any 'Views'. This activity is strictly to be run in the background of our application, and set this up now.

Once we have created our class, we now need to override a couple of its functions. We will be using the doInBackground(), and the onPostExecute methods, so you can override these now. First we will deal with the doInBackground() function.

Making Web Requests:

Now, in this application and series, I really want to try and test the different things that we are able to do with the steem blockchain, as I'm writing to it, you're reading from it, and we should all be doing what we can to add value to this platform. I hope that these tutorials, help all of you readers get comfortable and start testing your own things with steem, especially on Mobile, as there are very few android applications out as of yet. :)

For the reasons listed above, we will be using Steemit as our website of choice, which we will be requesting information from. The first thing we are going to need are some variables. I am just going to give them all to you right now, though they will not all be used immediately. First we will need to create 9 variables like so.

//The data variables, will be used to store different all of the data from our web request.
String data = "";

// The strings 'id', 'name', and 'memo', will be used to store a users ID number, username, as well as memo address.
String id;
String name;
String memo;

//Lastly, these 3 variables will hold the values of our balances from our steem wallets.
String balanceSteem;
String balanceSP;
String balanceSBD;

main4.PNG
Screenshot

After this has been done, we will move to our doInBackground() function. This is of course, everything that we want to be done 'in the background' of our application. Yours should look much like mine below,though you can change the variables as you like.

@Override
protected Void doInBackground(Void... voids) {

    {
        try {

            //Create a new URL Object, with a target address, though the username can easily be substituted for any other, or even a variable.
            URL url = new URL("https://steemit.com/@ceruleanblue.json");
            
            // Create an HttpsUrlConnection Object, with an open connection to our predefined 'url' Object.
            HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();

            //InputStream Object creation, in order to read data bit-by-bit. Buffered reader is rather similar,
            //though it is designed to work within its own buffer space, storing more than one bit of data at a time.
            InputStream inputStream = httpsURLConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

        // Just some simple catch statements, helping the app to continue running, should anything go wrong.
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    return null;
}

Now to briefly explain this previous segment, surrounded in a try/catch clause, we first set our URL variable, then create an HttpsURLConnection, in order to make the connection, as well as an InputStream for accessing the data byte by byte, and a BufferedReader daisy-chained through the InputStream. Finally we have all of our catch clauses, in case anything goes wrong during runtime.

Parsing JSON Object Data:

Now we will need to add just a few more lines of code, directly above our catch clauses, and directly below the 'BufferedReader bufferedReader' line in our fetchdata.java file. (Complete code linked below)

// In this fragment of code, the String lines is created, and a while loop is used, (while 'lines' is not equal to 'null'), 
//and while this statement is true, we add each line of the buffered reader, into our String 'lines' and provided 
//that it is not equal, we throw the line in 'lines', into our 'data' variable String.
String lines = "";
            while(lines != null){
                    lines = bufferedReader.readLine();
                    data = data + lines;
                    }

                    // Create a new JSONObject Object,  and feed it the data from our 'data' variable.
                    JSONObject jo = new JSONObject(data);

                    JSONObject user = jo.getJSONObject("user");

                   //We now fetch each of these bits of data from our JSONObject 'user', and store them within their own
                   // individually accessed variables. We do this for all 6 key bits of info we are aiming to obtain.
                    id = user.getString("id"); 
                    name = user.getString("name");
                    memo = user.getString("memo_key");

                    balanceSteem = user.getString("balance");
                    balanceSP = user.getString("vesting_shares");
                    balanceSBD = user.getString("sbd_balance");

main5.PNG
Screenshot

Again, lets go through what just happened in the most previous code segment. First we create a String, and then feed the data from our BufferedReader, into our String. After this, we create a new JSON object out of said String.

Unfortunately, the way the data is recieved, we will need to extract yet another JSON Object, and thats exatcly what we do when we create the 'JSONObject user'. Now that we have queried our second object, we can extract any particular strings we like, using their name in JSON format, and that is what the last 6 lines of this are from.

Setting up our Activity: followers.java

Lets leave that last page alone for now, as that is the end of our doInBackground() function anyway. Lets move back to our followers.java file, and initialize the widgets that we need to use to display the data. As I have mentioned, I will be using 6 TextViews, displaying 'id, name, memo_key, balance, vesting_shares, and sbd_balance'. First lets initialize our widgets, and make them public for other activities to be able to use.

public class followers extends AppCompatActivity {
    public static TextView dataTV;
    public static TextView nameTV;
    public static TextView memoTV;

    // In this page, we initialize and set all of the widgets that we want to control, to public and static, so that 
    // we can access them from anywhere within our application. Specifically our aSyncTask activity.
    public static TextView balanceSteemTV;
    public static TextView balanceSPTV;
    public static TextView balanceSBDTV;

Now lets carry on with our onCreate() function. This is where we set our widgets, and execute our aSyncTask activity. We execute this code here, so that no data is transfered between activities.

 @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_followers);

    nameTV= (TextView)findViewById(R.id.followersTVname);
    dataTV = (TextView)findViewById(R.id.followersTVid);
    memoTV = (TextView)findViewById(R.id.followersTVmemo);

    //We use these 6 lines, 3 above and 3 below, in order to tell our system the specific widget that we would like to 
    //have control over, and give it a name as well.
    balanceSteemTV = (TextView)findViewById(R.id.followTVbalanceSTEEM);
    balanceSPTV = (TextView)findViewById(R.id.followTVbalanceSP);
    balanceSBDTV = (TextView)findViewById(R.id.followTVbalanceSBD);


    //Here we create a new 'fetchdata' obect, named process, and then execute our 'process', meaning to execute 
    //our aSycnTask.
    fetchdata process = new fetchdata();
    process.execute();


}
}

main3.PNG
Screenshot

We are getting fairly close to the end result of this tutorial, but that is it for our followers.java file, though there are many things that we can do with this data now that we have it. Lets head back over to our followers.java file, and finish up our onPostExecute() function.

Finishing up, Displaying the Data: followers.java

In this function, we will simply be taking the data that we have retrieved from steemit.com, and displaying it to the UI of our followers activity. We will be using several iterations of the 'setText()' method to do so.

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

    // In this function, after our background code has executed, we run the following commands, in order to 
    //display the data received in our previous function, to the widgets that we chose above. Strings, and String 
    //Objects can be added together using the '+' symbol.
    followers.dataTV.setText("ID: "+this.id);
    followers.nameTV.setText("Username: "+this.name);
    followers.memoTV.setText("Memo Key: "+this.memo);

    followers.balanceSteemTV.setText("STEEM Balance: "+this.balanceSteem);
    followers.balanceSPTV.setText("Vesting Balance: "+ this.balanceSP);
    followers.balanceSBDTV.setText("SBD Balance: "+this.balanceSBD);

}

main2.PNG
Screenshot

Finishing Up, Implementing the onClick Listener:

I almost forgot! We must implement an onClickListener in order to launch our followers activity from within the home screen. quickly do that now in Main_Activity.java.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // We initialize and name our buttons, in order to attach 'listeners' to them.
    Button buttonBrowse = (Button)findViewById(R.id.buttonBrowser);
    Button buttonFollowers = (Button)findViewById(R.id.buttonFollow);

   //The button now has a 'listener' listening, dictating that when the button is clicked, a new 'intent' will be created, and then launched in the next line, bringing us to our browser activity.
    buttonBrowse.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent LaunchBrowser = new Intent (MainActivity.this, browser.class);
            startActivity(LaunchBrowser);
        }
    });
 
    // This listener is responsible for sending us to our new activity, the followers page.
    buttonFollowers.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent LaunchFollowers = new Intent (MainActivity.this, followers.class);
            startActivity(LaunchFollowers);
        }
    });
}

main1.PNG
Screenshot

Conclusion

That is pretty much it guys! You can go ahead and mess with colors, size, image and more, but the code at this pont, is solid and ready to run. Lets give it a run together now. When in the home screen, selecting our followers button will now display some quite useful information to us.

follow2.PNG
Screenshot

And this is really just the beginning of what we can do with this type of data. I have quite a few plans for the future, but feel free to play around with this on your own, see what kind of things you can make out of this. Theres alot of data there already, and you can change the url easily to your account or anything else. I hope this has been a good read for you all, and that you got some good ideas from this project.

Happy Hunting,
Cerulean

Curriculum

This is the 2nd release in this series - Much more to come.

Proof of Work Done

https://github.com/cerulean-skies/android-app-development-series/blob/master/Series%20%232.md

Sort:  

Thank you for your contribution.

  • Put your code indented.
  • I suggest you put comments in the code.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thanks @portugalcoin! I have looked into the reviews you have written for me, only just noticed them actually, and they are quite helpful! I am going to go in and do a bit of editing for these, but in my future tutorials, I will do my best to include more visualizations, as well as explanatory commenting :)

Really like the way you handle things around here :) Thanks for the support!

Thank you for your review, @portugalcoin!

So far this week you've reviewed 5 contributions. Keep up the good work!

I really love your development tutorial series and I think, you should make some development contributions for open source ecosystem :)

Thanks buddy :) Hmu in discord, I'd love to hear more about this ecosystem XD

Hey @ceruleanblue
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Thanks @utopian-io! Hope you guys had an awesome weekend! Can't wait to get started on my next tutorial either :)

Congratulations! This post has been upvoted from the communal account, @minnowsupport, by ceruleanblue from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, someguy123, neoxian, followbtcnews, and netuoso. The goal is to help Steemit grow by supporting Minnows. Please find us at the Peace, Abundance, and Liberty Network (PALnet) Discord Channel. It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.

If you would like to delegate to the Minnow Support Project you can do so by clicking on the following links: 50SP, 100SP, 250SP, 500SP, 1000SP, 5000SP.
Be sure to leave at least 50SP undelegated on your account.

Coin Marketplace

STEEM 0.35
TRX 0.12
JST 0.040
BTC 70557.88
ETH 3560.83
USDT 1.00
SBD 4.75