Instantly share code, notes, and snippets.

Embed
What would you like to do?
2.01 Add the Network Code
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String forecastJsonStr = null;
try {
// Construct the URL for the OpenWeatherMap query
// Possible parameters are avaiable at OWM's forecast API page, at
// http://openweathermap.org/API#forecast
URL url = new URL("http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7");
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
} catch (IOException e) {
Log.e("PlaceholderFragment", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
return rootView;
}
}
}
@gildassamuel

This comment has been minimized.

gildassamuel commented Feb 28, 2015

thanks for this help

@DANIELKAKAI

This comment has been minimized.

DANIELKAKAI commented Mar 14, 2015

thanks alot

@chrisyeung1121

This comment has been minimized.

chrisyeung1121 commented Mar 17, 2015

nice

@sagoyanfisic

This comment has been minimized.

sagoyanfisic commented Mar 19, 2015

nice!

@gpiancastelli

This comment has been minimized.

gpiancastelli commented Mar 21, 2015

Any reason why you are using StringBuffer instead of StringBuilder?

Also, nitpicking: the creation of the buffer could be better placed on line 28 instead of 22, because the buffer is needed only after checking that the input stream is not null.

@bucketzxm

This comment has been minimized.

bucketzxm commented Mar 25, 2015

thanks !

@rutyroot

This comment has been minimized.

rutyroot commented Mar 27, 2015

Good, thanks!

@pravinkerai212

This comment has been minimized.

pravinkerai212 commented Mar 28, 2015

Thanks, this really helps a lot.

@RaaulCabrera

This comment has been minimized.

RaaulCabrera commented Mar 29, 2015

thanks!!

@lyz1990

This comment has been minimized.

lyz1990 commented Mar 29, 2015

Thanks!!

@pepziman

This comment has been minimized.

pepziman commented Mar 30, 2015

thank you!

@ghost

This comment has been minimized.

ghost commented Apr 2, 2015

thanks a lot

@MagoMtz

This comment has been minimized.

MagoMtz commented Apr 3, 2015

why we use the GET method?

@vdugnist

This comment has been minimized.

vdugnist commented Apr 4, 2015

MagoMtz: because we only want to get data from openweather, not to modify it. You can read about the difference between http methods on wikipedia: http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

@happysahota

This comment has been minimized.

happysahota commented Apr 4, 2015

Awesome...

@kolasanichaitanya

This comment has been minimized.

kolasanichaitanya commented Apr 5, 2015

In line 34 why to use a stringBuffer ? we can directly append to a string right?

@npari

This comment has been minimized.

npari commented Apr 5, 2015

@kolasanichaitanya

The StringBuffer Class allows character representation that are mutable compared to the String class which is immutable. Also, concatenation is faster in StringBuffer. It is mainly a choice to improve performance. The concatenation operation using StringBuffer class and append makes it a cheaper operation.

@ZikasR

This comment has been minimized.

ZikasR commented Apr 11, 2015

thanks

@aindong

This comment has been minimized.

aindong commented Apr 24, 2015

awesome!

@mike915

This comment has been minimized.

mike915 commented Apr 24, 2015

Thanks, it helps a lot!

@solisfox

This comment has been minimized.

solisfox commented Apr 25, 2015

thanks !

@AliyuAbdullahi

This comment has been minimized.

AliyuAbdullahi commented Apr 25, 2015

Thanks

@younesmln

This comment has been minimized.

younesmln commented May 2, 2015

good

@refschool

This comment has been minimized.

refschool commented May 5, 2015

shouldn't it be return null at the end of the script?

@tunee

This comment has been minimized.

tunee commented May 13, 2015

cool

@Synix

This comment has been minimized.

Synix commented May 16, 2015

thanks!!

@Haloyum

This comment has been minimized.

Haloyum commented May 20, 2015

Thanks!

@nalamchaitanya

This comment has been minimized.

nalamchaitanya commented May 22, 2015

Helps a lot.

@cmauroie

This comment has been minimized.

cmauroie commented May 25, 2015

Thanks!

@ghost

This comment has been minimized.

ghost commented May 27, 2015

Thanks =)

@ewintory

This comment has been minimized.

ewintory commented May 31, 2015

Nice :)

@IdiotLeon

This comment has been minimized.

IdiotLeon commented Jun 3, 2015

Thanks

@88dave

This comment has been minimized.

