Android- Not getting full response from HttpResponse - android

I am trying to get an HttpResponse in xml but Im not getting the whole response, what is courious is that if I loop the request the response ends in different parts but is never full.
I use the same code to request things from different Urls but I only get problems with one.
Here is the code of the AsyncTask:
public class NetworkTask extends AsyncTask<String, Void, HttpResponse> {
private AsyncTaskListener listener;
#Override
protected HttpResponse doInBackground(String... params) {
String link = params[0];
HttpGet request = new HttpGet(link);
AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
try {
HttpResponse httpResponse = client.execute(request).;
return httpResponse;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
client.close();
}
}
#Override
protected void onPostExecute(HttpResponse result) {
if (result != null){
try {
String sRes = EntityUtils.toString(result.getEntity());
listener.onNTCompleted(sRes);
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public NetworkTask(AsyncTaskListener listener){
this.listener=listener;
}
}

I am not sure if this helps you but you have a problem because EntityUtils.toString() reads data from the network stream, which should not be done on UI thread (onPostExecute). Try moving EntityUtils.toString() to doInBackground() first. This may not help solve your problem, but it is the right thing to do.

Related

Android NetworkOnMainThreadException inside Asyntask class

This code shows the exception when it reach the get sentence (line commented on the code).
The code is the next, consist on get a comments list from Http get Request:
public class ObtencionComentariosPerfil extends AsyncTask<String, Integer, List<Comment>>{
#Override
protected List<Comment> doInBackground(String... params) {
// TODO Auto-generated method stub
HttpClient httpClient = new DefaultHttpClient();
URI url;
List<Comment> listaComentarios = new ArrayList<Comment>();
try {
url = new URI(params[1]);
HttpGet del = new HttpGet(url);
del.setHeader("content-type", "application/json");
del.setHeader("X-Auth-Token", params[0]);
System.out.println("El token params es: "+params[0]);
HttpResponse resp = httpClient.execute(del);// THE EXCEPTION shows here
StatusLine estatus = resp.getStatusLine();
if (estatus.getStatusCode() == 200) {
InputStream is = resp.getEntity().getContent();
CommentsParser parser= new CommentsParser();
listaComentarios = parser.parseoComentarios(is.toString());
} else {
System.out.println("Error");
listaComentarios = null;
}
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return listaComentarios;
}
#Override
protected void onPostExecute(List<Comment> lista){
}
}
Here is called from main code:
public List<Comment> obtieneComentariosPerfil(long idUsuario, String aut){
List<Comment> listaComentarios = new ArrayList<Comment>();
String url= "http://"+ip+":8080/api/users/"+idUsuario+"/comments";
String[] params= new String[2];
params[0]=aut;
params[1]=url;
ObtencionComentariosPerfil du = new ObtencionComentariosPerfil();
listaComentarios = du.doInBackground(params);
return listaComentarios;
}
I think it have to be a stupid failure but i cant find the error. Thanks.
Because you call du.doInBackground(params);
you should call du.excute(params) instead
listaComentarios = du.doInBackground(params);
You submit async tasks for execution in a background thread by calling execute(), not by directly calling the doInBackground() callback in the current thread.
Communicate the result back to UI thread in onPostExecute().

Trying to use AsyncTask to update server periodically

I have a method that need to update its status periodically to the server.
I am using AsyncTask to run the HTTP call in background.
PROBLEM: In onPostExecute method upon checking AsyncTask.getStatus, It show the previous task still running which is causing the error.
ERROR: java.lang.IllegalStateException: Cannot execute task: the task is already running.
DIFFERENT STRATEGIES USED TO SOLVE THE PROBLEM BUT NONE IS WORKING
1. Before Relaunching AsyncTask, checked the status, it is showing the thread is RUNNING.
2. Called the AsyncTask.cancel(true), immediately before calling the AsyncTask.execute if it is still running. It turns out AsyncTask still RUNNING and taking more than 3 mins to get cancel.
NOTE: I have checked many similar questions here, but haven't found helpful.
I would really appredicae if any one of you guys give me an example to solve this issue, Thanks a Million in advance......
public class MainActivity extends Activity implements AsyncResponse{
ConnectServer asyncTask =new ConnectServer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
asyncTask.delegate = this;
setContentView(R.layout.activity_main);
//Start updating server using below method
loop();
}
public void processFinish(String output){
//this you will received result fired from async class of onPostExecute(result) method.
//Log.v(TAG, output);
if(output != null){
//not using this at this point
}
}
//Method that will call Async method to reach server
public void loop(){
TextView b = (TextView) findViewById(R.id.mField);
String str;
try {
str = asyncTask.execute(true).get();
b.setText(str);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// START SERVER CONNECTION
class ConnectServer extends AsyncTask<Boolean, String, String> {
public AsyncResponse delegate=null;
public int i = 0;
private Activity activity;
public void MyAsyncTask(Activity activity) {
this.activity = activity;
}
#Override
protected String doInBackground(Boolean... params) {
String result = null;
StringBuilder sb = new StringBuilder();
try {
// http post
HttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http://192.168.0.21:8080");
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() != 200) {
Log.d("GPSApp", "Server encountered an error");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF8"));
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
return result;
}
#Override
protected void onPostExecute(String result) {
TextView mField = (TextView) findViewById(R.id.mField);
mField.setText(result+i);
try {
Thread.sleep(10000);
//asyncTask =new ConnectServer();
i++;
String str = asyncTask.execute(true).get();
mField.setText(str+i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void onPreExecute() {}
}
}
Call getStatus() to get the status of AsyncTask. If the status is AsyncTask.Status.RUNNING, cancel it.

Android stream m3u radio fails on mobile data (g3/mobile data)

Not very easy to explain:
I have this app for streaming online radio. The problem was first with m3u format (which android somehow cannot normally stream like pls), so I have to parse the url with this ParserM3UToURL (that I found somewhere)... like this:
Uri u = Uri.parse(ParserM3UToURL.parse(STREAM_URL, sdkVersion, c));
player = MediaPlayer.create(c, u);
Mostly it works ok but it has one bug...
I'm testing this on two devices one old 2.2.2. (api level 17), other 4.3 (api level 23). Older device works fine. It can stream radio over wifi or mobile data, but the newer device has some problem with streaming over mobile data (on wifi it works ok). The application crashes because the parse function returns null: http://pastebin.com/ghbAqGzM
And I assume there are many more phones with 4.x than 2.x android. Which of course is very painful for me. Somehow I have to fix this.. So I really hope somebody will have some clue about this. I hope my explanation was not to confusing...
This is the ParserM3UToURL.parse() function:
public static String parse(String paramString, int sdkVersion, Context c)
{
try
{
StrictModeWrapper.init(c);
HttpURLConnection localHttpURLConnection = (HttpURLConnection)new URL(paramString).openConnection();
InputStream localInputStream = localHttpURLConnection.getInputStream();
BufferedReader localBufferedReader = new BufferedReader(new InputStreamReader(localInputStream));
StringBuffer localStringBuffer = new StringBuffer();
while (true)
{
String str = localBufferedReader.readLine();
if (str == null)
{
localHttpURLConnection.disconnect();
localBufferedReader.close();
localInputStream.close();
break;
}
if (str.contains("http"))
{
localHttpURLConnection.disconnect();
localBufferedReader.close();
localInputStream.close();
return str;
}
localStringBuffer.append(str);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
Below is what i worked on to stream radio (m3Urls). The example below uses a service. When the service is started, the url is parsed. Note that in the onPostExecute, parsed file is prepared. Once the file is prepared(completed buffering), the file is played/started and stopped upon completion.
public class BackgroundRadioService extends Service implements
OnCompletionListener, OnPreparedListener{
MediaPlayer mediaPlayer;
#Override
public void onCreate() {
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
parseM3uUrlAndPrepare("http://listen.radionomy.com/andalousse.m3u");
return START_STICKY;
}
private void parseM3uUrlAndPrepare(final String url){
AsyncTask<String, Integer, String> asyn = new AsyncTask<String, Integer, String>(){
HttpClient httpClient;
HttpGet getRequest;
HttpResponse httpResponse = null;
String filePath = "";
#Override
protected void onPreExecute() {
super.onPreExecute();
httpClient = new DefaultHttpClient();
getRequest = new HttpGet(url);
}
#Override
protected String doInBackground(String... params) {
try {
httpResponse = httpClient.execute(getRequest);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(httpResponse != null)
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
// ERROR MESSAGE
} else {
InputStream inputStream = null;
try {
inputStream = httpResponse.getEntity().getContent();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
try {
while ((line = bufferedReader.readLine()) != null) {
//Log.v("PLAYLISTLINE", "ORIG: " + line);
if (line.startsWith("#")) { // Metadata
} else if (line.length() > 0) {
filePath = "";
if (line.startsWith("http://")) { // Assume it's a full URL
filePath = line;
} else { // Assume it's relative
try{
filePath = getRequest.getURI().resolve(line).toString();
}catch(IllegalArgumentException e){
}catch(Exception e){
}
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return filePath;
}
#Override
protected void onPostExecute(String filePath) {
try {
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepareAsync(); //this will prepare file a.k.a buffering
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
asyn.execute("");
}
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mediaPlayer.start();
}
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.stop();
}
}//end of Service class declaration
Note: This ignores playlists hence assumes the m3u parsed will return only one file. Let me know if you would like to handle playlists so I modify my answer :)
I solved it thanks to this question's comments: POST request failing when in 3G
The problem was actually with proxies on 3G. So if proxies are disabled, no weird http requests.
I modified my code a little. Thanks to Nana's answer I no longer need a m3u parser. I also no longer use HttpClient but HttpURLConnection instead. So when calling URL.openConnection() I add the Proxy.NO_PROXY parameter to that function and bam!
So the solution is "use HttpURLConnection not HttpClient and add NO_PROXY parameter":
conn = (HttpURLConnection) the_url.openConnection( Proxy.NO_PROXY );

Retrieving a returned string from AsyncTask in Android

I want to retrieve the contents of this file and save that to a string.
I've tried using AsyncTask (based on this answer) and here is my class.
class RetreiveURLTask extends AsyncTask<Void, Void, String> {
private Exception exception = null;
public String ResultString = null;
protected String doInBackground(Void ... something) {
URL url;
try {
url = new URL("http://stream.lobant.net/ccfm.info");
HttpURLConnection urlConnection;
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
String stream_url = IOUtils.toString(in, "UTF-8");
urlConnection.disconnect();
return stream_url;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (Exception e) {
this.exception = e;
return null;
}
}
protected void onPostExecute(String stream_url) {
// TODO: check this.exception
// TODO: do something with the feed
if (this.exception != null)
this.exception.printStackTrace();
this.ResultString = stream_url;
}
}
I've tried using my AsyncTask class like this:
AsyncTask<Void, Void, String> stream_task = new RetreiveURLTask().execute();
String stream_url = stream_task.ResultString;
but ResultString isn't recognised.
I'm confused about how this all works. Since the AsyncTask runs in the background, even if I could assign my string to one of the public variables, there is no guarentee that it will be valid when I make the assignment. Even if I were to use some kind of getResult() function, I would need to know when to call it so that the code has completed executing.
So, how is this usually done?
(Also, is my http read code ok?)
My ability: I can code, but am new to android.
Use an interface
new RetreiveURLTask(ActivityName.this).execute();
In your asyctask
TheInterface listener;
In the constructor
public RetreiveURLTask (Context context)
{
listener = (TheInterface) context;
}
The interface
public interface TheInterface {
public void theMethod(String result);
}
In onPostExecute
if (listener != null)
{
listener.theMethod(stream_url);
}
In your activity class implement the interface
implements RetreiveURLTask.TheInterface
Implement the method
#Override
public void theMethod(String result) {
// update ui using result
}
// try this way
RetreiveURLTask task = new RetreiveURLTask();
task.execute();
private void response(String responseData){
// here you write your code which use responseData
}
class RetreiveURLTask extends AsyncTask<Void, Void, String> {
private Exception exception = null;
public String ResultString = null;
protected String doInBackground(Void ... something) {
URL url;
try {
url = new URL("http://stream.lobant.net/ccfm.info");
HttpURLConnection urlConnection;
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
String stream_url = IOUtils.toString(in, "UTF-8");
urlConnection.disconnect();
return stream_url;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (Exception e) {
this.exception = e;
return null;
}
}
protected void onPostExecute(String stream_url) {
// TODO: check this.exception
// TODO: check this.exception
// TODO: do something with the feed
super.onPostExecute(stream_url);
response(stream_url)
}
}
Make this
public String ResultString = "";
Global
Asynctask is not the main class here , that's the reason you get ResultString cannot be resolved or is not a field
make it a global variable then you'll be able to access it
The execution of the AsyncTask is started in the background, while the assignment is carried out immediately after the execution began. Therefore, the assignment is carried out before the execution of the AsyncTask is complete.
Your best bet is to conduct the assignment in the OnPostExecute() method.

Android: TRying to show text saying sending when HttpClient sends message to server

I have a simple program that aks questions then call a php file saying if the answer was a yes or a no.
Right now it works but there is a slight pause when the information is being send. I would like some kind message or indicator to come up showing the computer is busy.
Now when I chnage the text of a textvue, before I send the data, the textView does not change, I allso tried to call it's update methed
code
case R.id.butYes:
mSend .setText("Sending your vote to server");
mSend.invalidate();
TalkToServer( mYes[mPes-1] );
UpdateScreen();
mSend .setText("");
break;
String TalkToServer( String addr)
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(addr);
HttpResponse response;
String responseBody=new String("");
try {
response = httpclient.execute(httppost);
responseBody = EntityUtils.toString(response.getEntity());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return responseBody;
}
use AsyncTask to avoid hanging of UI when sending data to server just change your code as:
case R.id.butYes:
new SendTextOperation().execute("");
break;
private class SendTextOperation extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
//Update UI here
mSend.setText("Sending your vote to server");
mSend.invalidate();
}
#Override
protected String doInBackground(String... params) {
// Talk to server here to avoid Ui hanging
TalkToServer( mYes[mPes-1] );
return null;
}
#Override
protected void onPostExecute(String result) {
// Update screen here after talk to server end
UpdateScreen();
mSend .setText("");
}
}

Categories

Resources