Error Parsing Twitter trend/place api with retrofit - android

I am trying to parse twitter/trends/place api to my android app with retrofit, however, i have been able to parse the api below with retrofit and i get all my desired data:
https://api.twitter.com/1.1/search/tweets.json,
am using the same approach for https://api.twitter.com/1.1/trends/place.json, but i am getting this exception
GSON throwing “Expected BEGIN_OBJECT but was BEGIN_ARRAY
Below is my code. i believe my error is coming from one of the code below, some should please help me.
TwitterApiService.java
public interface TwitterApiService {
#GET(ApiConstants.TWITTER_TREND_SEARCH_CODE )
void getTweetTagList(
#Header("Authorization") String authorization,
#Query("id") String id,
Callback<TweetTagList> callback
);
#FormUrlEncoded
#POST("/oauth2/token")
void getToken(
#Header("Authorization") String authorization,
#Field("grant_type") String grantType,
Callback<TwitterTokenType> response
);
}
TwitterServiceProvider.java
public class TwitterServiceProvider {
private static final String TAG = TwitterServiceProvider.class.getName();
private TwitterApiService mApi;
private Bus mBus;
public TwitterServiceProvider(TwitterApiService api, Bus bus) {
this.mApi = api;
this.mBus = bus;
}
#Subscribe
public void onLoadTweets(final SearchTweetsTagEvent event) {
mApi.getTweetTagList("Bearer " + event.twitterToken, event.id, new Callback<TweetTagList>() {
#Override
public void success(TweetTagList response, Response rawResponse) {
mBus.post(new SearchTweetsTagEventOk(response));
}
#Override
public void failure(RetrofitError error) {
Log.e(TAG, error.toString(), error);
mBus.post(new SearchTweetsEventFailed());
}
});
}
#Subscribe
public void onGetToken(TwitterGetTokenEvent event) {
try {
mApi.getToken("Basic " + getBase64String(ApiConstants.BEARER_TOKEN_CREDENTIALS), "client_credentials", new Callback<TwitterTokenType>() {
#Override
public void success(TwitterTokenType token, Response response) {
PrefsController.setAccessToken(TwitterSearchApplication.getAppContext(), token.accessToken);
PrefsController.setTokenType(TwitterSearchApplication.getAppContext(), token.tokenType);
mBus.post(new TwitterGetTokenEventOk());
}
#Override
public void failure(RetrofitError error) {
Log.e(TAG, error.toString(), error);
mBus.post(new TwitterGetTokenEventFailed());
}
});
} catch (UnsupportedEncodingException e) {
Log.e(TAG, e.toString(), e);
}
}
/*private static String getResponseBody(InputStream inputStream) {
StringBuilder sb = new StringBuilder();
BufferedReader bReader = null;
try {
bReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
String line = null;
while ((line = bReader.readLine()) != null) {
sb.append(line);
}
} catch (UnsupportedEncodingException ex) {
Log.e("LOG", "", ex);
} catch (ClientProtocolException ex1) {
Log.e("LOG", "", ex1);
} catch (IOException ex2) {
Log.e("LOG", "", ex2);
}
return sb.toString();
}*/
/*// converts a string of JSON data into a Twitter object
private static TweetList jsonToTweetLost(String result) {
TweetList twits = null;
if (result != null && result.length() > 0) {
try {
Gson gson = new Gson();
twits = gson.fromJson(result, TweetList.class);
} catch (IllegalStateException ex) {
Log.e("LOG", "",ex);
}
}
return twits;
}*/
}
Tweet.java
public class Tweet {
#SerializedName("created_at")
public String dateCreated;
#SerializedName("trends")
public TweetTag trend;
#Override
public String toString(){
return trend.nameTag;
}
}
TweetTagList.java
public class TweetList {
#SerializedName("")
public ArrayList<Tweet> tweets;
}
SearchTweetsTagEvent.java
public class SearchTweetsTagEvent {
public final String id;
public final String twitterToken;
public SearchTweetsTagEvent(String twitterToken, String hashtag) {
this.id = hashtag;
this.twitterToken = twitterToken;
}
}

Looks like you are using wrong model object for JSON response parsing. You can choose the proper one from twitter-kit-android. If I understand correctly Place.java is what you are looking for.