88dave commented Jun 4, 2015

Good stuff -- useful for lots of situations

@DeJaVo

This comment has been minimized.

DeJaVo commented Jun 6, 2015

Great, thank for this useful code snippet

@Curicaveri

This comment has been minimized.

Curicaveri commented Jun 10, 2015

Great code!!!

@dengn

This comment has been minimized.

dengn commented Jun 11, 2015

@gpiancastelli
It's very possible that this code is running in multi-thread environment, StringBuffer is synchronized while StringBuilder is not.

@theCaffeinatedTanuki

This comment has been minimized.

theCaffeinatedTanuki commented Jun 12, 2015

Thanks for this!

@mattCheung

This comment has been minimized.

mattCheung commented Jun 13, 2015

Forgive me if this is a newbie question, but on line 23, when would the inputStream == null but not be triggered by an IOException? Follow up is that shouldn't the fact that nothing was received in the inputStream that wasn't generated from some exception be logged, if nothing else, for info/debug purposes?

@osirvics

This comment has been minimized.

osirvics commented Jun 17, 2015

Please help, i see on line 37 we are checking if the StringBuffer object "buffer" is equal to zero, but nothing was ever assigned to it, I'm i missing something? (i'm a newbie).

@alexandru-calinoiu

This comment has been minimized.

alexandru-calinoiu commented Jun 17, 2015

@osirivics line #34

@haroldhues

This comment has been minimized.

haroldhues commented Jun 18, 2015

Not to be a spelling nut but...

s/avaiable/available
s/attemping/attempting
@gomaa86

This comment has been minimized.

gomaa86 commented Jun 21, 2015

thank you for help :)

@bkkothari

This comment has been minimized.

bkkothari commented Jun 26, 2015

Thanks for the snippet :)

@Mrboutte

This comment has been minimized.

Mrboutte commented Jun 28, 2015

Isn't there a better way of doing this with the try with resources block instead? That away the streams are automatically closed

@ikhfa

This comment has been minimized.

ikhfa commented Jul 1, 2015

Thanks for the snippet :)

@saadeh05

This comment has been minimized.

saadeh05 commented Jul 1, 2015

I really don't understand most of the code
so is it normal not to understand it all or i'm missing something ?

@Anthonyeef

This comment has been minimized.

Anthonyeef commented Jul 2, 2015

@saadeh05
I think it would be nice if you could understand it. But the Udacity course is aiming at the fresh man of Android development, and at this point the understanding of this code doesn't look that important.
So just learn how to use the snippet, and with the more code you read, you will get to understand it.

@TysonMatlhoma

This comment has been minimized.

TysonMatlhoma commented Jul 2, 2015

Thanks for the snippet :)

@silentsudo

This comment has been minimized.

silentsudo commented Jul 5, 2015

Thank you for Gist

@y-matsuyama

This comment has been minimized.

y-matsuyama commented Jul 11, 2015

thanks

@asinitson

This comment has been minimized.

asinitson commented Jul 11, 2015

@Mrboutte

Isn't there a better way of doing this with the try with resources block instead? That away the streams are automatically closed

I wondered about the same, so I searched a bit and according to what I understand, if you want to use try-with-resources statement (Java SE 7 feature), then you limit yourself to API 19: Android 4.4 (KitKat) and higher.

Source:
java 7 - Does Android support JDK 6 or 7 - Stack Overflow

@Wsakr

This comment has been minimized.

Wsakr commented Jul 11, 2015

why do we have to call the setRequestMethod("GET") if the default of the HTTPURLConnection is GET

@gishiru

This comment has been minimized.

gishiru commented Jul 15, 2015

thanks

@njsand

This comment has been minimized.

njsand commented Jul 16, 2015

