Permissions Error - Trying to get friends using android facebook sdk - java

I am trying to add a feature to my android app that allows users to "checkin" with other people tagged to the checkin.
I have the checkins method working no problem and can tag some one by adding the user ID as a parameter (see code below)
public void postLocationTagged(String msg, String tags, String placeID, Double lat, Double lon) {
Log.d("Tests", "Testing graph API location post");
String access_token = sharedPrefs.getString("access_token", "x");
try {
if (isSession()) {
String response = mFacebook.request("me");
Bundle parameters = new Bundle();
parameters.putString("access_token", access_token);
parameters.putString("place", placeID);
parameters.putString("Message",msg);
JSONObject coordinates = new JSONObject();
coordinates.put("latitude", lat);
coordinates.put("longitude", lon);
parameters.putString("coordinates",coordinates.toString());
parameters.putString("tags", tags);
response = mFacebook.request("me/checkins", parameters, "POST");
Toast display = Toast.makeText(this, "Checkin has been posted to Facebook.", Toast.LENGTH_SHORT);
display.show();
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")) {
Log.v("Error", "Blank response");
}
} else {
// no logged in, so relogin
Log.d(TAG, "sessionNOTValid, relogin");
mFacebook.authorize(this, PERMS, new LoginDialogListener());
}
} catch(Exception e) {
e.printStackTrace();
}
}
This works fine (I've posted it in case it is of help to anyone else!), the problem i am having is i am trying to create a list of the users friends so they can select the friends they want to tag. I have the method getFriends (see below) which i am then going to use to generate an AlertDialog that the user can select from which in turn will give me the id to use in the above "postLocationTagged" method.
public void getFriends(CharSequence[] charFriendsNames,CharSequence[] charFriendsID, ProgressBar progbar) {
pb = progbar;
try {
if (isSession()) {
String access_token = sharedPrefs.getString("access_token", "x");
friends = charFriendsNames;
friendsID = charFriendsID;
Log.d(TAG, "Getting Friends!");
String response = mFacebook.request("me");
Bundle parameters = new Bundle();
parameters.putString("access_token", access_token);
response = mFacebook.request("me/friends", parameters, "POST");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")) {
Log.v("Error", "Blank response");
}
} else {
// no logged in, so relogin
Log.d(TAG, "sessionNOTValid, relogin");
mFacebook.authorize(this, PERMS, new LoginDialogListener());
}
} catch(Exception e) {
e.printStackTrace();
}
}
When i look at the response in the log it reads:
"got responce: {"error":{"type":"OAuthException", "message":"(#200) Permissions error"}}"
I have looked through the graphAPI documentation and searched for similar questions but to no avail! I'm not sure if i need to request extra permissions for the app or if this is something your just not allowed to do! Any help/suggestions would be greatly appreciated.

You might need the following permissions:
user_checkins
friends_checkins
read_friendlists
manage_friendlists
publish_checkins
Check the related ones from the API docs. Before that, make sure that which line causes this permission error and try to fix it.

The solution is to implement a RequestListener when making the request to the Facebook graph API. I have the new getFriends() method (see below) which uses the AsyncGacebookRunner to request the data.
public void getFriends(CharSequence[] charFriendsNames,String[] sFriendsID, ProgressBar progbar) {
try{
//Pass arrays to store data
friends = charFriendsNames;
friendsID = sFriendsID;
pb = progbar;
Log.d(TAG, "Getting Friends!");
//Create Request with Friends Request Listener
mAsyncRunner.request("me/friends", new FriendsRequestListener());
} catch (Exception e) {
Log.d(TAG, "Exception: " + e.getMessage());
}
}
The AsyncFacebookRunner makes the the request using the custom FriendsRequestListener (see below) which implements the RequestListener class;
private class FriendsRequestListener implements RequestListener {
String friendData;
//Method runs when request is complete
public void onComplete(String response, Object state) {
Log.d(TAG, "FriendListRequestONComplete");
//Create a copy of the response so i can be read in the run() method.
friendData = response;
//Create method to run on UI thread
FBConnectActivity.this.runOnUiThread(new Runnable() {
public void run() {
try {
//Parse JSON Data
JSONObject json;
json = Util.parseJson(friendData);
//Get the JSONArry from our response JSONObject
JSONArray friendArray = json.getJSONArray("data");
//Loop through our JSONArray
int friendCount = 0;
String fId, fNm;
JSONObject friend;
for (int i = 0;i<friendArray.length();i++){
//Get a JSONObject from the JSONArray
friend = friendArray.getJSONObject(i);
//Extract the strings from the JSONObject
fId = friend.getString("id");
fNm = friend.getString("name");
//Set the values to our arrays
friendsID[friendCount] = fId;
friends[friendCount] = fNm;
friendCount ++;
Log.d("TEST", "Friend Added: " + fNm);
}
//Remove Progress Bar
pb.setVisibility(ProgressBar.GONE);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FacebookError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
Feel free to use any of this code in your own projects, or ask any questions about it.

You can private static final String[] PERMISSIONS = new String[] {"publish_stream","status_update",xxxx};xxx is premissions

Related

Connect Android to Laravel using http URL

I'm confused on how can I connect my android mobile to Laravel I've tried different ways but returns me an Java.ioFileNotFoundException:http://122.168...
I found out that the problem is the CSRF-TOKEN when I've tried disabling the CSRF-TOKEN in my laravel it works , what I tried I fetch first my CSRF-TOKEN and submit it with CSRF-TOKEN when buttons click but it didn't work either.
I used Plugin for Advanced-HttpURLConnection GITHUB LINK link
This is what I tried
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
FetchData fetchData = new FetchData("http://122.168.1.3/app/refreshtokens");
if (fetchData.startFetch()) {
if (fetchData.onComplete()) {
String fetchResult = fetchData.getResult();
try {
//getting the token from fetch data
JSONObject jsonObject = new JSONObject(fetchResult);
String csrfToken = jsonObject.getString("csrfToken");
String[] field = new String[3];
field[0] = "id_no";
field[1] = "password";
field[2] = "X-CSRF-TOKEN";
//Creating array for data
String[] data = new String[3];
data[0] = id_no;
data[1] = password;
data[2] = csrfToken;
PutData putData = new PutData("http://122.168.1.3/app/auth", "POST", field, data);
if (putData.startPut()) {
if (putData.onComplete()) {
String result = putData.getResult();
//just want to getData when success
Toast.makeText(getApplicationContext(), "Testt " + result, Toast.LENGTH_SHORT).show();
}
}
//End Write and Read data with URL
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "error catch " + e, Toast.LENGTH_SHORT).show();
}
}
}}
});

Asynctask doesnt work after too many rows retrieved

I am doing an app where I synchronize my online DB to the offline DB everytime the user logs in. The table is dropped in offline, recreated then new rows gets added ( Its neccessary to drop it and add new instead of just checking and adding the rows that are not in the table already). I had about 200 rows in my online table and they are synchronised to my offline table relatively fast (in the background, then I tried 3000 and it was still processing. But When I generated 90 000 rows and tried to synchronize it to my offline DB it wouldnt move.
The log in onPreExecute() executed, but none of the logs in my doInBackground. json is not null.
For each retrieved row I am adding a row in offline.
Anyone know what could be the issue?
I tried adding LIMIT 200 in my PHP Scripts and still didnt do it, which was weird, cause when I had 200 rows it executed, but when I limit the output to 200 it does not.
Thank you for any answers, that would bring me closer to the solution.
public class SyncVykresToOffline {
String DataParseUrl = "/scriptsforandroidapplicationofflinemode/SyncVykresToOffline.php";
JSONObject json = null;
String str = "";
HttpResponse response;
DBHelper dbh;
private Context mContext;
public static boolean syncedvykres = false;
int k = 200;
public SyncVykresToOffline(Context context) {
mContext = context;
dbh = new DBHelper(mContext);
}
public class SyncVykres extends AsyncTask<Void, Void, Void>
{
public Context context;
public SyncVykres(Context context)
{
this.context = context;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
Log.i("Poradie_zacal","ano");
}
#Override
protected Void doInBackground(Void... arg0)
{
HttpClient myClient = new DefaultHttpClient();
HttpPost myConnection = new HttpPost(DataParseUrl);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("limit", String.valueOf(k)));
try {
myConnection.setEntity(new UrlEncodedFormEntity(nameValuePairs));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
try {
HttpResponse response = myClient.execute(myConnection);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
response = myClient.execute(myConnection);
str = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int i = 0;
try{
int vykres_version;
JSONArray jArray = new JSONArray(str);
json = jArray.getJSONObject(i);
Log.i("Poradie_json",String.valueOf(jArray.length()));
String
Nazov_vykresu;
int Version,
ID_vykres,
ID_stav,
ID_zakazka,
Poradie;
if(json == null) {
Log.i("Poradie","son is null");
}
while(json != null) {
Log.i("Poradie","been here");
ID_vykres = Integer.parseInt(json.getString("ID_vykres"));
vykres_version = dbh.getVykresVersion(ID_vykres);
Nazov_vykresu = json.getString("Nazov_vykresu");
ID_stav = Integer.parseInt(json.getString("ID_stav"));
ID_zakazka = Integer.parseInt(json.getString("ID_zakazka"));
Version = Integer.parseInt(json.getString("Version"));
Poradie = Integer.parseInt(json.getString("Poradie"));
Log.i("Poradie",json.getString("Poradie"));
dbh.SyncVykresToOffline(new technicky_vykres(ID_vykres,Nazov_vykresu,ID_stav,ID_zakazka,Version,Poradie));
i++;
json = jArray.getJSONObject(i);
}
} catch ( JSONException e) {
e.printStackTrace();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void result)
{
syncedvykres = true;
}
}
}
Edit: added Logcat logs.
06-25 20:36:07.013 8278-8308/com.example.chris.normitapplication W/System.err: at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONArray.<init>(JSONArray.java:96)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.example.chris.normitapplication.offline.SyncVykresToOffline$SyncVykres.doInBackground(SyncVykresToOffline.java:102)
at com.example.chris.normitapplication.offline.SyncVykresToOffline$SyncVykres.doInBackground(SyncVykresToOffline.java:44)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
Edit 2: added PHP Script from where the JSON array is retrieved from:
<?php
include 'DatabaseConfig.php';
$conn = mysqli_connect($HostName,$HostUser,$HostPass,$DatabaseName);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
mysqli_set_charset($conn,"utf8");
$vykres = array();
$sql = "SELECT * FROM `technicky_vykres`";
$result = mysqli_query($conn, $sql) or die("Error in Selecting " . mysqli_error($conn));
while($row =mysqli_fetch_assoc($result))
{
$emparray[] = $row;
}
echo json_encode($emparray);
$conn->close();
?>
Issue identified when logging STR:
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>openresty</center>
</body>
</html>
My hunch is, its the data that is breaking the loop and causing your program to end without going through the complete data set. I just added simple try/catch (see below) to printout any data objects, that we can't parse and but still continue to process the next row. Of course you'll need to have better error handling in place for production quality code.
while(json != null) {
try{
Log.i("Poradie","been here");
ID_vykres = Integer.parseInt(json.getString("ID_vykres"));
vykres_version = dbh.getVykresVersion(ID_vykres);
Nazov_vykresu = json.getString("Nazov_vykresu");
ID_stav = Integer.parseInt(json.getString("ID_stav"));
ID_zakazka = Integer.parseInt(json.getString("ID_zakazka"));
Version = Integer.parseInt(json.getString("Version"));
Poradie = Integer.parseInt(json.getString("Poradie"));
Log.i("Poradie",json.getString("Poradie"));
dbh.SyncVykresToOffline(new technicky_vykres(ID_vykres,Nazov_vykresu,ID_stav,ID_zakazka,Version,Poradie));
i++;
json = jArray.getJSONObject(i);
}catch(Exception e){
//Something wrong with the data? log it and see if you can find the culprit row/data....
Log.i("The faulty jason obj: " + json);
continue; //Move on the next one....
}
}
The error indicates that JSONArray believes your response is not formed as a Json Array.
Here's the code within JSONArray throwing your error:
public JSONArray(JSONTokener readFrom) throws JSONException {
/*
* Getting the parser to populate this could get tricky. Instead, just
* parse to temporary JSONArray and then steal the data from that.
*/
Object object = readFrom.nextValue();
if (object instanceof JSONArray) {
values = ((JSONArray) object).values;
} else {
throw JSON.typeMismatch(object, "JSONArray");
}
}
So the tokener does not recognize the object as a JSONArray. I would take a look at your raw response and see if adding a limit doesn't change the response to be an object with a result array inside of it (so that it can also include arguments to help web calls handle paging). Either way, there's something in the format of the response that the tokener does not recognize as being a Json array.
Upon realizing that the PHP script stopped working because too many rows & columns were retrieved instead of * I only Selected data that I truly needed (about 1/3 of all columns), then I added a where clause where ID would be above the number I sent from post and I keep repeating the script until finally the response is not "null".
Thank you for everyone who contributed to finding the solution.

ArrayList, print only the value

I have a contactList = new ArrayList<>(); where I store information in this format: "name", value_for_name.
I populate my contactList inside this function:
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray contacts = jsonObj.getJSONArray("results");
// looping through All Results
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String icon = c.getString("icon");
String id = c.getString("id");
String name = c.getString("name");
// tmp hash map for single contact
HashMap<String, String> contact = new HashMap<>();
// adding each child node to HashMap key => value
// contact.put("id", id);
contact.put("name", name);
// contact.put("email", icon);
// adding contact to contact list
contactList.add(contact);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
The problem is that when I try to print a value:
System.out.println(contactList.get(position));
The output is in this format:
{name="Foo"}
I only want to print Foo
I tried also with: System.out.println(String.valueOf(contactList.get(position)));
but I always get the whole string: {name="Foo"}
Can you help me, please?
Do I really need to parse the string?
Try:
System.out.println(contactList.get(position).get("name"));
I see you have a hashmap into an array list so you want to get the object from "X" position from array and after that get the value from the hashmap by property name.

org.json.JSONException: No value for id - IMPOSSIBLE TO SOLVE

http://www.androidhive.info/2014/10/android-building-group-chat-app-using-sockets-part-2/
Hi,
This is a tutorial about building a group chat app using socket programming. This app allows us to chat between multiple devices like android mobiles and web.
I want to send more than one "String" at a time to the server. I'm having trouble figuring that out.
The link to the tutorial where I downloaded the code is pasted above. I've already made the dynamic web page and I have it hosted on eapps.com At the very bottom of the this email is the edited code for the app. If you click the link above, you can see how I changed it.
The way it works is..
A web socket is created using WebSocketClient class and it has all the callback methods like onConnect, onMessage and onDisconnect.
In onMessage method parseMessage() is called to parse the JSON received from the socket server.
In parseMessage() method, the purpose of JSON is identified by reading the flag value.
When a new message is received, the message is added to list view data source and adapter.notifyDataSetChanged() is called to update the chat list.
sendMessageToServer() method is used to send the message from android device to socket server.
playBeep() method is called to play device’s default notification sound whenever a new message is received.​
When you click the btnSend. it uses this method from the UtilsXd class. I've changed it a little in an attempt to pass an extra value.
public String getSendMessageJSONXD(String message, String whichPicIndex) {
String json = null;
try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_MESSAGE);
jObj.put("sessionId", getSessionId());
jObj.put("message", message);
jObj.put("id", id);
json = jObj.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
First of all, what I still don't understand is, where did the values for
String sessionId = jObj.getString("sessionId");
and
String onlineCount = jObj.getString("onlineCount");​
from this method
private void parseMessage(final String msg, String idINDEX) {
come from.
They were't added in the JSON object created in the UtilsXD class so how are they created?
That's not the problem I'm having. This is.
superString is the value I want to pass to dictate which picture to show.
superString = (sharedPrefs.getString("prefSyncAvatar", "1"));​
You can change your picture in from the settings.
When a message is received, a switch/case statement changes the picture of/ for the message received according to the value passed by superString.
I should be able to sit there and just receive messages, and whatever number the user passes, the profilePicture should be set according to that number.
Here's where the problem begins.
This constructer builds a message based of the message that's just been parsed.
// Message m = new Message(fromName, message, isSelf);
Message m = new Message(fromName, message, isSelf, id, name,
image, status, profilePic, timeStamp, url);
In this method.
private void parseMessage(final String msg, String idINDEX) {
I can pass an value to the string "id" excluding the JSON I need it to.
String id = idINDEX;​
this works,
String id = "0";
this works,
String id = utils.getPictureId();
this works,
String id = jObj.getString("id");
This doesn't work.
This is the error I'm getting.
org.json.JSONException: No value for id (this is the issue)
I've added the key/value pair
jObj.put("id", id);
in
public String getSendMessageJSONXD(String message, String whichPicIndex) {​
but it's not coming though to the message.
Here's where I think the problem is.
The method onMessage, isn't can't take an extra parameter because it's from a library project. And I can't find that method to make a new constructor.
#Override
public void onMessage(String message) {
Log.d(TAG, String.format("Got string message! %s", message));
parseMessage(message, superString);
}
#Override
public void onMessage(byte[] data) {
Log.d(TAG, String.format("Got binary message! %s",
bytesToHex(data)));
String hello = "99";
parseMessage(bytesToHex(data), superString);
}
/////// Here's the final code below ////////
// JSON flags to identify the kind of JSON response
private static final String TAG_SELF = "self", TAG_NEW = "new",
TAG_MESSAGE = "message", TAG_ID = "id", TAG_EXIT = "exit";
#SuppressWarnings("deprecation")
#SuppressLint({ "NewApi", "CutPasteId" })
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_chat);
showUserSettings();
getActionBar().setTitle("City Chat - Beta 1.3");
superString = (sharedPrefs.getString("prefSyncAvatar", "1"));
listView = (ListView) findViewById(R.id.list_view_messages);
feedItems = new ArrayList<FeedItem>();
// We first check for cached request
vollewStuff();
//
//
// THis is where this fun begins
btnSend = (Button) findViewById(R.id.btnSend);
inputMsg = (EditText) findViewById(R.id.inputMsg);
listViewMessages = (ListView) findViewById(R.id.list_view_messages);
utils = new UtilsXD(getApplicationContext());
// Getting the person name from previous screen
Intent i = getIntent();
name = i.getStringExtra("name");
Integer.parseInt((sharedPrefs.getString("prefSyncAvatar", "1")));
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Sending message to web socket server
sendMessageToServer(utils.getSendMessageJSONXD(inputMsg
.getText().toString(), superString), superString);
utils.storePictureId((sharedPrefs.getString("prefSyncAvatar",
"1")));
// Clearing the input filed once message was sent
inputMsg.setText("");
}
});
listMessages = new ArrayList<Message>();
adapter = new MessagesListAdapter(this, listMessages, feedItems);
listViewMessages.setAdapter(adapter);
/**
* Creating web socket client. This will have callback methods
* */
client = new WebSocketClient(URI.create(WsConfig.URL_WEBSOCKET
+ URLEncoder.encode(name)), new WebSocketClient.Listener() {
#Override
public void onConnect() {
}
/**
* On receiving the message from web socket server
* */
#Override
public void onMessage(String message) {
Log.d(TAG, String.format("Got string message! %s", message));
parseMessage(message, superString);
// parseMessage(message,
// (sharedPrefs.getString("prefSyncAvatar", "1")));
}
#Override
public void onMessage(byte[] data) {
Log.d(TAG, String.format("Got binary message! %s",
bytesToHex(data)));
String hello = "99";
parseMessage(bytesToHex(data), superString);
// Message will be in JSON format
// parseMessage(bytesToHex(data),
// (sharedPrefs.getString("prefSyncAvatar", "1")));
}
/**
* Called when the connection is terminated
* */
#Override
public void onDisconnect(int code, String reason) {
String message = String.format(Locale.US,
"Disconnected! Code: %d Reason: %s", code, reason);
showToast(message);
//
// clear the session id from shared preferences
utils.storeSessionId(null);
}
#Override
public void onError(Exception error) {
Log.e(TAG, "Error! : " + error);
// showToast("Error! : " + error);
showToast("Are you sure you want to leave?");
}
}, null);
client.connect();
}
/**
* Method to send message to web socket server
* */
private void sendMessageToServer(String message, String id) {
if (client != null && client.isConnected()) {
client.send(message);
client.send(id);
}
}
/**
* Parsing the JSON message received from server The intent of message will
* be identified by JSON node 'flag'. flag = self, message belongs to the
* person. flag = new, a new person joined the conversation. flag = message,
* a new message received from server. flag = exit, somebody left the
* conversation.
* */
private void parseMessage(final String msg, String idINDEX) {
try {
jObj = new JSONObject(msg);
// JSON node 'flag'
String flag = jObj.getString("flag");
String id = idINDEX;
// if flag is 'self', this JSON contains session id
if (flag.equalsIgnoreCase(TAG_SELF)) {
String sessionId = jObj.getString("sessionId");
// Save the session id in shared preferences
utils.storeSessionId(sessionId);
Log.e(TAG, "Your session id: " + utils.getSessionId());
} else if (flag.equalsIgnoreCase(TAG_NEW)) {
// If the flag is 'new', new person joined the room
String name = jObj.getString("name");
String message = jObj.getString("message");
// number of people online
String onlineCount = jObj.getString("onlineCount");
showToast(name + message + ". Currently " + onlineCount
+ " people online!");
} else if (flag.equalsIgnoreCase(TAG_MESSAGE)) {
// if the flag is 'message', new message received
String fromName = name;
String message = jObj.getString("message");
String sessionId = jObj.getString("sessionId");
// switch (Integer.parseInt((sharedPrefs.getString(
// "prefSyncAvatar", "1"))))
boolean isSelf = true;
switch (Integer.parseInt(utils.getPictureId())) {
case 1:
profilePic = "http://clxxxii.vm-host.net/clxxxii/citychatlion.png";
break;
case 2:
profilePic = "http://clxxxii.vm-host.net/clxxxii/citychatmatt.png";
break;
case 3:
profilePic = "http://clxxxii.vm-host.net/clxxxii/citychatroboman.png";
break;
case 4:
profilePic = "http://clxxxii.vm-host.net/clxxxii/citychatalien.png";
break;
case 5:
profilePic = "http://clxxxii.vm-host.net/clxxxii/citychatkitty.png";
break;
case 10:
profilePic = "http://clxxxii.vm-host.net/clxxxii/citychatkitty.png";
break;
}
// Checking if the message was sent by you
if (!sessionId.equals(utils.getSessionId())) {
fromName = jObj.getString("name");
// profilePic = jObj.getString("profilePic");
//
//
//
//
jObj.getString("message");
isSelf = false;
profilePic = "http://clxxxii.vm-host.net/clxxxii/citychatalien.png";
}
// profilePic =
// "http://clxxxii.vm-host.net/clxxxii/citychatlion.png";
Integer.parseInt(utils.getPictureId());
String name = "clxxxii";
String image = "http://i.huffpost.com/gen/1716876/thumbs/o-ATLANTA-TRAFFIC-facebook.jpg";
String status = "status";
String timeStamp = "1403375851930";
String url = "url";
// Message m = new Message(fromName, message, isSelf);
Message m = new Message(fromName, message, isSelf, id, name,
image, status, profilePic, timeStamp, url);
// Appending the message to chat list
appendMessage(m);
} else if (flag.equalsIgnoreCase(TAG_EXIT)) {
// If the flag is 'exit', somebody left the conversation
String name = jObj.getString("name");
String message = jObj.getString("message");
showToast(name + message);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
///////// I've updated the socket server from the first project. /////// I've added the JSON value "id" successfully /// But I how do I change the value without having to type in "5" please see below..
//
This is the JSONutilty method I changed.
//
public String getSendAllMessageJson(String sessionId, String fromName,
String message, String photoId) {
String json = null;
try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_MESSAGE);
jObj.put("sessionId", sessionId);
jObj.put("name", fromName);
jObj.put("message", message);
jObj.put("id", photoId);
json = jObj.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
}
This is the method that is being used by SocketServer. I can successfully send a message from this activity, to the utility method to send over the network.
// Normal chat conversation message
json = jsonUtils //
.getSendAllMessageJson(sessionId, name, message, "5");
How can I retrieve a value sent over the network to place in spot where I have "5" instead of hard coding it?
Thanks!!!
jobj doesn't have the value id. Example of the JSON object looks like this:
{
"message": " joined conversation!",
"flag": "new",
"sessionId": "4",
"name": "Ravi Tamada",
"onlineCount": 6
}
(as shown in the part1 of the same tutorial).
That solves the first issue of onlineCount and sessionId.
Thanks #miselking, you where correct, The server was missing the JSON string "id". To actually solve the problem of post.
"I want to send more than one "String" at a time to the server. I'm having trouble figuring that out."
This is how you do it.
Step 1)
Adding the string photoId to the method
public String getSendAllMessageJson(String sessionId, String fromName,
String message, String photoId) {
String json = null;
try {
JSONObject jObj = new JSONObject();
jObj.put("flag", FLAG_MESSAGE);
jObj.put("sessionId", sessionId);
jObj.put("name", fromName);
jObj.put("message", message);
jObj.put("id", photoId);
json = jObj.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
}
Step 2)
Add the string to the correct sting to the method.
String json = null;
json = jsonUtils
.getSendAllMessageJson(sessionId, name, message,
photoId);
Step 3) Parse the JSON
try {
JSONObject jObj = new JSONObject(message);
msg = jObj.getString("message");
photoId = jObj.getString("id");
} catch (JSONException e) {
e.printStackTrace();
}

Volley Request Manager

I'm using Volley however I'm having some problems with the JSON parsed data most likely because volley doesn't implement something like AsyncTask's onPostExecute() and I'm getting some duplicated data on wrong list items.
Then I came across this: https://github.com/yakivmospan/volley-request-manager#custom-listener-implementation-
Has anyone use it? How can I add it to my current Volley code?
More details about my problem here Volley not sending correct data. How to implement an alternative to onPostExecute()?
UPDATE
As requested, some code. Here's a button that calls a method on another class that uses Volley to request some raw JSON data (NovaJSON) and then send the JSON to a parser class (NovaParser):
info.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String instanceDetail = NovaJSON.shared().receiveDetail(getId());
Dialog dialog = new Dialog(v.getContext());
dialog.setContentView(R.layout.instances_info);
TextView image = (TextView) dialog.findViewById(R.id.imageInstance);
TextView flavor = (TextView) dialog.findViewById(R.id.flavorInstance);
dialog.setTitle(name.getText() + " Details");
if (instanceDetail != null) {
image.setText(" \u2022 image : " + NovaParser.shared().parseImages(instanceDetail));
flavor.setText(" \u2022 flavor : " + NovaParser.shared().parseFlavor(instanceDetail));
}
dialog.show();
}
});
This is the method that does the Volley request on the NovaJSON class:
public void getJSONdetail() {
final String authToken = getAuth();
String novaURL = getNova();
novaURL = novaURL+"/servers/"+id;
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, novaURL, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("Nova on Response", response.toString());
setNovaJSONdetail(response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Nova on Error", "Error: " + error.getMessage());
setNovaJSONdetail(error.toString());
}
}
) {
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("X-Auth-Token", authToken);
params.put("User-Agent", "stackerz");
params.put("Accept", "application/json");
params.put("Content-Type", "application/json; charset=utf-8");
return params;
}
};
queue = VolleySingleton.getInstance(this).getRequestQueue();
queue.add(getRequest);
}
It then sends the JSON from the server as a string to be parsed using the following methods:
public static String parseImages(String imagesDetail){
ArrayList<HashMap<String, String>> imagesList = NovaParser.shared().getImagesList();
String temp = null;
JSONObject novaDetail = null;
try {
novaDetail = new JSONObject(imagesDetail);
JSONObject server = novaDetail.getJSONObject("server");
JSONObject image = server.getJSONObject("image");
if (imagesList !=null){
temp = image.getString("id");
for (Map<String,String> map : imagesList) {
if (map.containsValue(temp)) {
temp = map.get(NAME);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return temp;
}
public static String parseFlavor(String instanceDetail){
ArrayList<HashMap<String, String>> flavorList = NovaParser.shared().getFlavorList();
String temp = null;
JSONObject novaDetail = null;
try {
novaDetail = new JSONObject(instanceDetail);
JSONObject server = novaDetail.getJSONObject("server");
JSONObject flavor = server.getJSONObject("flavor");
if (flavorList !=null){
temp = flavor.getString("id");
for (Map<String,String> map : flavorList) {
if (map.containsValue(temp)) {
temp = map.get(NAME);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return temp;
}
When I press the button once the dialog is displayed with empty values. When I press it the second time I get the correct parsed data. Basically first time I click the button the instanceDetail string is null because Volley didn't finish doing its thing then I click the 2nd time it loads the values accordingly because it finally finished the 1st request.
I understand Volley is asynchronous, the requests happen in parallel and the responses sometimes are not immediate however I need some sort of progress bar or spinning wheel to give the user some feedback that the app is waiting for data. It could be done with AsyncTask however it doesn't seem to be possible with Volley.
I think your problem is not because of Volley.
Check the parameters you send and receive.
However if you need onPostExcecute you have Volley's callback:
Response.Listener<JSONObject> and Response.ErrorListener() which are called after the request.
About Volley request manager just switch all your volley calls with appropriate Volley request manager calls
I solved my problem by dumping Volley altogether and moving to Retrofit. I setup all the calls to be sync/blocking, worked out the exceptions/errors using try/catches and setup a short timeout on the OkHTTP client. Now it's working as I wanted.

Categories

Resources