Related

how to retrieve below json data from server in android?

how to retrieve below json data from server in android? can you please guide me with an example? how to get UserRole from the below url?
http://beta.json-generator.com/api/json/get/4y2NmxAYf
Here's an example to retrieve json data from server
Add this dependency of the Gson library to the App's gradle:
compile 'com.google.code.gson:gson:2.4'
Create a model class
public class UserModel{
public String UserRole;
public String UserName;
public int Id;
public String Email;
public String getUserRole(){
return UserRole;
}
public void setUserRole(String _userRole){
UserRole = _userRole;
}
public String getUserName(){
return UserName;
}
public void setUserName(String _userName){
UserName = _userName;
}
public int getId(){
return Id;
}
public void setId(int _id){
Id = _id;
}
public String getEmail(){
return Email;
}
public void setEmail(String _email){
Email = _email;
}
}
Now use Gson library to convert data from server's response to the above model.(Note: Write these lines in the onPostExecute() of the AsyncTask Class)
#Override
protected void onPostExecute(final Boolean success) {
try {
if (success) {
if (responsecode == 200) {
//GSON responsedata
if(responsedata!=null) {
if (responsedata != "") {
List<UserModel> userlist = new ArrayList<UserModel>();
JSONArray jsonArray = new JSONArray(responsedata);
for (int i = 0; i < jsonArray.length(); i++) {
UserModel item = new UserModel();
item = new Gson().fromJson(jsonArray.getJSONObject(i).toString(), UserModel.class);
userlist.add(item);
}
}
}
} else if(responsecode==401){
// use toast display the specific error
}
}
else {
Toast.makeText(context, responsedata, Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(context, "Access denied!", Toast.LENGTH_LONG).show();
}
}
catch (Exception e){
if(e!=null){
}
}
}
You are getting json array in response. You can get details from array like:
try {
JSONArray jsonArray = new JSONArray(response);
for (int i=0; i<jsonArray.length();i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String userRole = jsonObject.getString("UserRole");
//Rest of the code....
}
} catch (Exception e) {
e.printStackTrace();
}
Use Below Code to get JsonRespone :
class RetrieveFeedTask extends AsyncTask<Void, Void, String> {
protected void onPreExecute() {
responseView.setText("");
}
protected String doInBackground(Void... urls) {
String API_URL = "http://beta.json-generator.com/api/json/get/4y2NmxAYf";
// Do some validation here
try {
URL url = new URL(API_URL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
return stringBuilder.toString();
}
finally{
urlConnection.disconnect();
}
}
catch(Exception e) {
Log.e("ERROR", e.getMessage(), e);
return null;
}
}
protected void onPostExecute(String response) {
if(response == null) {
response = "THERE WAS AN ERROR";
}
// progressBar.setVisibility(View.GONE);
Log.i("INFO", response);
responseView.setText(response);
parseJsonData(response);
}
}
And Parse your data using below method:
private void parseJsonData(String jsonResponse){
try
{
JSONArray jsonArray = new JSONArray(jsonResponse);
for(int i=0;i<jsonArray.length();i++)
{
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
String UserRole = jsonObject1.optString("UserRole");
String UserName = jsonObject1.optString("UserName");
String Id = jsonObject1.optString("Id");
String Email = jsonObject1.optString("Email");
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
find API calling code from below Link :
How to use a web API from your Android app
You can use OkHttp to fetch json data from server and use fastjson to parse data.
Add these dependencies to the App's build.gradle:
compile 'com.alibaba:fastjson:1.2.24'
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.squareup.okio:okio:1.11.0'
Then 1.Create a model class:
public class JsonModel {
private String UserRole;
private String UserName;
private int Id;
private String Email;
public String getUserRole() {
return UserRole;
}
public void setUserRole(String UserRole) {
this.UserRole = UserRole;
}
public String getUserName() {
return UserName;
}
public void setUserName(String UserName) {
this.UserName = UserName;
}
public int getId() {
return Id;
}
public void setId(int Id) {
this.Id = Id;
}
public String getEmail() {
return Email;
}
public void setEmail(String Email) {
this.Email = Email;
}
#Override
public String toString() {
return "JsonModel{" +
"Email='" + Email + '\'' +
", UserRole='" + UserRole + '\'' +
", UserName='" + UserName + '\'' +
", Id=" + Id +
'}';
}
2.Use OkHttp to fetch json data and use fastjson to parse the data.
class GetJson extends Thread {
private String url;
public GetJson(String url) {
this.url = url;
}
#Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
final String text = response.body().string();
List<JsonModel> models = JSON.parseArray(text, JsonModel.class);
//Do other things based on models
}
} catch (IOException e) {
e.printStackTrace();
}
}
you can take a look at http://www.androidhive.info/2012/01/android-json-parsing-tutorial/ and try to search more before you start a new topic next time !
Try this,
StringRequest stringRequest = new StringRequest(Request.Method.GET,"http://beta.json-generator.com/api/json/get/4y2NmxAYf",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray result = new JSONArray(response);
for (int i = 0; i < result.length(); i++)
{
JSONObject c = result.getJSONObject(i);
String UserRole = c.getString("UserRole");
String UserName = c.getString("UserName");
int Id = c.getInt("Id");
String Email = c.getString("Email");
}
} catch (JSONException e) {
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
gradle dependencies for your Android project's app module:
compile 'com.android.volley:volley:1.0.0'

How to form json array in android to send to server?

I have created an Api which is used to add multiple invitations in the database called as sendMultipleInvites.
Now I want to implement this API in android. I am trying to create an AsyncTask to call the api. I have helper class to connect to http server.
I am testing this in postman: my input should be like this:
{
"invitations": [
{
"date" : "12/08/2016",
"invitee_no" : "196756456",
"status" : "1",
"user_name" : "user10"
},
{
"date" : "12/08/2016",
"invitee_no" : "13633469",
"status" : "1",
"user_id" : "user9"
}
]
}
My serverRequest class:
public class ServerRequest {
String api;
JSONObject jsonParams;
public ServerRequest(String api, JSONObject jsonParams) {
this.api = api;
this.jsonParams = jsonParams;
}
public JSONObject sendRequest() {
try {
URL url = new URL(api);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
con.setDoInput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
writer.write(jsonParams.toString());
writer.close();
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = "";
while ( (line = reader.readLine()) != null ){
sb.append(line);
}
reader.close();
Log.d("ServerResponse", new String(sb));
return new JSONObject(new String(sb));
} else {
throw new UnexpectedServerException("Unexpected server exception with status code : "+responseCode);
}
} catch (MalformedURLException me) {
me.printStackTrace();
return Excpetion2JSON.getJSON(me);
} catch(IOException ioe) {
ioe.printStackTrace();
return Excpetion2JSON.getJSON(ioe);
} catch(UnexpectedServerException ue) {
ue.printStackTrace();
return Excpetion2JSON.getJSON(ue);
} catch (JSONException je) {
je.printStackTrace();
return Excpetion2JSON.getJSON(je);
}
}
public ServerRequest(String api) {
this.api = api;
}
}
This is my asyncTask :
public class SendMultipleInvitesAsyncTask extends AsyncTask<Map<String, String>, Void, JSONObject> {
private Context context;
public SendInviteAsyncTask(Context context) {
this.context = context;
this.progressDialog = new ProgressDialog(context);
}
#Override
protected JSONObject doInBackground(Map<String, String>... params) {
try {
String api = context.getResources().getString(R.string.server_url) + "contactsapi/sendInvite.php";
Map2JSON mjs = new Map2JSON();
JSONObject jsonParams = mjs.getJSON(params[0]);
ServerRequest request = new ServerRequest(api, jsonParams);
return request.sendRequest();
} catch (JSONException je) {
return Excpetion2JSON.getJSON(je);
}
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
Log.d("ServerResponse", jsonObject.toString());
try {
int result = jsonObject.getInt("status");
String message = jsonObject.getString("message");
if (result == 1) {
//Code for having successful result for register api goes here
} else {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
} catch (JSONException je) {
je.printStackTrace();
Toast.makeText(context, je.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
Edit:
Trying like this it is giving an error when I try to pass an arraylist to the execute method of async task.
AsyncTask:
public class SendInviteAsyncTask extends AsyncTask<ArrayList<Invitation>, Void, JSONObject> {
private ProgressDialog progressDialog;
private Context context;
public SendInviteAsyncTask(Context context) {
this.context = context;
this.progressDialog = new ProgressDialog(context);
}
#Override
protected JSONObject doInBackground(ArrayList<Invitation>... arrayLists) {
try {
String api = context.getResources().getString(R.string.server_url) + "contactsapi/sendInvite.php";
ServerRequest request = new ServerRequest(api, jsonParams);
return request.sendRequest();
} catch (JSONException je) {
return Excpetion2JSON.getJSON(je);
}
}
Activity:
public class SendMultipleInvites extends AppCompatActivity {
private ArrayList<Invitation> invitationArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_multiple_invites);
invitationArrayList = new ArrayList<>();
Invitation invitation = new Invitation("3","17/02/2016","55165122","1","user10");
invitationArrayList.add(invitation);
invitation = new Invitation("3","17/02/2016","282751221","1","user10");
invitationArrayList.add(invitation);
new SendMultipleInvitesAsyncTask(SendMultipleInvites.this).execute(invitationArrayList);
}
}
I was using hash map to send key and values. How can I do to send a json array?
How to modify my async Task? How can I send array to an async task? Can anyone help please.. Thank you..
To pass Array to your async Task do this:
SendInviteAsyncTask extends AsyncTask<ArrayList<Sring>, Void, JSONObject>
To make a Json object you can use Gson library
try this
JSONObject obj = new JSONObject();
JSONArray req = new JSONArray();
JSONObject reqObj = new JSONObject()
reqObj.put( "ctrlId", "txt1" );
req.put( reqObj );
reqObj = new JSONObject();
reqObj.put( "ctrlId", "txt2" );
req.put( reqObj );
obj.put( "req", req );
You can really simplify your code by using a few libraries for building json and sending http requests. Here is sample code using Gson for building the json string and Volley for the http request.
I also used this fantastic project for generating the json pojo objects below. It makes really quick work of it.
Invite ivt = new Invite();
ivt.getInvitations().add( new Invitation("3","17/02/2016","55165122","1","user10"));
ivt.getInvitations().add( new Invitation("3","17/02/2016","282751221","1","user10"));
Gson gson = new Gson();
String jsonString = gson.toJson(ivt);
String url = appContext.getResources().getString(R.string.server_url) + "contactsapi/sendInvite.php";
RequestQueue queue = Volley.newRequestQueue(appContext);
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("TAG", "success: " + response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(stringRequest);
Invite.java
public class Invite {
#SerializedName("invitations")
#Expose
private List<Invitation> invitations = new ArrayList<Invitation>();
public List<Invitation> getInvitations() {
return invitations;
}
public void setInvitations(List<Invitation> invitations) {
this.invitations = invitations;
}
}
Invitation.java
public class Invitation {
#SerializedName("date")
#Expose
private String date;
#SerializedName("invitee_no")
#Expose
private String inviteeNo;
#SerializedName("status")
#Expose
private String status;
#SerializedName("user_name")
#Expose
private String userName;
#SerializedName("user_id")
#Expose
private String userId;
public Invitation(String d, String one, String two, String three, String four) {
date = d;
inviteeNo = one;
status = two;
userName = three;
userId = four;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getInviteeNo() {
return inviteeNo;
}
public void setInviteeNo(String inviteeNo) {
this.inviteeNo = inviteeNo;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}

Android Bug: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path in android

This is my JSON
[
{
"id":1,
"media":{
"name":"ABC",
"url":"abc.org/"
},
"published":"2016-01-24T16:00:00.000Z",
"_links":{
"self":{
"href":"acb.net"
}
}
}
]
Class ApiInterface
public interface ApiServiceInterface {
#GET("/api/feed/channels/current/entries")
ApiFeedCurrentRequest getAllApiFeedCurrent();
}
Class ApiFeedCurrentRequest
public class ApiFeedCurrentRequest {
#SerializedName("id")
private int mId;
#SerializedName("media")
private Media mMedia;
#SerializedName("published")
private String mPublished;
#SerializedName("_links")
private Link mLinks;
Class ApiService
private static final String TAG = "__API__Service";
private final ApiServiceInterface mApiService;
public ApiService(Context context) {
final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(30, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.create();
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Constant.BASE_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(okHttpClient))
.setLogLevel(BuildConfig.DEBUG ? RestAdapter.LogLevel.FULL : RestAdapter.LogLevel.NONE)
.setLog(new AndroidLog(TAG))
.setConverter(new CleanGsonConverter(gson))
.setErrorHandler(new CustomErrorHandler(context))
.build();
this.mApiService = restAdapter.create(ApiServiceInterface.class);
}
public ApiFeedCurrentRequest getAllData() {
if (mApiService != null) {
return mApiService.getAllApiFeedCurrent();
} else {
return null;
}
}
Class CleanGsonConverter
public class CleanGsonConverter extends GsonConverter {
private Gson mGson;
public CleanGsonConverter(Gson gson) {
super(gson);
mGson = gson;
}
public CleanGsonConverter(Gson gson, String encoding) {
super(gson, encoding);
mGson = gson;
}
#Override
public Object fromBody(TypedInput body, Type type) throws ConversionException {
boolean willCloseStream = false; // try to close the stream, if there is no exception thrown using tolerant JsonReader
try {
String mDirty = toString(body);
if (TextUtils.isEmpty(mDirty)) return null;
String clean = mDirty.replaceAll("(^\\(|\\)$)", "");
body = new JsonTypedInput(clean.getBytes(Charset.forName("UTF-8")));
JsonReader jsonReader = new JsonReader(new InputStreamReader(body.in()));
jsonReader.setLenient(true);
Object o = mGson.fromJson(jsonReader, type);
willCloseStream = true;
return o;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (willCloseStream) {
closeStream(body);
}
}
}
private String toString(TypedInput body) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(body.in()));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
private void closeStream(TypedInput body) {
try {
InputStream in = body.in();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In Activity.
private class GetDataAsync extends AsyncTask<Void, Void, Void> {
private WeakReference<SplashActivity> mWeakReference;
private ProgressDialog mDialog;
private boolean mErrorInternet = false;
private ApiFeedCurrentRequest mApiFeedCurrent;
public GetDataAsync(SplashActivity splashActivity) {
mWeakReference = new WeakReference<SplashActivity>(splashActivity);
mDialog = new ProgressDialog(splashActivity);
mDialog.setMessage(splashActivity.getString(R.string.message_loading));
mDialog.setCancelable(false);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
SplashActivity activity = mWeakReference.get();
if (activity != null) {
if (Utils.isInternetAvailable()) {
try {
mApiFeedCurrent = activity.mApiService.getAllData();
} catch (RetrofitError error) {
DebugTool.logD("ERROR = " + error.toString());
} catch (Exception e) {
e.printStackTrace();
}
} else {
mErrorInternet = true;
}
}
return null;
}
This is my Error.
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200)
at com.google.gson.Gson.fromJson(Gson.java:810)
at com.seesaa.newsaudiocast.api.CleanGsonConverter.fromBody(CleanGsonConverter.java:60)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:367)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at $Proxy0.getAllApiFeedCurrent(Native Method)
at com.seesaa.newsaudiocast.api.ApiService.getAllData(ApiService.java:50)
at com.seesaa.newsaudiocast.activity.SplashActivity$GetDataAsync.doInBackground(SplashActivity.java:75)
at com.seesaa.newsaudiocast.activity.SplashActivity$GetDataAsync.doInBackground(SplashActivity.java:49)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
Please. Help me fix bug. Thanks all!
Class ApiInterface
public interface ApiServiceInterface {
#GET("/api/feed/channels/current/entries")
ApiFeedCurrentRequest getAllApiFeedCurrent();
}
replace with
public interface ApiServiceInterface {
#GET("/api/feed/channels/current/entries")
List<ApiFeedCurrentRequest> getAllApiFeedCurrent();
}
AND :in Activity
private List<ApiFeedCurrentRequest> mApiFeedCurrent = new ArrayList<>();
#Override
protected Void doInBackground(Void... params) {
SplashActivity activity = mWeakReference.get();
if (activity != null) {
if (Utils.isInternetAvailable()) {
try {
mApiFeedCurrent = activity.mApiService.getAllData();
} catch (RetrofitError error) {
DebugTool.logD("ERROR = " + error.toString());
} catch (Exception e) {
e.printStackTrace();
}
} else {
mErrorInternet = true;
}
}
return null;
}
Hope it will help you my friend ! :)
change this
ApiFeedCurrentRequest getAllApiFeedCurrent();
to this
ApiFeedCurrentRequest[] getAllApiFeedCurrent();
or
List<ApiFeedCurrentRequest> getAllApiFeedCurrent();

I'm getting an error on my response from Retrofit Expected BEGIN_ARRAY but was STRING at line 1 column 1 path $

I've looked at several answers, I'm missing something. Also is there a way to see the data prior to Retrofit handling it?
Here's the code
extends Activity implements Callback<List<MemberPOJO>> {
#Inject
MembersInterface memberInterfaceService;
#Override
public void onFailure(Exception ex) {
setProgressBarIndeterminateVisibility(false);
String retrofitError = "Error: " + ex.getMessage();
Log.e("LoadActivity", retrofitError);
}
#Override
public void onSuccess(List<MemberPOJO> result) {
ArrayList<String> strings = new ArrayList<String>(result.size());
Log.e("LoadActivity", "MemberPOJO:" + result);
}
...
public void getMemberHostData() {
MemberLoader loader = new MemberLoader(this, memberInterfaceService);
RetrofitLoaderManager.init(getLoaderManager(), 0, loader, this);
}
static class MemberLoader extends RetrofitLoader<List<MemberPOJO>, MembersInterface> {
public MemberLoader(Context context, MembersInterface service) {
super(context, service);
}
RestAdapter.Builder builder= new RestAdapter.Builder()
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json;versions=1");
request.addHeader("authorization",getAuthorization(getContext()));
}
});
#Override
public List<MemberPOJO> call(MembersInterface service) {
return service.listOfMemebers();
}
}
You can pull string if you have StringConverter and StringTypedOutput. This will deliver plain string and it won't deserialize anything. Of course you can try to validate if JSON is valid inside fromBody() method, if it is valid then just proceed with deserialization (extends it to GsonConverter), otherwise just get the Response
public class StringConverter implements Converter {
#Override
public Object fromBody(TypedInput arg0, Type arg1)
throws ConversionException {
return getStringFromInputStream(arg0.in());
}
#Override
public TypedOutput toBody(Object arg0) {
String string = (String) arg0;
return new StringTypedOutput(string.getBytes(Charset.forName(HTTP.UTF_8)));
}
public static String getStringFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//close the stream if needed.
}
return sb.toString();
}
}

Method to AsyncTask Android OAuth2Client

I am trying to use this code:
public static Token getAccessToken(OAuth2Config oauthDetails) {
HttpPost post = new HttpPost(oauthDetails.getTokenEndPointUrl());
String clientId = oauthDetails.getClientId();
String clientSecret = oauthDetails.getClientSecret();
String scope = oauthDetails.getScope();
List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();
parametersBody.add(new BasicNameValuePair(OAuthConstants.GRANT_TYPE,
oauthDetails.getGrantType()));
parametersBody.add(new BasicNameValuePair(OAuthConstants.USERNAME,
oauthDetails.getUsername()));
parametersBody.add(new BasicNameValuePair(OAuthConstants.PASSWORD,
oauthDetails.getPassword()));
if (isValid(clientId)) {
parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_ID,
clientId));
}
if (isValid(clientSecret)) {
parametersBody.add(new BasicNameValuePair(
OAuthConstants.CLIENT_SECRET, clientSecret));
}
if (isValid(scope)) {
parametersBody.add(new BasicNameValuePair(OAuthConstants.SCOPE,
scope));
}
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = null;
Token accessToken = null;
try {
post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));
response = client.execute(post);
int code = response.getStatusLine().getStatusCode();
if (code >= 400) {
Log.d(TAG, "Authorization server expects Basic authentication");
// Add Basic Authorization header
post.addHeader(
OAuthConstants.AUTHORIZATION,
getBasicAuthorizationHeader(oauthDetails.getUsername(),
oauthDetails.getPassword()));
Log.d(TAG, "Retry with login credentials");
try {
response.getEntity().consumeContent();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response = client.execute(post);
code = response.getStatusLine().getStatusCode();
if (code >= 400) {
Log.d(TAG, "Retry with client credentials");
post.removeHeaders(OAuthConstants.AUTHORIZATION);
post.addHeader(
OAuthConstants.AUTHORIZATION,
getBasicAuthorizationHeader(
oauthDetails.getClientId(),
oauthDetails.getClientSecret()));
try {
response.getEntity().consumeContent();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response = client.execute(post);
code = response.getStatusLine().getStatusCode();
if (code >= 400) {
throw new RuntimeException(
"Could not retrieve access token for user: "
+ oauthDetails.getUsername());
}
}
}
Map map = handleResponse(response);
accessToken = new Token(Long.valueOf((Integer) map.get(OAuthConstants.EXPIRES_IN)), (String) map.get(OAuthConstants.TOKEN_TYPE), (String) map.get(OAuthConstants.REFRESH_TOKEN), (String) map.get(OAuthConstants.ACCESS_TOKEN));
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return accessToken;
}
Is part of an OAuth2Client that i am using in my Android app.
I am getting this error:
android.os.NetworkOnMainThreadException
and i was reading that i should use AsyncTask, but i have no idea how to convert this method to a AsyncTask.
I will apreciate some help.
Thanks
First of All you need a Fragment to wrap your asynctask so if the device rotates you do not create multiple requests and leak that. And also you need listener (GetAccessTokenCallbacks) to inform your activity that you have done and returning the result.
public class GetAccessTokenFragment extends Fragment {
OAuth2Config mOauthDetails;
static interface GetAccessTokenCallbacks {
void onPostExecute(Token token);
}
private GetAccessTokenCallbacks mCallbacks;
private AccessTokenTask mTask;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallbacks = (GetAccessTokenCallbacks) activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
// you must do it as follow
// first create new instance
// mOauthDetails = new OAuth2Config(....)
// then use the values of MainActivity.this.mOauthDetails to initialize it
mTask = new AccessTokenTask();
mTask.execute();
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
private class AccessTokenTask extends AsyncTask<Void, Void, Token> {
#Override
protected Token doInBackground(Void... param) {
Token token = TheClassOfThisFunction.getAccessToken(mOauthDetails);
return token;
}
#Override
protected void onPostExecute(Token token) {
if (mCallbacks != null) {
mCallbacks.onPostExecute(token[0]);
}
}
}
}
and in your MainActivity you must implement GetAccessTokenFragment.GetAccessTokenCallbacks and creating the GetAccessTokenFragment.
public class MainActivity extends FragmentActivity implements GetAccessTokenFragment.GetAccessTokenCallbacks {
public OAuth2Config mOauthDetails;
private static final String TAG_GetAccessTokenFragment = "GetAccessToken";
private GetAccessTokenFragment mGetAccessTokenFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize mOauthDetails here
FragmentManager fm = getSupportFragmentManager();
mGetAccessTokenFragment = (GetAccessTokenFragment) fm.findFragmentByTag(TAG_GetAccessTokenFragment);
if (mGetAccessTokenFragment == null) {
mGetAccessTokenFragment = new GetAccessTokenFragment();
fm.beginTransaction().add(mGetAccessTokenFragment, TAG_GetAccessTokenFragment).commit();
}
}
#Override
public void onPostExecute(Token token) {
//you got your token here
}
}
Seems that OAuthConfig is called in the following:
public class OAuth2Client {
private final String username;
private final String password;
private final String clientId;
private final String clientSecret;
private final String site;
public OAuth2Client(String username, String password, String clientId, String clientSecret, String site) {
this.username = username;
this.password = password;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.site = site;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getClientId() {
return clientId;
}
public String getClientSecret() {
return clientSecret;
}
public String getSite() {
return site;
}
public Token getAccessToken() {
OAuth2Config oauthConfig = new OAuth2Config.OAuth2ConfigBuilder(username, password, clientId, clientSecret, site)
.grantType("password").build();
return OAuthUtils.getAccessToken(oauthConfig);
}
}

Categories

Resources