@dengn Use of StringBuffer is wrong here. Even if multiple threads enter this method, they each allocate their own instance (because that's how "new" works), and this instance never "escapes" the method. Thus any internal synchronization that StringBuffer performs is completely wasted. So don't use it. StringBuilder is designed for exactly situations like this.

@wahooka9

This comment has been minimized.

wahooka9 commented Jul 21, 2015

@njsand StringBuffer is fine here, and as stated above it has better performance for .append()
To the generation of extra strings on separate threads - I believe that is something you want. The response you get from any requests will be parsed on that thread (and added to that particular stringbuffer). The "threaded" part of networking is that the request posts and a thread that is not the UI thread handles the response and the parsing. This is how they do it in iOS also. To keep it from locking the UI.

@ahmeDatef3112

This comment has been minimized.

ahmeDatef3112 commented Aug 12, 2015

grazie

@NrTwelve

This comment has been minimized.

NrTwelve commented Aug 14, 2015

Thank you!

@du2x

This comment has been minimized.

du2x commented Aug 20, 2015

coooool!

@jrmineur

This comment has been minimized.

jrmineur commented Aug 21, 2015

Hi All!

The URL in the code snipped gives me a city in Poland when I hand it to Chrome. I will try this URL for Mountain View - it seems to work in Chrome:

http://api.openweathermap.org/data/2.5/forecast/daily?zip=94043,us&mode=json&units=metric&cnt=7

@jhealy

This comment has been minimized.

jhealy commented Aug 25, 2015

@jrmineur -
on edge in win10 - mountain view
On IE in win10 - montainview
On chrome in win10 - mountainview

Verified the following URL in Jason and xml formats - http://api.openweathermap.org/data/2.5/forecast/daily?zip=94043,us&mode=json&units=metric&cnt=7

Healy in Tampa

@m0nst3rdr1v3n

This comment has been minimized.

m0nst3rdr1v3n commented Aug 27, 2015

This is great!

@Jorelx

This comment has been minimized.

Jorelx commented Aug 29, 2015

thanks

@taehunzzang

This comment has been minimized.

taehunzzang commented Sep 1, 2015

it's good. thanks

@vainarouski

This comment has been minimized.

vainarouski commented Sep 2, 2015

Thanks a lot!

@linuxedhorse

This comment has been minimized.

linuxedhorse commented Sep 2, 2015

Java has a try-with-resources, why android hasn't?
But question: why StringBuffer buffer = new StringBuffer(); doesn't under the inputStream != null checking? Here creates the buffer, and if an inputStream is null, there is work for CG, isn't it :)
Thanks anyway!

@metaruslan

This comment has been minimized.

metaruslan commented Sep 6, 2015

@dengn,
+1 for @njsand comment. The StringBuffer object is not shared between threads, it's totally "thread-confined", so there is no use in its thread-safety:)

@yallen011

This comment has been minimized.

yallen011 commented Sep 10, 2015

@jrmineur and @jhealy using the zip parameter doesn't work for all zipcodes. I think getting the correct city every time involves getting the city id but that involves knowing the correct longitude and latitude.

@maximusg

This comment has been minimized.

maximusg commented Sep 23, 2015

Oh wow that is fairly simple. One newbie question, why do we return the rootView at the end? Also what is with all the extra "}" at the end? Thanks!

@twhoward99

This comment has been minimized.

twhoward99 commented Sep 24, 2015

Thank you. The previous answer box didn't accept mode=JSON, but the API functioned properly with this parameter. Thanks again.

@tuhinsherlock

This comment has been minimized.

tuhinsherlock commented Oct 1, 2015

Should this be in "MainActivity" class or "MainActivityFragment" class?

@zano5

This comment has been minimized.

zano5 commented Oct 8, 2015

MainActivity class

@timbru31

This comment has been minimized.

timbru31 commented Oct 18, 2015

@bahkali

This comment has been minimized.

bahkali commented Oct 19, 2015

thank you. very explanatory

@mrrobot97

This comment has been minimized.

mrrobot97 commented Oct 25, 2015

Thanks a lot!It's much helpful.

@sebcagnon

This comment has been minimized.

sebcagnon commented Oct 26, 2015

Why don't we do like this?

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

I am no Java programmer, but this is the first answer for InputStream to String
http://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string

I just can't believe an InputStream would require 19 lines, 4 intermediary objects (buffer, reader, line, unnamed InputStreamReader) to convert it to a string.

Is it all for the sake of adding \n in between lines?

Another question, the json output from the query doesn't have lines. So where are we writing all those \n?

@marianosalvetti

This comment has been minimized.

marianosalvetti commented Nov 3, 2015

Thanks a lot, it's helpful .

@ganeshachary

This comment has been minimized.

ganeshachary commented Nov 8, 2015

Thanks

@Rolos

This comment has been minimized.

Rolos commented Nov 22, 2015

I'm here too!

@dandv

This comment has been minimized.

dandv commented Nov 25, 2015

Like @sebcagnon above, this low-level Java code makes my head hurt. The equivalent JavaScript code for the Meteor framework (which generates web and mobile apps from the same code base) is far, far simpler:

