I am getting a response from server in json format and it have more then 5000 lines.
My problem is that I am not able to see complete json value in logcat and I already increase buffer size from eclipse logcat. I can not use this url in PC's web browser to check the json value because it's using some tokens to identify device. I have only one solution that I have to write a file with this json value and than extract it to my PC.
Anyone know some good solutions please help me.
You can split your lengthy response and print it like this:
int maxLogSize = 1000;
for(int i = 0; i <= veryLongString.length() / maxLogSize; i++) {
int start = i * maxLogSize;
int end = (i+1) * maxLogSize;
end = end > veryLongString.length() ? veryLongString.length() : end;
Log.v(TAG, veryLongString.substring(start, end));
}
Related
This problem freak me out
I have an application and now i want to transer data between client android application and localhost tomcat 7 server, i did that many times ago, now when i want to send data from client to server it works well and i can see the data on the server, but something happend and the android application is trying to trigger an activity from another project i deleted that project then still try to trigger activty form another project
my actiivty name is "Signup", and the android client trying to trigger activiteis with the same name from another projects.
as in log :
NumberFormatException: unable to parse
'[Lorg.apache.http.Header;#44ee4c10' as integer
means you are trying to parse wrong string to Integer . wrap casting code inside try/catch block to avoid NumberFormatException as :
String str_NumberOfCities="";
Header[] headers = response.getAllHeaders();
for (int i=0; i < headers.length; i++) {
Header h = headers[i];
Log.i(TAG, "Header names: "+h.getName());
if(h.getName().toLowerCase().contains("NumberOfCities".toLowerCase()){
str_NumberOfCities=h.getValue();
}
Log.i(TAG, "Header Value: "+h.getValue());
}
int numberOfCities=0;
try {
numberOfCities = Integer.parseInt(str_NumberOfCities);
} catch (NumberFormatException e) {
numberOfCities=0;
}
Data.cities = new String[numberOfCities];
///....your code
We usually get data from server response in android development.
/*
* get server response inputStream
*/
InputStream responseInputStream;
Solution1: get response string by multiple read.
/*
* get server response string
*/
StringBuffer responseString = new StringBuffer();
responseInputStream = new InputStreamReader(conn.getInputStream(),"UTF-8");
char[] charBuffer = new char[bufferSize];
int _postion = 0;
while ((_postion=responseInputStream.read(charBuffer)) > -1) {
responseString.append(charBuffer,0,_postion);
}
responseInputStream.close();
Solution2: get response only one read.
String responseString = null;
int content_length=1024;
// we can get content length from response header, here assign 1024 for simple.
responseInputStream = new InputStreamReader(conn.getInputStream(),"UTF-8");
char[] charBuffer = new char[content_length];
int _postion = 0;
int position = responseInputStream.read(charBuffer)
if(position>-1){
responseString = new String(charBuffer,0,position );
}
responseInputStream.close();
Which solution has better performance? why?
Notes: server response json format data that less than 1M bytes.
Why you're reinventing a wheel? ;)
If you're using HttpClient then just use EntityUtils.toString(...).
I guess you're using HttpURLConnection. Then look at EntityUtils.toString(...) from Apache HttpClient - source code. Your first approach is similar to it.
BTW, the second code is worse because:
new String(charBuffer,0,position ) runs garbage collector
In both and even in EntityUtils:
int content_length = 1024; in most cases 8192 is default for socket buffer, so your code might run while loop 8 times more often than it could.
I would recommend the second method IF you do not want to display the amount of data downloaded/transferred . As the object is read as a whole and since the size of your JSON string is comparable to 1M, it will take some time to download. At that time you can, atmost, put up a text for the user saying downloading... You cannot notify the user the amount downloaded.
But if you want to display the amount of data downloaded, use the first method that you gave. Where the you read the data from the server in parts. You can update the UI, with the amount downloaded. For eg 25 % downloaded...
char[] charBuffer = new char[bufferSize];
int _postion = 0;
int i=0;
while ((_postion=responseInputStream.read(charBuffer)) > -1) {
//((i*buffer_size)/content_length) * 100 % completed..
i++;
}
So, I would say the seconds method is better.
BTW Did you consider this?
ObjectInputStream in = new InputStreamReader(conn.getInputStream(),"UTF-8");
if(resposeCode==200)
{
String from_server=(String) in.readObject();
}
Reading the input String as an object. Any object whoe class implements serializable can be passed using ObjectOutputStream and received using ObjectInputStream()
I Think First one is good
Because, in First that will reading your response in char to char method .
Where , Second that will try to read whole response object or as key Filed of Object.
So ,As i think and as per my knowledge First is Better to camper with second.If anyone want to edit then it will truly appreciated.
I had a PHP API which showed a JSON Array, which I then read into an Android Application.
I since moved servers and the android application broke.
I assumed it was the Authentication and thought I would re-build the Android application (Was my first application and thought a re-write could make things better)
For some reason I am now getting this exception error
I read somewhere that I need to parse JSON_FORCE_OBJECT in the PHP json_encode
json_encode($arrMyData, JSON_FORCE_OBJECT);
But I am running PHP 5.2 (Options parameter came out in PHP 5.3)
My code for you to rip into
private void displayAllStories(){
String line;
int intNumStories = 0;
JSONObject arrAllStories;
LinearLayout storiesLayout = (LinearLayout) findViewById(R.id.lyoutStoriesMain);
storiesLayout.removeAllViewsInLayout();
try {
while((line = this.jsonResult.readLine()) != null){
JSONObject arrStories;
arrStories = new JSONObject(line.trim());
intNumStories = Integer.parseInt(arrStories.optString("NumStories"));
arrAllStories = arrStories.getJSONObject("StoryData");
this.strDebug += "We have "+intNumStories+"\n";
}
} catch (IOException e) {
this.strDebug += "Error (3) "+e.getLocalizedMessage()+"\n";
} catch (JSONException e) {
this.strDebug += "Error (4) "+e.getLocalizedMessage()+"\n";
}
}
And the encoded data from the website
{
"NumStories":1,
"StoryData":{
"Story0":{
"ID":"1020",
"OWERNAME":"Alicia",
"STORYMAIN":"Good evening my son was born with bilateral club feet. When he was a week old we started serial casting once a week for 3 months and then he was placed in braces for the next 6 months for a 23 hour period and then for the next 3 months just durning the night. This last visit the doctor said that he needs to have his tendons lengthened and he will go back into cast. After reading all of these articles I am a little scared on what will be best for him. It sounds like the risk of having the surgery are just as heavily weighed as just keeping him in AFO\\'s till he can make his own decision. I would like all advice whether it be positive or negative. Thank you in advance for your help.",
"STORYBRIEF":"Need reassurance that tendon lengthening is the best decision.",
"ADDEDDATE":"2011-12-12 00:51:16",
"CURRENTSTATUS":"n"
}
}
}
Sorry I should add, the code before this which procudes jsonResult is as follows
try{
URL url = null;
URLConnection urlConn = null;
InputStreamReader jsonIsr = null;
BufferedReader jsonBr = null;
//this.strDebug += "URL is "+this.strURL+"\n";
url = new URL(this.strURL);
urlConn = url.openConnection();
jsonIsr = new InputStreamReader(urlConn.getInputStream());
jsonBr = new BufferedReader(jsonIsr, 8192);
this.jsonResult = jsonBr;
return true;
}catch(MalformedURLException e){
this.strDebug += "JSON Error (1) "+e.getLocalizedMessage()+"\n";
}catch(IOException e){
this.strDebug += "JSON Error (2) "+e.getLocalizedMessage()+"\n";
}
}else{
strDebug = "NO URL Passed to JSON\n";
}
// EDIT 2
For those who asking
The error is as the title says
Error (4) A JSONObject text must being with '{' at character 1 of {"NumStories":1, "StoryData":........
Your code assumes that whole JSON data comes on one line: it iterates with readLine() but creates a new JSON object every time.
You are reading the data line by line and trying to convert each line into a JSON object. That won't work because a single line just contains a fragment of a complete JSON object.
I don't know what type jsonResult has. But you'll probably want to read the whole thing at once.
Your old web application probably produced JSON data without line break so a single line would contain a full JSON object.
i think you read the json file line by line and pass to the json object you should like this way the whole string you have to pass to the json object for parsing than only you getting the json
JSONObject arrStories = new JSONObject(jsonResult);
now get the object like this way
intNumStories = Integer.parseInt(arrStories.getString("NumStories"));
This code is going to break, if object takes more than one line (apparemtly it does). Your choices are:
Collect all the strings into string builder, the parse from this string ( http://developer.android.com/reference/org/json/JSONTokener.html )
Take GSON or my databinding layer ( https://github.com/ko5tik/jsonserializer ) and just parse stream into object.
i'm making a soft to play online video, and i'm trying to add a traffic statistic feature tot the soft. I try to use TrafficStats and getUidRxBytes function. however, it doesnt count the videoview's net traffic.
Like the following code ,i can see the rx(return by getTotalRxBytes) increase a lot, but the myapprx(return by getUidRxBytes) doesnt change.
int uid = VideoViewPlayer.this.getApplicationInfo().uid;
long rx = TrafficStats.getTotalRxBytes();
long tx = TrafficStats.getTotalTxBytes();
long myapprx = TrafficStats.getUidRxBytes(uid);
long myapptx = TrafficStats.getUidTxBytes(uid);
String info = "uid:"+uid+" rx:"+rx+" tx:"+tx+" myrx:"+myapprx+" mytx:"+myapptx;
UPDATE
Thanks first, your comment gives me important clue. And I'm trying to find the uid responsable for steaming media. I use the following code.However i cannt find the process that comsume the traffic.
List<ActivityManager.RunningAppProcessInfo> appProcessList = am.getRunningAppProcesses();
ActivityManager.RunningAppProcessInfo info=null;
//List<ActivityManager.RunningServiceInfo> appProcessList = am.getRunningServices(100);
//ActivityManager.RunningServiceInfo info = null;
strinfo = "";
long max =0;
for(int i=0;i<appProcessList.size();++i)
{
info = appProcessList.get(i);
String key = info.processName+"_" +info.uid;
if(mNetTraffic.containsKey(key))
{
long myrx = TrafficStats.getUidRxBytes(info.uid);
long lastrx = mNetTraffic.get(key).longValue();
mNetTraffic.put(key, new Long(myrx));
if(myrx-lastrx>max && myrx - lastrx>0)
{
max = myrx-lastrx;
strinfo = key +":"+max;
}
}else
{
long myrx = TrafficStats.getUidRxBytes(info.uid);
mNetTraffic.put(key, new Long(myrx));
}
}
//trying to watch the key and max and find process and uid, sadly cant find it
Streaming media should be reported for a different UID, as it is actually streamed and played by an Android internal process and module (OpenCORE or StageFright, depending on Android version).
I had the same issue and managed to find out what UID the process has that streams media: the UID is 1013
http://forum.xda-developers.com/showthread.php?t=442557
http://android-dls.com/wiki/index.php?title=Android_UIDs_and_GIDs
Hope it helps :)
I've been asking questions regarding my Android project that continually plots Bluetooth data in real-time.
Basically what I've already done is create a first version of my app by cobbling together some open source code Blueterm and OrientationSensorExample
It's been suggested that I add a thread, a handler, a Service, or use Async Task, or AIDL, etc. But I don't know how to use any of these and would appreciate an explanation.
Here's a description of the Blueterm open source code I started with (see link above). Blueterm is basically a terminal emulator program that communicates over Bluetooth. It consists of several activities with Blueterm being the most important. It discovers, pairs, and connects with a remote Bluetooth device that supports SPP/RfComm. When connected I can use Blueterm to configure the remote device by sending it commands to turn on sampling, change the number of channels to sample (to one channel), change to format of the incoming data (I like comma separated data), etc
Here's a description of the OrientationSensorExample open source code I started with (see link above). It's basically an example application of the AnroidPlot library. The OrientationSensor activity implements SensorEventListener. This includes overriding onSenorChanged() which is called whenever new orientation sensor data is taken, and it redraws the graph.
Having cobbled together these two open source projects (Blueterm and OrientationSensorExample) into one application (Blueterm) here's a description of how the overall application (Blueterm) works. When I start Blueterm the whole screen emulates a nice blue terminal. From the Options Menu I discover, pair with, connect to, and configure a remote bluetooth device as described above. Once I have configured the remote device, I go again to the Options Menu and select "Plot data" which launches the Plot activity. The terminal emulator goes away, and a nice scrolling real-time plot from the Plot activity shows up.
As far as I can tell there is a background thread that calls an update() method as follows:
/**
* Look for new input from the ptty, send it to the terminal emulator.
*/
private void update() {
int bytesAvailable = mByteQueue.getBytesAvailable();
int bytesToRead = Math.min(bytesAvailable, mReceiveBuffer.length);
try {
int bytesRead = mByteQueue.read(mReceiveBuffer, 0, bytesToRead);
append(mReceiveBuffer, 0, bytesRead);
//VTR use existing handler that calls update() to get data into plotting activity
Plot.plotData(mReceiveBuffer, 0, bytesRead);
} catch (InterruptedException e) {
//VTR OMG their swallowing this exception
}
}
In the update() method I found it convenient to call my Plot.plotData() method and pass it the same date that is passed to the append() method to plot the data. NOTE: This only works if plotData() is a static method. No one has been able to explain why.
Anyway plotData() is a static method and here's how it and it's helper methods look now:
private static StringBuffer strData = new StringBuffer("");
public static void plotData(byte[] buffer, int base, int length) {
Log.i("Entering: ", "plotData()");
/*
byte[] buffer = (byte[]) msg.obj;
int base = msg.arg1;
int length = msg.arg2;
*/
for (int i = 0; i < length; i++) {
byte b = buffer[base + i];
try {
if (true) {
char printableB = (char) b;
if (b < 32 || b > 126) {
printableB = ' ';
}
Log.w("Log_plotData", "'" + Character.toString(printableB)
+ "' (" + Integer.toString(b) + ")");
strData.append(Character.toString(printableB));
if (b == 10)
{
Log.i("End of line: ", "processBlueData()");
Log.i("strData", strData.toString());
splitData(strData);
strData = new StringBuffer("");
}
}
} catch (Exception e) {
Log.e("Log_plotData_exception", "Exception while processing character "
+ Integer.toString(i) + " code "
+ Integer.toString(b), e);
}
}
Log.i("Leaving: ", "plotData()");
}
private static void splitData(StringBuffer strBuf) {
String strDash = strBuf.toString().trim();
String[] strDashSplit = strDash.split("-");
for (int ndx = 0; ndx < strDashSplit.length; ndx++)
{
if (strDashSplit[ndx].length() > 0)
Log.i("strDashSplit", ndx + ":" + strDashSplit[ndx]);
String strComma = strDashSplit[ndx].trim();
String[] strCommaSplit = strComma.split(",");
for (int mdx = 0; mdx < strCommaSplit.length; mdx++)
{
if (strCommaSplit[mdx].length() > 0)
Log.i("strCommaSplit", mdx + ":" + strCommaSplit[mdx]);
if (mdx == 1)
{
int raw = Integer.parseInt(strCommaSplit[1],16);
Log.i("raw", Integer.toString(raw));
float rawFloat = raw;
Log.i("rawFloat", Float.toString(rawFloat));
float ratio = (float) (rawFloat/65535.0);
Log.i("ratio", Float.toString(ratio));
float voltage = (float) (5.0*ratio);
Log.i("voltage", Float.toString(voltage));
nowPlotData(voltage);
}
}
}
}
public static void nowPlotData(float data) {
// get rid the oldest sample in history:
if (plotHistory.size() > HISTORY_SIZE) {
plotHistory.removeFirst();
}
// add the latest history sample:
plotHistory.addLast(data);
// update the plot with the updated history Lists:
plotHistorySeries.setModel(plotHistory, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY);
//VTR null pointer exception?
if (plotHistoryPlot == null)
Log.i("aprHistoryPlot", "null pointer exception");
// redraw the Plots:
plotHistoryPlot.redraw();
}
If it is strongly recommended that plotData() not be a static method and that I should do something else please explain here and how. Thanks!
This might be a question much better suited for Code Review, rather than here. Perhaps you can reformulate to post it there, or trim it a lot to repost it here.
Furthermore, to answer: "It's been suggested that I add a thread, a handler, a Service, or use Async Task, or AIDL, etc. But I don't know how to use any of these and would appreciate an explanation.", the best advise would be to link you to a book about android, such as: http://commonsware.com/Android/ . Chapters 35 and 36 deal with services, while chapter 20 is about threads. You will never get an answer as complete as those chapters here.