how to call UI or UI thread in doInBackground method - android

I'm using AsyncTask class to connect with database. Based on data I will create dynamic EditText, Checkbox without involving XML file.
lView = new LinearLayout(this); - Here I'm facing with error!
Is there any way to call UI thread inside of doInBackground method!
Thanks in advance!!
#Override
protected String doInBackground(String... param) {
HashMap<String, bean> map = new HashMap<String, bean>();
try {
url = new URL("http://localhost/app/alldata.php");
} catch (MalformedURLException e) {
Toast.makeText(getApplicationContext(), "URL Exception", Toast.LENGTH_LONG).show();
e.printStackTrace();
return null;
}
try {
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("user_id", "user_id")
.appendQueryParameter("dpt_id","dptid");
String query = builder.build().getEncodedQuery();
// Open connection for sending data
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
int response_code = conn.getResponseCode();
lView = new LinearLayout(this);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return null;
}

You can call publishProgress() from doInBackground method and override onProgressUpdate which will be called on UI thread.
Obviously, this is intented for progress-like usage. You should have clearly separated one unit of work for background and then process it normally in onPostExecute.

If you really want to communicate with the main UI Thread you can use:
runOnUiThread(new Runnable() {
#Override
public void run() {
//place your code here
}
});

The more elegant way of doing this is passing a callback function so that when your AsyncTask finishes its job, it can invoke the method call in your Activity and then you can make necessary changes there.
I would like to suggest keeping an interface like this.
public interface HttpResponseListener {
void httpResponseReceiver(String result);
}
Now, in your Activity, you need to implement this listener and when executing your AsyncTask you need to pass the listener to that AsyncTask too.
public YourActivity extends Activity implements HttpResponseListener {
// ... Other functions
#Override
public void httpResponseReceiver(String result) {
int response_code = (int) Integer.parseInt(result);
// Take necessary actions here
lView = new LinearLayout(this);
}
}
Now in your AsyncTask you need to have a variable first as a listener to your Activity.
public class HttpRequestAsyncTask extends AsyncTask<Void, Void, String> {
// Declare the listener here
public HttpResponseListener mHttpResponseListener;
#Override
protected String doInBackground(String... param) {
HashMap<String, bean> map = new HashMap<String, bean>();
try {
url = new URL("http://localhost/app/alldata.php");
} catch (MalformedURLException e) {
Toast.makeText(getApplicationContext(), "URL Exception", Toast.LENGTH_LONG).show();
e.printStackTrace();
return null;
}
try {
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("user_id", "user_id")
.appendQueryParameter("dpt_id","dptid");
String query = builder.build().getEncodedQuery();
// Open connection for sending data
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
// int response_code = conn.getResponseCode(); // Return the result to onPostExecute
// lView = new LinearLayout(this); // Remove this from here
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return conn.getResponseCode() + "";
}
// Set the result here
#Override
protected void onPostExecute(final String result) {
mHttpResponseListener.httpResponseReceiver(result);
}
}
Now from your Activity, when you're starting the AsyncTask you need to assign the listener first like this.
HttpRequestAsyncTask mHttpRequestAsyncTask = new HttpRequestAsyncTask();
mHttpRequestAsyncTask.mHttpResponseListener = YourActivity.this;
// Start your AsyncTask
mHttpRequestAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Hope that helps!

Related

Android : take Data in ListView

Actually in my project, I'm blocked. So, for the first time I ask the community of Stackoverflow. I'm new in development.
So, I have a MySql with my datas and I wan't to see in my application the items of users.
For that, I've this :
public class SuccessActivity extends AppCompatActivity {
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private ListView listView;
protected String meubles[] = new String[100];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_success);
Intent intent = getIntent();
String id = intent.getStringExtra("id");
this.listView = (ListView) findViewById(R.id.liste);
new SuccessActivity.Recup().execute(id);
}
//PRIVATE CLASSE POUR AFFICHER LES MEUBLES
private class Recup extends AsyncTask<String, String, String> {
HttpURLConnection conn;
URL url = null;
#Override
protected String doInBackground(String... params) {
try {
//url d'ou reside mon fichier php
url = new URL("http://opix-dev.fr/mytinyhomme/personne/afficher.meuble.php");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
}
try {
// parametrage du HttpURLConnection pour recevoir et envoyer des donner à mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("id", params[0]);
String query = builder.build().getEncodedQuery();
// Open connection for sending data
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return "exception";
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return "exception";
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String resulta) {
//this method will be running on UI thread
if (resulta.equalsIgnoreCase("false")) {
} else if (resulta.equalsIgnoreCase("exception") || resulta.equalsIgnoreCase("unsuccessful")) {
} else {
try {
JSONArray nom = new JSONArray(resulta);
System.out.println(nom);
String meubles[] = new String[100];
for (int i = 0; i < nom.length(); i++){
JSONObject jsonobject = nom.getJSONObject(i);
meubles[i]= jsonobject.getString("nom");
System.out.println(jsonobject);
System.out.println(meubles);
item.setText( meubles[i]);
}
System.out.println(meubles);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
The file.php is correct because the JSONArray in System.print is ok But I've try with some TextView for display the board at the end, but I did not succeed.
How I can use the meuble[0] , meuble[1], meuble[2](it's board of String name of items) in a ListView ?
Here is what you need to do to show your data in a listview,
Modified onPostExecute() method:
#Override
protected void onPostExecute(String resulta) {
//this method will be running on UI thread
if (resulta.equalsIgnoreCase("false")) {
} else if (resulta.equalsIgnoreCase("exception") || resulta.equalsIgnoreCase("unsuccessful")) {
} else {
try {
JSONArray nom = new JSONArray(resulta);
System.out.println(nom);
String meubles[] = new String[100];
for (int i = 0; i < nom.length(); i++){
JSONObject jsonobject = nom.getJSONObject(i);
meubles[i]= jsonobject.getString("nom");
System.out.println(jsonobject);
System.out.println(meubles);
}
ArrayAdapter<String> listAdapter=new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,meubles);
listView.setAdapter(listAdapter);
System.out.println(meubles);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
What's added?
You need an adapter to show items in a listview. You can create your custom adapter class by extending an arrayadapter or you can use an arrayadapter without customizing it as shown.
Added code:
Create a new adapter,
ArrayAdapter listAdapter=new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,list);
Set adapter for your listview,
listView.setAdapter(listAdapter);

Get unique item id from item list in Android

I was creating android project in that i am using itemlist view and pagination . while clicking on that particular item i want to get that item id.but i am not getting the unique id.
When i use position then each and every page it is getting form 0-9.
i have the field 'audit_id'. i want to assign this values as item id and i want to get . whether it is possible?
My Code is :
private class AsyncLogin extends AsyncTask<String, String, StringBuilder> {
ProgressDialog pdLoading = new ProgressDialog(Tblview.this);
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected StringBuilder doInBackground(String... params) {
try {
// Enter URL address where your php file resides
url = new URL("http://192.168.1.99/ashwad/ims/webservices/alldata.php");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "URL Exception", Toast.LENGTH_LONG).show();
e.printStackTrace();
return null;
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn.setDoInput(true);
conn.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("user_id", "sdfa")
.appendQueryParameter("password", "asffs");
String query = builder.build().getEncodedQuery();
// Open connection for sending data
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return null;
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
result = new StringBuilder();
String next1;
while ((next1 = bufferedReader.readLine()) != null) {
result.append(next1 + "\n");
}
Log.e("dfasf",result.toString());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return result;
}
#Override
protected void onPostExecute(StringBuilder s) {
super.onPostExecute(s);
try {
JSONArray login;
JSONObject obj = new JSONObject(s.toString());
if(s.toString().contains("Result")) {
data = new ArrayList<String>();
login = obj.getJSONArray("Result");
for(int i=0;i<login.length();i++) {
JSONObject c = login.getJSONObject(i);
productsArray = c.getJSONArray(Latest_Products);
TOTAL_LIST_ITEMS=productsArray.length();
int val = TOTAL_LIST_ITEMS%NUM_ITEMS_PAGE;
val = val==0?0:1;
pageCount = (TOTAL_LIST_ITEMS/NUM_ITEMS_PAGE)+val;
for (int j = 0; j < productsArray.length(); j++) {
JSONObject cc = productsArray.getJSONObject(j);
//------------------------------------------------------------------------
Log.e("audit",cc.getString("phone_name"));
String audit_id_str = cc.getString("audit_id");
int audit_id =Integer.parseInt(audit_id_str);
listview.setSelection(audit_id);
data.add(cc.getString("phone_name") +"\n\n"+cc.getString("audit_status") );
loadList(0);
btn_next.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
increment++;
loadList(increment);
CheckEnable();
}
});
btn_prev.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
increment--;
loadList(increment);
CheckEnable();
}
});
//------------------------------------------------------------------------
}
}
pdLoading.dismiss();
//CheckEnable();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
private void loadList(int number)
{
ArrayList<String> sort = new ArrayList<String>();
title.setText("Page "+(number+1)+" of "+pageCount);
int start = number * NUM_ITEMS_PAGE;
for(int i=start;i<(start)+NUM_ITEMS_PAGE;i++)
{
if(i<data.size())
{
sort.add(data.get(i));
}
else
{
break;
}
}
sd = new ArrayAdapter<String>(Tblview.this,android.R.layout.simple_list_item_1,sort);
listview.setAdapter(sd);
}
private void CheckEnable()
{
if(increment+1 == pageCount)
{
btn_next.setEnabled(false);
btn_prev.setEnabled(true);
}
else if(increment == 0)
{
btn_prev.setEnabled(false);
btn_next.setEnabled(true);
}
else
{
btn_prev.setEnabled(true);
btn_next.setEnabled(true);
}
}
}
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int positon1 =position;
String a1 = Integer.toString(positon1);
Toast.makeText(getApplicationContext(),a1,Toast.LENGTH_SHORT).show();
}
});
If you are keeping count of page then you can add page number to item position.
That will give you unique number for each item.

How Android Async Task Works with UrlConnection

I am new with the android. I am developing an app that will load content from target url in file. If the url didn't work, it will contact our server to request the correct url. If still fail, then it will ask the url from user input dialog. And it will try to initialize again. I have code like this:
if (initialize(target)!=true) {
JSONObject jsonParam = new JSONObject();
try {
jsonParam.put("sns", getSerial(PREF_NAME));
jsonParam.put("code", pwd);
} catch (JSONException e) {
e.printStackTrace();
}
target = getContent(samURL + "/sam_ip", jsonParam);
if (initialize(target)!=true) {
askIpUserDialog();
}
}
and the initialize() as follow
private boolean initialize(String url) {
Boolean success = false;
if ((!url.trim().startsWith("http://")) && (!url.trim().startsWith("https://"))) {
url = "http://" + url;
}
if (url.endsWith("/")) {
url = url.substring(0,url.length()-1);
}
String sUrl = url + "/android_view";
URL pUrl;
HttpURLConnection urlConn = null;
try {
DataOutputStream printout;
DataInputStream input;
pUrl = new URL (sUrl);
urlConn = (HttpURLConnection) pUrl.openConnection();
urlConn.setDoInput (true);
urlConn.setDoOutput (true);
urlConn.setUseCaches (false);
urlConn.setRequestProperty("Content-Type","application/json");
urlConn.setRequestProperty("Host", "android.schoolportal.gr");
urlConn.connect();
//Create JSONObject here
JSONObject jsonParam = new JSONObject();
jsonParam.put("snc", serialClient);
jsonParam.put("code", pwd);
printout = new DataOutputStream(urlConn.getOutputStream());
String str = jsonParam.toString();
byte[] data = str.getBytes("UTF-8");
printout.write(data);
printout.flush();
printout.close ();
int HttpResult = urlConn.getResponseCode();
if(HttpResult == HttpURLConnection.HTTP_OK){
success = true;
WebView view=(WebView) this.findViewById(R.id.webView);
view.setWebChromeClient(new WebChromeClient());
view.setWebViewClient(new WebViewClient());
view.getSettings().setJavaScriptEnabled(true);
view.loadUrl(sUrl);
}else{
success = false;
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally{
if(urlConn!=null)
urlConn.disconnect();
}
return success;
}
I just know that in android, url connection should run in separate thread. That's why I got the following error:
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork
My question is, how do I use AsyncTask to avoid the error?
I saw there is doInBackground() which I can put the initialize() function there.
I saw also there is onPostExecute() event which I can check the result from the doInBackground(), but I don't understand yet how do I retrieve the return of initialize() which placed inside doInBackground()?
Bonus question, later I'd like to place all this job inside an intentservice. Do I need to stil use the asynctask? Does intentservice itself is an asynctask?
you can try some thing like this and also u can use a different thread
final Handler h = new Handler();
Runnable r = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
final File file = new File(path);
Log.i("path",path);
downloadFile(url[j], file);
h.post(new Runnable(){
#Override
public void run() {
txt.setText(""+jp);
jp++;
}
});
}
}
};
new Thread(r).start();
}
private static void downloadFile(String url, File outputFile) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
Log.i("len","" + contentLength);
Log.i("url1","Streaming from "+url+ "....");
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch(FileNotFoundException e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
} catch (IOException e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
}
catch (Exception e) {
Log.v("FileError" , e.toString());
return; // swallow a 404
}
}
and also you cant access ui elements on different thread you have to use handler or run on ui thread.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try{
this.pd = ProgressDialog.show(this, "Loading..", "Please Wait...", true, false);
new AsyncAction().execute();
}catch (Exception e) {
e.printStackTrace();
}
}
private class AsyncAction extends AsyncTask<String, Void, String> {
protected Void doInBackground(String... args) {
//do your stuff here }
}
}
Network traffic (and all other logic which takes some time to process) should always be handled by a background thread and never on the Main thread.
Use an ASyncTask to execute the logic.
private class YourTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// perform your network logic here
return "YourResult";
}
#Override
protected void onPostExecute(String result) {
// Update your screen with the results.
}
}
Call the ASyncTask in your code:
new YourTask().execute("");