HTTP.get("http://api.openweathermap.org/data/...", function (error, result) {
    if (error) {
        ...
    } else {
        let weatherData = result.data;  // JSON automatically parsed
    }
});

No need to get more complicated than what you actually want to do - get a JSON string via HTTP. Given that this course is aimed at beginners, it might have made more sense to use a high-level HTTP library such as Volley.

PS: no need to say "Thanks"; GitHub doesn't send notifications of activity on gists.

@marzoukali

This comment has been minimized.

marzoukali commented Nov 29, 2015

Amazing, thank you

@nareshcode

This comment has been minimized.

nareshcode commented Nov 30, 2015

i didnt get what is rootview the return type variable.It is a string right

@SeifMostafa

This comment has been minimized.

SeifMostafa commented Dec 9, 2015

don't forget to make comment in the url as the website needs id for now

@anandbibek

This comment has been minimized.

anandbibek commented Dec 12, 2015

I'm not exactly sure, but the correct url seems to be http://api.openweathermap.org/data/2.5/forecast/daily?id=5375480&cnt=7&appid=xxxxxxxxxxxxxxxxxxxxxxxx

Can't figure out what is q parameter being used, which is not mentioned in current API. And the present url gives a city in Poland. Basically because we have to use id now, and zip code is deprecated I guess.

@ghost

This comment has been minimized.

ghost commented Dec 15, 2015

Consider this URL. When requesting postal codes use the 'zip' parameter. Also the new format for weather apis require an appid.

http://api.openweathermap.org/data/2.5/forecast?zip=94043&metric&cnt=7&appid=2de143494c0b295cca9337e1e96b00e0

The codes presented in this course are not static. As the days go by, newer libraries are created and some codes become deprecated. It's up to you, the programmer, to debug the code that doesn't work.

@khanhnv3007

This comment has been minimized.

khanhnv3007 commented Dec 17, 2015

nice 💃

@williamboxhall

This comment has been minimized.

williamboxhall commented Jan 15, 2016

ace!

@b03902043

This comment has been minimized.

b03902043 commented Jan 24, 2016

great!

@ambitionwang277

This comment has been minimized.

ambitionwang277 commented Jan 26, 2016

Thanks a lot.

@marciliooliveira

This comment has been minimized.

marciliooliveira commented Jan 29, 2016

Guys, someone can help me?

I've gotten this error when I put my code on fragment, It's about async (I saw in StackOverflow) threads or some like that?

01-29 00:56:10.194 21852-21852/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.sunshine.app, PID: 21852
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.sunshine.app/com.example.android.sunshine.app.MainActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)

Tks.

@JustinNam

This comment has been minimized.

JustinNam commented Jan 30, 2016

why in my code error buffer not initialization ??

@rishsethia

This comment has been minimized.

rishsethia commented Feb 1, 2016

Why do we need a inputstream when we have a bufferdreader? Actually I am confused about this . Could someone please help?

@SiddharthPant

This comment has been minimized.

SiddharthPant commented Feb 1, 2016

In my competitive coding escapades I have used more complex form of input reading system which involved StringTokenizer etc. So this is not new to me. Why are we using these two? Well its because InputStreamReader takes byte stream and converts into one character at a time from input while BufferedReader then stores that and keeps buffering till a full line has been read. When this has been done we then just need to read our buffered string in one go. Without BufferedReader we will have to use a loop that stores everything in a char array character by character not a very efficient proposition. As for not using Scanner class I can't say if its the reason but in my experience Scanner class is terribly slow.

@fzls

This comment has been minimized.

fzls commented Feb 2, 2016

thanks a lot!

@abhi007tyagi

This comment has been minimized.

abhi007tyagi commented Feb 2, 2016

@dengn @njsand @wahooka9
check below link. Looks like String Builder would be better choice.

@AIRAT1

This comment has been minimized.

AIRAT1 commented Feb 6, 2016

Herzlichen Dank!

@abhinandankothari

This comment has been minimized.

abhinandankothari commented Feb 6, 2016

@abhi007tyagi Thanks for the link 👍

@TasneemS

This comment has been minimized.

TasneemS commented Feb 8, 2016

I think this code should be in the MainActivityFragment class in newer versions.

@Ashish680

This comment has been minimized.

Ashish680 commented Feb 11, 2016

