Please help me with this error. Even after passing value in execute() method I'm still unable to fix this issue.
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0 at com.iamsharzil.constraintlayoutproject.DownloadNews.doInBackground(DownloadNews.java:54) at com.iamsharzil.constraintlayoutproject.DownloadNews.doInBackground(DownloadNews.java:22)
DownloadNews.java
String NEWS_SOURCE = "bbc-news";
ArrayList<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>();
private Activity mContext;
String API_KEY = "4f5f4fbf57f7476ba41c276b28379a6b";
ListView listNews;
static final String KEY_AUTHOR = "author";
static final String KEY_TITLE = "title";
static final String KEY_DESCRIPTION = "description";
static final String KEY_URL = "url";
static final String KEY_URLTOIMAGE = "urlToImage";
static final String KEY_PUBLISHEDAT = "publishedAt";
public DownloadNews(BaseDrawerActivity mContext) {
this.mContext = mContext;
Log.i("Constructor", "Download News called");
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
String xml = "";
String url = args[0];
Log.i("URL", url);
xml = Function.executeGet(url);
return xml;
}
@Override
protected void onPostExecute(String xml) {
if(null != xml && xml.length()>10) {
try {
JSONObject jsonResponse = new JSONObject(xml);
JSONArray jsonArray = jsonResponse.optJSONArray("articles");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_AUTHOR, jsonObject.optString(KEY_AUTHOR).toString());
map.put(KEY_TITLE, jsonObject.optString(KEY_TITLE).toString());
map.put(KEY_DESCRIPTION, jsonObject.optString(KEY_DESCRIPTION).toString());
map.put(KEY_URL, jsonObject.optString(KEY_URL).toString());
map.put(KEY_URLTOIMAGE, jsonObject.optString(KEY_URLTOIMAGE).toString());
map.put(KEY_PUBLISHEDAT, jsonObject.optString(KEY_PUBLISHEDAT).toString());
dataList.add(map);
}
} catch (JSONException e) {
Toast.makeText(mContext, "Unexpected error", Toast.LENGTH_SHORT).show();
}
listNews = (ListView) mContext.findViewById(R.id.listNews);
ListNewsAdapter adapter = new ListNewsAdapter((Activity) mContext, dataList);
listNews.setAdapter(adapter);
listNews.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(mContext, DetailsActivity.class);
i.putExtra("url", dataList.get(+position).get(KEY_URL));
mContext.startActivity(i);
}
});
}else{
Toast.makeText(mContext, "No news found", Toast.LENGTH_SHORT).show();
}
}
}
BaseDrawerActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_drawer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle("NEWS");
listNews = (ListView) findViewById(R.id.listNews);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
if(Function.isNetworkAvailable(getApplicationContext()))
{
DownloadNews newsTask = new DownloadNews(this);
newsTask.execute();
}else{
Toast.makeText(getApplicationContext(), "No Internet Connection", Toast.LENGTH_LONG).show();
}
}
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.nav_general) {
String general = "https://newsapi.org/v2/top-headlines?country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(general);
} else if (id == R.id.nav_sports) {
String sports = "https://newsapi.org/v2/top-headlines?categoty=sports&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(sports);
} else if (id == R.id.nav_business) {
String business = "https://newsapi.org/v2/top-headlines?categoty=business&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(business);
} else if (id == R.id.nav_technology) {
String technology = "https://newsapi.org/v2/top-headlines?categoty=technology&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(technology);
} else if (id == R.id.nav_entertainment) {
String entertainment = "https://newsapi.org/v2/top-headlines?categoty=entertainment&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(entertainment);
} else if (id == R.id.nav_health) {
String health = "https://newsapi.org/v2/top-headlines?categoty=health&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(health);
} else if (id == R.id.nav_science) {
String science = "https://newsapi.org/v2/top-headlines?categoty=science&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(science);
}
if(fragment!=null) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.screen_area, fragment);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
When a user click on any of the Menu item I want the url to be change.
Function.java
public class Function {
public static boolean isNetworkAvailable(Context context) {
return ((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)).
getActiveNetworkInfo()!=null;
}
public static String executeGet(String targetURL) {
URL url;
HttpURLConnection connection = null;
try {
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
//connection.setRequestMethod("POST");
//connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("content-type", "application/json; charset=utf-8");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(false);
InputStream is;
int status = connection.getResponseCode();
if (status != HttpURLConnection.HTTP_OK)
is = connection.getErrorStream();
else
is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
}
You are calling execute here:
if(Function.isNetworkAvailable(getApplicationContext()))
{
DownloadNews newsTask = new DownloadNews(this);
newsTask.execute(); // <-
}else{
Toast.makeText(getApplicationContext(), "No Internet Connection", Toast.LENGTH_LONG).show();
}
But are not passing an argument. That will cause your method to fail because you cannot access the zeroth item of a zero length array. You either need to ensure you are always passing data to it, or you need to do something like this:
protected String doInBackground(String... args) {
String xml = "";
if (args.length > 0) {
String url = args[0];
Log.i("URL", url);
xml = Function.executeGet(url);
}
return xml;
}
This way, if args
is empty, you return an empty string and can then handle for that where you need to.