I am working on an Android Application using Android Studio that uses the http://open-platform.theguardian.com/explore/ API. I am having trouble running the application. I will include some code snippets with the error I am coming across. If anyone needs any additional information to assist please let me know. I appreciate your time in looking at this.
This is the Error I am running into:
E/AndroidRuntime: FATAL EXCEPTION: ModernAsyncTask #1
Process: com.timothykocik.newsapp, PID: 32631
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:161)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.SecurityException: Permission denied (missing INTERNET permission?)
at java.net.InetAddress.lookupHostByName(InetAddress.java:464)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:220)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:176)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:108)
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:482)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:465)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:447)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:353)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:468)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:118)
at com.timothykocik.newsapp.QueryUtils.makeHttpRequest(QueryUtils.java:83)
at com.timothykocik.newsapp.NewsLoader.loadInBackground(NewsLoader.java:32)
at com.timothykocik.newsapp.NewsLoader.loadInBackground(NewsLoader.java:15)
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:299)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:57)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:45)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:138)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
at libcore.io.Posix.android_getaddrinfo(Native Method)
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
at java.net.InetAddress.lookupHostByName(InetAddress.java:451)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:220)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:176)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:108)
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:482)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:465)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:447)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:353)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:468)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:118)
at com.timothykocik.newsapp.QueryUtils.makeHttpRequest(QueryUtils.java:83)
at com.timothykocik.newsapp.NewsLoader.loadInBackground(NewsLoader.java:32)
at com.timothykocik.newsapp.NewsLoader.loadInBackground(NewsLoader.java:15)
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:299)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:57)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:45)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:138)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.ErrnoException: android_getaddrinfo failed: EACCES (Permission denied)
This is my QueryUtils Java File:
public class QueryUtils {
static String createStringUrl() {
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
.encodedAuthority("content.guardianapis.com")
.appendPath("search")
.appendQueryParameter("order-by", "newest")
.appendQueryParameter("show-references", "author")
.appendQueryParameter("show-tags", "contributor")
.appendQueryParameter("q", "Android")
.appendQueryParameter("api-key", "test");
String url = builder.build().toString();
return url;
}
static URL createUrl() {
String stringUrl = createStringUrl();
try {
return new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e("Queryutils", "Error creating URL: ", e);
return null;
}
}
private static String formatDate(String rawDate) {
String jsonDatePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";
SimpleDateFormat jsonFormatter = new SimpleDateFormat(jsonDatePattern, Locale.US);
try {
Date parsedJsonDate = jsonFormatter.parse(rawDate);
String finalDatePattern = "MMM d, yyy";
SimpleDateFormat finalDateFormatter = new SimpleDateFormat(finalDatePattern, Locale.US);
return finalDateFormatter.format(parsedJsonDate);
} catch (ParseException e) {
Log.e("QueryUtils", "Error parsing JSON date: ", e);
return "";
}
}
static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
if (url == null){
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.connect();
if (urlConnection.getResponseCode() == 200){
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e("mainActivity", "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e("Queryutils", "Error making HTTP request: ", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
static List<News> parseJson(String response) {
ArrayList<News> listOfNews = new ArrayList<>();
try {
JSONObject jsonResponse = new JSONObject(response);
JSONObject jsonResults = jsonResponse.getJSONObject("response");
JSONArray resultsArray = jsonResults.getJSONArray("results");
for (int i = 0; i < resultsArray.length(); i++) {
JSONObject oneResult = resultsArray.getJSONObject(i);
String webTitle = oneResult.getString("webTitle");
String url = oneResult.getString("webUrl");
String date = oneResult.getString("webPublicationDate");
date = formatDate(date);
String section = oneResult.getString("sectionName");
JSONArray tagsArray = oneResult.getJSONArray("tags");
String author = "";
if (tagsArray.length() == 0) {
author = null;
} else {
for (int j = 0; j < tagsArray.length(); j++) {
JSONObject firstObject = tagsArray.getJSONObject(j);
author += firstObject.getString("webTitle") + ". ";
}
}
listOfNews.add(new News(webTitle, author, url, date, section));
}
} catch (JSONException e) {
Log.e("Queryutils", "Error parsing JSON response", e);
}
return listOfNews;
}
}
MainActivity.java
public class MainActivity
extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<List<News>>, SwipeRefreshLayout.OnRefreshListener {
private NewsAdapter adapter;
private static int LOADER_ID = 0;
SwipeRefreshLayout swipe;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swipe = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
swipe.setOnRefreshListener(this);
swipe.setColorSchemeColors(getResources().getColor(R.color.colorAccent));
ListView listView = (ListView) findViewById(R.id.list_view);
adapter = new NewsAdapter(this);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
News news = adapter.getItem(i);
String url = news.url;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
}
});
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
}
@Override
public Loader<List<News>> onCreateLoader(int id, Bundle args) {
return new NewsLoader(this);
}
@Override
public void onLoadFinished(Loader<List<News>> loader, List<News> data) {
swipe.setRefreshing(false);
if (data != null) {
adapter.setNotifyOnChange(false);
adapter.clear();
adapter.setNotifyOnChange(true);
adapter.addAll(data);
}
}
@Override
public void onLoaderReset(Loader<List<News>> loader) {
}
@Override
public void onRefresh() {
getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
}
}