http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7

this given url in the code above is not working it showing a error page

@pitlv2109

This comment has been minimized.

pitlv2109 commented Feb 11, 2016

@Ashish680
Now that the OpenWeatherMap requires API key to make requests (http://openweathermap.org/faq#error401). It should be http://api.openweathermap.org/data/2.5/forecast/daily?zip=94043&mode=json&units=metric&cnt=7&APPID=put-your-id-here. (You can always paste it into your web browser to check the result).

@mousaab

This comment has been minimized.

mousaab commented Feb 14, 2016

It is true that the OpenWeatherMap requires API key
put any one can use this key:
appid=44db6a862fba0b067b1930da0d769e98
so your URL should be like this ;
http://api.openweathermap.org/data/2.5/find?lat=57&lon=-2.15&cnt=3&appid=44db6a862fba0b067b1930da0d769e98

@denkomanceski

This comment has been minimized.

denkomanceski commented Feb 22, 2016

I cant believe that it takes 60 lines of code to make one GET request. I come from web background. We need 1 line there :(

@galagade

This comment has been minimized.

galagade commented Feb 23, 2016

beautiful code

@bkmagnetron

This comment has been minimized.

bkmagnetron commented Feb 23, 2016

@dandv @denkomanceski 👍 same feeling And I think more annoyingly, you don't see all of the try-catch blocks here.

Here is a simpler version.
how to send HttpRequest and get Json response in android?

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget= new HttpGet(new URL("http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7"));
String forecastJsonStr;

HttpResponse response = httpclient.execute(httpget);

if(response.getStatusLine().getStatusCode()==200){
   forecastJsonStr = EntityUtils.toString(response.getEntity());
} else {
   Log.i("Server response", "Failed to get server response" );
}
@MostafaAnter

This comment has been minimized.

MostafaAnter commented Feb 27, 2016

i recommend using volley is the best solution with few lines 👍
volley, Easy fast Networking library for android

@skielosky

This comment has been minimized.

skielosky commented Feb 27, 2016

Thanks !

@bkmagnetron

This comment has been minimized.

bkmagnetron commented Mar 2, 2016

This is my understanding of this code snippet,

Task
We have to send a HTTP request to an URL and GET some data.

Solving

  • Create a new variable for the URL
    new URL(...)
  • Use the URL to create and open HttpURLConnection
    openConnection()
  • Now send a GET request
    setRequestMethod("GET")
  • If we get response for our request
    inputStream != null
    buffer the data and store it as a String.
    new BufferedReader()
  • And "finally" close the HttpURLConnection
    disconnect()

Simply as open, request, response, close.

@Ashwin-Kapes

This comment has been minimized.

Ashwin-Kapes commented Mar 10, 2016

Instead of (buffer.length() == 0) can we write (buffer == null). Please explain.

@augustocarmo

This comment has been minimized.

augustocarmo commented Mar 15, 2016

Thank you very much!!!

@wilik16

This comment has been minimized.

wilik16 commented Mar 16, 2016

@Ashwin-Kapes you can't, because the buffer is instantiated already = new StringBuffer(); thus not null.

@saberelharti

This comment has been minimized.

saberelharti commented Mar 16, 2016

thank u

@AbdouElnemr

This comment has been minimized.

AbdouElnemr commented Mar 16, 2016

Thank You

@kyodgorbek

This comment has been minimized.

kyodgorbek commented Mar 17, 2016

I am getting error following error

Executing tasks: [:app:assembleDebug]

Configuration on demand is an incubating feature.
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAnimatedVectorDrawable2321Library UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72321Library UP-TO-DATE
:app:prepareComAndroidSupportDesign2321Library UP-TO-DATE
:app:prepareComAndroidSupportRecyclerviewV72321Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42321Library UP-TO-DATE
:app:prepareComAndroidSupportSupportVectorDrawable2321Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppindexing810Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesBasement810Library UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:compileDebugJavaWithJavac
/home/yodgorbek/AndroidStudioProjects/Sunshine/app/src/main/java/com/example/android/sunshine/MainActivity.java:117: error: non-static method getInputStream() cannot be referenced from a static context
InputStream inputStream = URLConnection.getInputStream();
^
Note: /home/yodgorbek/AndroidStudioProjects/Sunshine/app/src/main/java/com/example/android/sunshine/MainActivity.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 error

FAILED

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':app:compileDebugJavaWithJavac'.

    Compilation failed; see the compiler error output for details.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1.303 secs

@alexisforce

This comment has been minimized.

alexisforce commented Mar 22, 2016

Google + Udacity = Best Combination ever.... Thanks for all, Very intuitive way to teach

@KosratDAhmad

This comment has been minimized.

KosratDAhmad commented Mar 22, 2016

Thank you, That is great

@JLundho

This comment has been minimized.

JLundho commented Mar 27, 2016

To mix it up and simplify the networking tasks, I used OkHttp to perform the network request (which also reduced the boilerplate), but this resulted in an exception saying that I was attempting to perform network operations on the main thread. Did this always create an exception?
If you stumble onto the same problem, use AsyncTask and remember to request the appropriate permissions.

@mahasagar

This comment has been minimized.

mahasagar commented Apr 4, 2016

awesome

@Danihelsan

This comment has been minimized.

Danihelsan commented Apr 5, 2016

Thanks

@Nicofisi

This comment has been minimized.

Nicofisi commented Apr 9, 2016

Great ^^

@PrafullaKumarSahu

This comment has been minimized.

PrafullaKumarSahu commented Apr 12, 2016

@Nicofisi and @Danihelsan if possible please share your snippet I am getting error

04-12 20:31:01.652 5740-5740/com.android.serverwarrior.sunshine.app E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                      java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.serverwarrior.sunshine.app/com.android.serverwarrior.sunshine.app.MainActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
                                                                                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2255)
                                                                                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2309)
                                                                                          at android.app.ActivityThread.access$700(ActivityThread.java:157)
                                                                                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289)
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                          at android.os.Looper.loop(Looper.java:176)
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:5317)
                                                                                          at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                          at java.lang.reflect.Method.invoke(Method.java:511)
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
                                                                                          at dalvik.system.NativeStart.main(Native Method)
                                                                                       Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
                                                                                          at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:710)
                                                                                          at android.view.LayoutInflater.parseInclude(LayoutInflater.java:818)
                                                                                          at android.view.LayoutInflater.rInflate(LayoutInflater.java:742)
                                                                                          at android.view.LayoutInflater.inflate(LayoutInflater.java:495)
                                                                                          at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
                                                                                          at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
                                                                                          at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:276)
                                                                                          at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
                                                                                          at com.android.serverwarrior.sunshine.app.MainActivity.onCreate(MainActivity.java:17)
                                                                                          at android.app.Activity.performCreate(Activity.java:5326)
                                                                                          at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
                                                                                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2218)
                                                                                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2309) 
                                                                                          at android.app.ActivityThread.access$700(ActivityThread.java:157) 
                                                                                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289) 
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:99) 
                                                                                          at android.os.Looper.loop(Looper.java:176) 
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:5317) 
                                                                                          at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                          at java.lang.reflect.Method.invoke(Method.java:511) 
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
                                                                                          at dalvik.system.NativeStart.main(Native Method) 
                                                                                       Caused by: android.os.NetworkOnMainThreadException
                                                                                          at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1128)
                                                                                          at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
                                                                                          at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
                                                                                          at java.net.InetAddress.getAllByName(InetAddress.java:214)
                                                                                          at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
                                                                                          at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
                                                                                          at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
                                                                                          at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
                                                                                          at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
                                                                                          at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
                                                                                          at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)
                                                                                          at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
                                                                                          at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
                                                                                          at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:81)
                                                                                          at com.android.serverwarrior.sunshine.app.MainActivityFragment.onCreateView(MainActivityFragment.java:68)
                                                                                          at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
                                                                                          at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1036)
                                                                                          at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1230)
                                                                                          at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1332)
                                                                                          at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2288)
                                                                                          at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:120)
                                                                                          at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:357)
                                                                                          at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
                                                                                          at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:80)
                                                                                          at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:686)