HttpUrlConnection multipart file upload with progressBar

I want to check progress of uploading file by HttpUrlConnection. How I can do this? I've tried to calculate bytes when writing data in OutputStream but it's wrong, cause real uploading happens only when I call conn.getInputStream(), so I need somehow to check inputStream. Here is my code:
public static void uploadMovie(final HashMap<String, String> dataSource, final OnLoadFinishedListener finishedListener, final ProgressListener progressListener) {
if (finishedListener != null) {
new Thread(new Runnable() {
public void run() {
try {
String boundary = getMD5(dataSource.size()+String.valueOf(System.currentTimeMillis()));
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.setCharset(Charset.forName("UTF-8"));
for (String key : dataSource.keySet()) {
if (key.equals(MoviesFragmentAdd.USERFILE)) {
FileBody userFile = new FileBody(new File(dataSource.get(key)));
multipartEntity.addPart(key, userFile);
continue;
}
multipartEntity.addPart(key, new StringBody(dataSource.get(key),ContentType.APPLICATION_JSON));
}
HttpEntity entity = multipartEntity.build();
HttpURLConnection conn = (HttpsURLConnection) new URL(URL_API + "/video/addForm/").openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("Content-length", entity.getContentLength() + "");
conn.setRequestProperty(entity.getContentType().getName(),entity.getContentType().getValue());
OutputStream os = conn.getOutputStream();
entity.writeTo(os);
os.close();
//Real upload starting here -->>
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//<<--
JsonObject request = (JsonObject) gparser.parse(in.readLine());
if (!request.get("error").getAsBoolean()) {
//do something
}
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
Because you have to deal with upload, I'd suppose most time is taken when doing entity.writeTo(os);. Maybe the first contact to the server takes some time as well (DNS resolution, SSL-handshake, ...). The markers you set for "the real upload" are not correct IMO.
Now it depends on your Multipart-library, whether you can intercept writeTo. If it is clever and resource-efficient, it's iterating over the parts and streams the content one-by-one to the output stream. If not, and the .build() operation is creating a big fat byte[], then you could take this array, stream it in chunks to the server and tell your user how many percent of the upload is already done.
From a resource perspective I'd prefer not really knowing what happens. But if feedback is that important and if the movies are only a few megabytes in size, you could stream the Multipart-Entity first to a ByteArrayOutputStream and then write little chunks of the created byte-array to the server while notifying your user about progress. The following code is not validated or tested (you can see it as pseudo-code):
ByteArrayOutputStream baos = new ByteArrayOutputStream();
entity.writeTo(baos);
baos.close();
byte[] payload = baos.toByteArray();
baos = null;
OutputStream os = conn.getOutputStream();
int totalSize = payload.length;
int bytesTransferred = 0;
int chunkSize = 2000;
while (bytesTransferred < totalSize) {
int nextChunkSize = totalSize - bytesTransferred;
if (nextChunkSize > chunkSize) {
nextChunkSize = chunkSize;
}
os.write(payload, bytesTransferred, nextChunkSize); // TODO check outcome!
bytesTransferred += nextChunkSize;
// Here you can call the method which updates progress
// be sure to wrap it so UI-updates are done on the main thread!
updateProgressInfo(100 * bytesTransferred / totalSize);
}
os.close();
A more elegant way would be to write an intercepting OutputStream which registers progress and delegates the real write-operations to the underlaying "real" OutputStream.
Edit
#whizzzkey wrote:
I've re-checked it many times - entity.writeTo(os) DOESN'T do a real upload, it does conn.getResponseCode() or conn.getInputStream()
Now it's clear. HttpURLConnection is buffering your upload data, because it doesn't know the content-length. You've set the header 'Content-length', but oviously this is ignored by HUC. You have to call
conn.setFixedLengthStreamingMode(entity.getContentLength());
Then you should better remove the call to conn.setRequestProperty("Content-length", entity.getContentLength() + "");
In this case, HUC can write the headers and entity.writeTo(os) can really stream the data to the server. Otherwise the buffered data is sent when HUC knows how many bytes will be transferred. So in fact, getInputStream() tells HUC that you're finished, but before really reading the response, all the collected data has to be sent to the server.
I wouldn't recommend changing your code, but for those of you who don't know the exact size of the transferred data (in bytes, not characters!!), you can tell HUC that it should transfer the data in chunks without setting the exact content-length:
conn.setChunkedStreamingMode(-1); // use default chunk size
Right this code in your activity...
public class PublishPostToServer extends AsyncTask implements
ProgressListenerForPost {
public Context pContext;
public long totalSize;
private String response;
public PublishPostToServer(Context context) {
pContext = context;
}
protected void onPreExecute() {
showProgressDialog();
}
#Override
protected Boolean doInBackground(Void... params) {
boolean success = true;
try {
response = NetworkAdaptor.getInstance()
.upLoadMultipartImageToServer(
"",
"",
"", this, this); // Add file path, Authkey, caption
} catch (Exception e) {
success = false;
}
return success;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
//validateResponse(result, response);
}
#Override
protected void onProgressUpdate(Integer... values) {
try {
if (mProgressDialog != null) {
mProgressDialog.setProgress(values[0]);
}
} catch (Exception exception) {
}
}
#Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
}
private void showProgressDialog() {
try {
String dialogMsg = "Uploading Image...";
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage(dialogMsg);
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
} catch (Exception exception) {
}
}
Now, Make a NetworkAdapter Class
public String upLoadMultipartImageToServer(String sourceFileUri,
String auth_key, String caption, ProgressListenerForPost listiner,
PublishPostToServer asyncListiner) {
String upLoadServerUri = "" + "upload_image";
HttpPost httppost = new HttpPost(upLoadServerUri);
File file = new File(sourceFileUri);
if (file.exists()) {
FileBody filebodyVideo = new FileBody(file);
CustomMultiPartEntity multipartEntity = new CustomMultiPartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE, listiner);
try {
multipartEntity.addPart("auth_key", new StringBody(auth_key));
multipartEntity.addPart("caption", new StringBody(caption));
multipartEntity.addPart("image", filebodyVideo);
asyncListiner.totalSize = multipartEntity.getContentLength();
httppost.setEntity(multipartEntity);
}
catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
DefaultHttpClient mHttpClient = new DefaultHttpClient();
String response = "";
try {
response = mHttpClient.execute(httppost,
new MovieUploadResponseHandler());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
} else {
return null;
}
}
#SuppressWarnings("rawtypes")
private class MovieUploadResponseHandler implements ResponseHandler {
#Override
public Object handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
HttpEntity r_entity = response.getEntity();
String responseString = EntityUtils.toString(r_entity);
// DebugHelper.printData("UPLOAD", responseString);
return responseString;
}
}
public static boolean isValidResponse(String resultData) {
try {
} catch (Exception exception) {
//DebugHelper.printException(exception);
}
return true;
}
public String upLoadVideoToServer(String currentFilePath, String string,
PublishPostToServer publishPostToServer,
PublishPostToServer publishPostToServer2) {
// TODO Auto-generated method stub
return null;
}

Android: waiting for response from server just for a minute otherwise showing alert dialog

I need to show a dialog box if the internet network is low and response from server side is taking time more than 1 minute. how to accomplish this task.
I am using following code for it.
BUt it is not working intentionally.:
try
{
HttpConnectionParams.setConnectionTimeout(hc.getParams(),60000);
int timeoutSocket = 60*1000;
HttpConnectionParams.setSoTimeout(hc.getParams(), timeoutSocket);
}
catch(ConnectTimeoutException e){
//System.out.println(e);
m_Progress.cancel();
alertDialog = new AlertDialog.Builder(AdminEbooks.this).create();
//alertDialog.setTitle("Reset...");
// System.out.println("internet not available");
alertDialog.setMessage("Low internet connectivity?");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.cancel();
}
});
}
Here is how I'm doing this :
public void UseHttpConnection(String url, String charset, String query) {
try {
System.setProperty("http.keepAlive", "false");
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setDoOutput(true);
connection.setConnectTimeout(15000 /* milliseconds */);
connection.setRequestMethod("POST");
connection.setRequestProperty("Charset", charset);
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=" + charset);
OutputStream output = null;
try {
output = connection.getOutputStream();
output.write(query.getBytes(charset));
} catch (IOException e) {
e.printStackTrace();
showError2("Check your network settings!");
} finally {
if (output != null)
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
int status = ((HttpURLConnection) connection).getResponseCode();
Log.d("", "Status : " + status);
for (Entry<String, List<String>> header : connection
.getHeaderFields().entrySet()) {
Log.d("Headers",
"Headers : " + header.getKey() + "="
+ header.getValue());
}
InputStream response = new BufferedInputStream(connection.getInputStream());
int bytesRead = -1;
byte[] buffer = new byte[30 * 1024];
while ((bytesRead = response.read(buffer)) > 0) {
byte[] buffer2 = new byte[bytesRead];
System.arraycopy(buffer, 0, buffer2, 0, bytesRead);
handleDataFromSync(buffer2);
}
connection.disconnect();
} catch (FileNotFoundException e) {
e.printStackTrace();
showError2("Check your network and server settings!");
} catch (IOException e) {
showError2("Check your network settings!");
e.printStackTrace();
}
}
Basically if your connection is time out it will throw you an IOException which you need to catch and create the alert dialog there. At least this is what I'm doing and it's working.
Make a method for checking the response time,
public boolean checkURL() {
boolean exist = false;
try {
URL url=new URL("http://.................");
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(60000);
urlConnection.connect();
exist = true;
} catch(Exception e) {
e.printStackTrace();
exist = false;
}
return exist;
}
it return flase if not responded in 60 secs
Now perform the condition,
if(chcekURL){
} else {
alertDialog = new AlertDialog.Builder(AdminEbooks.this).create();
//alertDialog.setTitle("Reset...");
// System.out.println("internet not available");
alertDialog.setMessage("Low internet connectivity?");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.cancel();
}
});
}
Sounds like you need to put it in a background thread. I recommend using AsyncTask.
You'll need to override onPreExecute(), doInBackground(), and onPostExecute() at the very minimum to accomplish what you are trying to do.
onPreExecute() and onPostExecute() are executed on the UI thread so your dialogs can be shown in these methods.
I recommend doInBackground() to return a boolean so onPostExecute() can display the correct dialog.
For my dialogs i just use
String error = e.toString();
Dialog d = new Dialog(this);
d.setTitle("Dialog Title");
TextView tv = new TextView(this);
tv.setText(error);
d.setContentView(tv);
d.show();

Categories

Resources