I have a url: https://api.spreaker.com/v2/users/7725967/episodes?limit=1
. I am trying to get to the variables in the JSON results.
Using Spring for Android, I have the following code:
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
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.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@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);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
protected void onStart() {
super.onStart();
new HttpRequestTask().execute();
}
private class HttpRequestTask extends AsyncTask<Void, Void, RadioInfo> {
@Override
protected RadioInfo doInBackground(Void... params) {
try {
final String url = "https://api.spreaker.com/v2/users/7725967/episodes?limit=1";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
return restTemplate.getForObject(url, RadioInfo.class);
} catch (Exception e) {
Log.e("MainActivity", e.getMessage(), e);
}
return null;
}
@Override
protected void onPostExecute(RadioInfo radioInfo) {
TextView radioInfoIdText = (TextView) findViewById(R.id.songName);
TextView radioInfoTypeText = (TextView) findViewById(R.id.radioInfo);
TextView radioInfoIdRadio = (TextView) findViewById(R.id.showInfo);
radioInfoIdText.setText(radioInfo.getTitle());
radioInfoTypeText.setText(radioInfo.getType());
radioInfoIdRadio.setText(radioInfo.getId());
}
}
}
My JSON output is as follows:
{
"response": {
"items": [
{
"episode_id": 9019035,
"type": "RECORDED",
"title": "Abu Mohamed",
"duration": 5046750,
"show_id": 1392547,
"author_id": 7725967,
"site_url": "https://www.spreaker.com/episode/9019035",
"image_url": "https://d1bm3dmew779uf.cloudfront.net/large/618b5806c9854bc8379ded0c27cc0694.jpg",
"image_original_url": "https://d3wo5wojvuv7l.cloudfront.net/images.spreaker.com/original/618b5806c9854bc8379ded0c27cc0694.jpg",
"published_at": "2016-07-20 01:13:37",
"download_enabled": true,
"waveform_url": "https://d3770qakewhkht.cloudfront.net/episode_9019035.gz.json?v=a7ZcQU"
}
],
"next_url": "https://api.spreaker.com/v2/users/7725967/episodes?filter=listenable&last_id=9019035&limit=1"
}
}
Here is my issue: Android studio throws a null error somewhere in these lines:
public class HttpRequestTask extends AsyncTask<Void, Void, RadioInfo> {
@Override
protected RadioInfo doInBackground(Void... params) {
try {
String url = "https://api.spreaker.com/v2/users/7725967/episodes?limit=1";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
String result = String.valueOf(restTemplate.getForObject(url, RadioInfo.class, "Android"));
return restTemplate.getForObject(url, RadioInfo.class);
} catch (Exception e) {
Log.e("MainActivity", e.getMessage(), e);
}
return null;
}
@Override
protected void onPostExecute(RadioInfo radioInfo) {
TextView radioInfoIdText = (TextView) findViewById(R.id.songName);
TextView radioInfoTypeText = (TextView) findViewById(R.id.type);
TextView radioInfoIdRadio = (TextView) findViewById(R.id.showInfo);
radioInfoIdText.setText(radioInfo.getTitle());
radioInfoTypeText.setText(radioInfo.getType());
radioInfoIdRadio.setText(radioInfo.getId());
}
}
I do not understand how it is a null I am returning. I think it's because of the JSON format, but I am not sure. I must be mapping it correctly as Jackson should handle this just fine.
How can I implement this correctly?
Here is my Radio class:
public class RadioInfo {
private String episode_id;
private String type;
private String title;
public String getId() {
return this.episode_id;
}
public String getType() {
return this.type;
}
public String getTitle() {
return this.title;
}
}
Update
The permissions error was due to me not being careful where I placed the internet permissions in the Android manifest XMl file.
So my original question is still in play, with a new stack trace on the JSON parsing and null object error:
07-23 19:45:47.613 14016-14084/software.blackstone.masjidtawheedmobileradio E/MainActivity: Could not read JSON: Unrecognized field "response" (class software.blackstone.masjidtawheedmobileradio.RadioInfo), not marked as ignorable (2 known properties: "title", "type"])
at [Source: buffer(com.android.okhttp.okio.GzipSource@dbb91a).inputStream(); line: 1, column: 14] (through reference chain: software.blackstone.masjidtawheedmobileradio.RadioInfo["response"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "response" (class software.blackstone.masjidtawheedmobileradio.RadioInfo), not marked as ignorable (2 known properties: "title", "type"])
at [Source: buffer(com.android.okhttp.okio.GzipSource@dbb91a).inputStream(); line: 1, column: 14] (through reference chain: software.blackstone.masjidtawheedmobileradio.RadioInfo["response"])
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "response" (class software.blackstone.masjidtawheedmobileradio.RadioInfo), not marked as ignorable (2 known properties: "title", "type"])
at [Source: buffer(com.android.okhttp.okio.GzipSource@dbb91a).inputStream(); line: 1, column: 14] (through reference chain: software.blackstone.masjidtawheedmobileradio.RadioInfo["response"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "response" (class software.blackstone.masjidtawheedmobileradio.RadioInfo), not marked as ignorable (2 known properties: "title", "type"])
at [Source: buffer(com.android.okhttp.okio.GzipSource@dbb91a).inputStream(); line: 1, column: 14] (through reference chain: software.blackstone.masjidtawheedmobileradio.RadioInfo["response"])
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readInternal(MappingJackson2HttpMessageConverter.java:126)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:147)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:76)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:484)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
at software.blackstone.masjidtawheedmobileradio.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:133)
at software.blackstone.masjidtawheedmobileradio.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:126)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
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: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "response" (class software.blackstone.masjidtawheedmobileradio.RadioInfo), not marked as ignorable (2 known properties: "title", "type"])
at [Source: buffer(com.android.okhttp.okio.GzipSource@dbb91a).inputStream(); line: 1, column: 14] (through reference chain: software.blackstone.masjidtawheedmobileradio.RadioInfo["response"])
at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:671)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:771)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1297)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1275)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:247)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose
07-23 19:45:47.674 14016-14016/software.blackstone.masjidtawheedmobileradio D/AndroidRuntime: Shutting down VM
--------- beginning of crash
07-23 19:45:47.686 14016-14016/software.blackstone.masjidtawheedmobileradio E/AndroidRuntime: FATAL EXCEPTION: main
Process: software.blackstone.masjidtawheedmobileradio, PID: 14016
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String software.blackstone.masjidtawheedmobileradio.RadioInfo.getTitle()' on a null object reference
at software.blackstone.masjidtawheedmobileradio.MainActivity$HttpRequestTask.onPostExecute(MainActivity.java:148)
at software.blackstone.masjidtawheedmobileradio.MainActivity$HttpRequestTask.onPostExecute(MainActivity.java:126)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
07-23 19:50:48.015 14016-14016/software.blackstone.masjidtawheedmobileradio I/Process: Sending signal. PID: 14016 SIG: 9