@ronengi

This comment has been minimized.

ronengi commented Apr 14, 2016

Thanks

@andredelgado

This comment has been minimized.

andredelgado commented Apr 15, 2016

thanks

@miriban

This comment has been minimized.

miriban commented Apr 16, 2016

Thanks

@marlonlom

This comment has been minimized.

marlonlom commented Apr 20, 2016

@PrafullaKumarSahu ... i think is related to yout fragment initialization, besides, have you reviewed the http response of the query?
i just copied that snippet and it works :)

@ghost

This comment has been minimized.

ghost commented May 7, 2016

Thanks!

@Tacfarinas

This comment has been minimized.

Tacfarinas commented May 17, 2016

great

@progdog

This comment has been minimized.

progdog commented May 23, 2016

Thank you very much!

@mur7ay

This comment has been minimized.

mur7ay commented May 23, 2016

@PrafullaKumarSahu Did you figure it out or do you still need help?

@bangonkali

This comment has been minimized.

bangonkali commented May 27, 2016

Nice.

@Hossein-Ghanaati

This comment has been minimized.

Hossein-Ghanaati commented May 30, 2016

i get errors in all "return null;" lines

@windog

This comment has been minimized.

windog commented Jun 2, 2016

Awesome!!thanks a lot.
but the Http request method was changed.
Now you can use the following address:
http://api.openweathermap.org/data/2.5/forecast/city?q=mountainview&APPID={your APPID}

@rajat1saxena

This comment has been minimized.

rajat1saxena commented Jun 2, 2016

I would suggest users to replace line 34 with the following

buffer.append(line).append("\n"); // Replaced string concatenation inside append

As string concatenation inside buffer.append() will lead to the creation of yet another StringBuffer on the fly, which degrades performance. It is a good practice to avoid string concatenation inside loops (read more about it in an awesome book: Effective Java)

@gpetuhov

This comment has been minimized.

gpetuhov commented Jun 20, 2016

Thanks a lot!

@Clumsy-Coder

This comment has been minimized.

Clumsy-Coder commented Jun 20, 2016

@PrafullaKumarSahu
I had a problem executing the code from the snippet above. Turns out it was NetworkOnMainThreadException. Which means the network access has occured in the main thread. Which is highly discouraged. I have found a small work around. This is a dirty approach. It should be only used for checking if the code works. Here is my solution.

The following code is in the onCreateView(LayoutInflator, ViewGroup, Bundle) method in the PlaceholderFragment subclass:

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
StrictMode.setThreadPolicy(policy);

The following is in the AndroidManifest.xml file.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
The two xml elements are placed as a child of manifest and are siblings to the application element

@ManishaRana1195

This comment has been minimized.

ManishaRana1195 commented Jul 27, 2016

The same can be achieved with the following code:

String forecastJsonStr = null;
URL url = new URL("http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7");
try {

          OkHttpClient client = new OkHttpClient();
          Request request = new Request.Builder().url(url).build();
          response = client.newCall(request).execute();
          forecastJsonStr = response.body().string();

           } catch (IOException e) {
              e.printStackTrace();
        }
            return forecastJsonStr;
}

For above to work, you have to add following line to your gradle:

compile {
     compile 'com.squareup.okhttp3:okhttp:3.4.1'
        }
@mj-ghani004

This comment has been minimized.

mj-ghani004 commented Jul 27, 2016

i am just new to android
when i add this code into new file there i am having error for rootView.
inside of doInBackGround its saying rootView is undefined although all this code is still part of Fragment.
Any Suggestion?

@rduncan354

This comment has been minimized.

rduncan354 commented Aug 1, 2016

Thanks a lot!

@Alreco

This comment has been minimized.

Alreco commented Aug 2, 2016

Thanks a lot!

@code-dagger

This comment has been minimized.

code-dagger commented Aug 14, 2016

Why we are using StringBuffer ?

@ArkinDharawat

This comment has been minimized.

ArkinDharawat commented Aug 19, 2016

Thanks!

@tgmarinho

This comment has been minimized.

tgmarinho commented Aug 24, 2016

cool =) Tks

@ibo-coder

This comment has been minimized.

ibo-coder commented Aug 26, 2016

Great

@Claiger

This comment has been minimized.

Claiger commented Sep 3, 2016

So I'm getting the same error that PrafullaKumarSahu was getting. I'm not sure what the reason is. I saw the comment about the dirty approach but I'd rather have some sort of fix I can maintain in the system. I'm trying to publish my code to Github and am having problems so in the meantime I'll pose the question.

@andrueastman

This comment has been minimized.

andrueastman commented Sep 7, 2016

Thanks!

@mohammedhassan2525

This comment has been minimized.

mohammedhassan2525 commented Sep 27, 2016

Thanks

@torresjorgev

This comment has been minimized.

torresjorgev commented Sep 30, 2016

Thanks! a nice code to teach basics

@alextudu

This comment has been minimized.

alextudu commented Oct 2, 2016

Great Code!

@porzioj

This comment has been minimized.

porzioj commented Oct 3, 2016

Thanks

@hvubio

This comment has been minimized.

hvubio commented Oct 11, 2016

Thanks!

@YassinAJDI

This comment has been minimized.

YassinAJDI commented Oct 16, 2016

Thanks a lot!

@grimmjhow

This comment has been minimized.

grimmjhow commented Oct 16, 2016

Thanks! =]

@shinabarger

This comment has been minimized.

shinabarger commented Nov 8, 2016

Excellent.

@chandradeep01

This comment has been minimized.

chandradeep01 commented Nov 13, 2016

cool

@vikasdesale

This comment has been minimized.

vikasdesale commented Dec 5, 2016

Thanks

@Preeti-gupta02

This comment has been minimized.

Preeti-gupta02 commented Dec 18, 2016

Thanks!!

@LuisAlvarez12

This comment has been minimized.

LuisAlvarez12 commented Jan 4, 2017

Thank you!

@diogocapela

This comment has been minimized.

diogocapela commented Jan 12, 2017

Ty

@Miltex

This comment has been minimized.

Miltex commented Jan 14, 2017

Cool :D

@shirleyhu12

This comment has been minimized.

shirleyhu12 commented Jun 30, 2017

@Clumsy-Coder your comment was super helpful! I had the same problem and couldn't figure out why earlier!

@lephleg

This comment has been minimized.

lephleg commented Dec 10, 2017

The daily forecast has been removed for the free subscibers. Try to use 5 days 3 hour forecast endpoint instead:
https://openweathermap.org/price

@dnmanveet

This comment has been minimized.

dnmanveet commented Apr 5, 2018

package com.example.android.sunshine.app;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    ArrayAdapter<String> mForecastAdapter;

    public PlaceholderFragment() {
    }

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

        // Create some dummy data for the ListView.  Here's a sample weekly forecast
        String[] data = {
                "Mon 6/23 - Sunny - 31/17",
                "Tue 6/24 - Foggy - 21/8",
                "Wed 6/25 - Cloudy - 22/17",
                "Thurs 6/26 - Rainy - 18/11",
                "Fri 6/27 - Foggy - 21/10",
                "Sat 6/28 - TRAPPED IN WEATHERSTATION - 23/18",
                "Sun 6/29 - Sunny - 20/7"
        };
        List<String> weekForecast = new ArrayList<String>(Arrays.asList(data));


        // Now that we have some dummy forecast data, create an ArrayAdapter.
        // The ArrayAdapter will take data from a source (like our dummy forecast) and
        // use it to populate the ListView it's attached to.
        mForecastAdapter =
                new ArrayAdapter<String>(
                        getActivity(), // The current context (this activity)
                        R.layout.list_item_forecast, // The name of the layout ID.
                        R.id.list_item_forecast_textview, // The ID of the textview to populate.
                        weekForecast);

        View rootView = inflater.inflate(R.layout.fragment_main, container, false);


        // Get a reference to the ListView, and attach this adapter to it.
        ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast);
        listView.setAdapter(mForecastAdapter);

        // These two need to be declared outside the try/catch
        // so that they can be closed in the finally block.
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;

        // Will contain the raw JSON response as a string.
        String forecastJsonStr = null;

        try {
            // Construct the URL for the OpenWeatherMap query
            // Possible parameters are avaiable at OWM's forecast API page, at
            // http://openweathermap.org/API#forecast
            URL url = new URL("http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7");

            // Create the request to OpenWeatherMap, and open the connection
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // Read the input stream into a String
            InputStream inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null) {
                // Nothing to do.
                return null;
            }
            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {
                // Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
                // But it does make debugging a *lot* easier if you print out the completed
                // buffer for debugging.
                buffer.append(line + "\n");
            }

            if (buffer.length() == 0) {
                // Stream was empty.  No point in parsing.
                return null;
            }
            forecastJsonStr = buffer.toString();
        } catch (IOException e) {
            Log.e("PlaceholderFragment", "Error ", e);
            // If the code didn't successfully get the weather data, there's no point in attemping
            // to parse it.
            return null;
        } finally{
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e("PlaceholderFragment", "Error closing stream", e);
                }
            }
        }

        return rootView;
    }
}

}
i implemented my code like this and my app is crashing what might be the reason for it??????

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment