I am trying to get the result from the AsyncTask to another class. I am using interface to achieve this. I doing the same procedure in another module and it was working good but I fail to identify the issue in this case...
I'm calling like this from another class.
GroupDetails gd=new GroupDetails();
groups=gd.getGroupList("email");
public class GroupDetails implements AsyncResponse {
String result;
String[] groupList;
public String getGroupList(String userEmail){
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("user_email", userEmail));
PhpConnect phpcon=new PhpConnect("http://www.pinnacle2k14.com/letsmeet/get_group.php",postParameters);
phpcon.delegate=this;
phpcon.execute();
result="hello"
return result;
}
#Override
public void processFinish(String output) { //this method not functioning why?
// TODO Auto-generated method stub
result="hello";
//groupList=output.split(",");
}
}
PhpConnect.php
public class PhpConnect extends AsyncTask<String, Void, String> {
String url1;
ArrayList<NameValuePair> postParameters1;
public PhpConnect(String url,ArrayList<NameValuePair> postParameters){
url1=url;
postParameters1=postParameters;
}
public PhpConnect() {
// TODO Auto-generated constructor stub
}
String response;
public AsyncResponse delegate=null;
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
try {
response = CustomHttpClient.executeHttpPost(url1,postParameters1);
} catch (Exception e) {
// TODO Auto-generated catch block
response=e.toString();
}
return response;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
delegate.processFinish(result);
}
}
AsynResponse interface
public interface AsyncResponse {
void processFinish(String output);
}
You know you can do
PhpConnect phpcon=new PhpConnect("http://www.pinnacle2k14.com/letsmeet/get_group.php",postParameters) {
#Override
public void onPostExecute(String result) {
//DO YOUR STUFF
}
};
phpcon.execute();
This way you can save the callback.
Related
I have a class AsyncCallWS that get content from webservice. It worked well. However, I want to get result in the class AsyncCallWS, namely returnServer string in the MainActivity . Could you help me to solve it?
public class MainActivity extends Activity {
String resultRegister;
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnRegister =(Button) findViewById(R.id.btnRegister);
btnRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
new AsyncCallWS().execute("123");
Log.d("DDD",resultRegister);
if(resultRegister.equals("")) {
Log.d("D", "OK");
}
else
{
Log.d("E", "False");
}
}
});
}
private class AsyncCallWS extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
Log.i(TAG, "doInBackground");
String id_num = params[0];
//toast(id);
String url_registerID="server path"+id_num ;
try {
String returnServer=getStringContent(id);
Log.d("D",returnServer);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
}
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i(TAG, "onProgressUpdate");
}
}
Remove 3rd parameter Void from this AsyncTask<String, Void, Void>
and replace it with String, i.e;
private class AsyncCallWS extends AsyncTask<String, Void, String>
After changing you'll get compilation errors in your doInBackground().. just change the return type from Void to String
protected String doInBackground(String... params)
Now you can get the String returned by this method in onPostExecute(String result)
The String result here is the String which is returned by doInBackground()
*EDIT *
public class MainActivity extends Activity {
String resultInActivity;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AsyncCallWS().execute("123");
//How to get respond from AsyncCallWS
}
private class AsyncCallWS extends AsyncTask<String, Void, Void> {
#Override
protected String doInBackground(String... params) {
Log.i(TAG, "doInBackground");
String id_num = params[0];
//toast(id);
String url_registerID="server path"+id_num ;
try {
String returnServer=getStringContent(id);
Log.d("D",returnServer);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return returnServer;
}
#Override
protected void onPostExecute(String result) {
Log.i(TAG, "onPostExecute");
resultInActivity = result;
if(resultRegister.equals("")) {
Log.d("D", "OK");
}
else
{
Log.d("E", "False");
}
}
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i(TAG, "onProgressUpdate");
}
} // Asyntask ends
} // activity ends
The response from AsyncTask is produced in onPostExecute() from there you can perform tasks based on the response etc.
I highly recommend you read the AsyncTask Life Cycle
private class AsyncCallWS extends AsyncTask
Replace the third parameter with String which results doInBackground return String and corresponding postExecute method parameter as String
protected String doInBackground(String... params)
protected void onPostExecute(String result)
In Order to get it on MainActivity you have to do the following Steps
Create an Interface anywhere you want to and declare a method of any name which should have parameter of type String
interface ResponseHandler
{
void onResponse(String result)
}
In the MainActivity you have to implement that interface and you will
get the data here in this method
ResponseHandler handler = new ResponseHandler(){
#override
public void onResponse(String result)
{
// enter code here
}
};
After implementing this interface you can provide the instance of it to the AsyncTask constructor.
AsyncTask task = new AsyncTask(handler);
You will get the reference of ResponseHandler in AsyncTask
public AsyncTaskClass(ResponseHandler handler)
{
this.handler = handler
}
//enter code here
void onPostExecute(String result)
{
handler.onResponse(result)
}
This way you will get the result in your MainActivity.
I have searched all over for a good code for uploading an mp3 or similar file to a php server and have tested over 10 samples but none has been successful so far. Most codes I have checked out are either full of bugs or use outdated libraries.
I would appreciate if anyone has a truly working code sample. Possibly one that uses volley or a similar library. Would appreciate any help or some code that points me in the right direction.
Thanks
You can use loopj Android Asynchronous Http Client lib for uploading file to the php server.
download the lib file from given link and put into your project's libs folder and use this code for uploading file.
public void postFile(){
RequestParams params = new RequestParams();
params.put("fileTitle","MyFile1");
params.put("file", new File("File Path Here")); // e.g Environment.getExternalStorageDirectory().getPath() + "/test.mp3"
AsyncHttpClient client = new AsyncHttpClient();
client.post("http://www.yourweserviceurlhere.com", params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
// TODO Auto-generated method stub
}
#Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
// TODO Auto-generated method stub
}
});
}
if you want progress of uploading. then you can use my custom design class. for this also require common io 2.4 lib reference in converting HTTPresponse into string.
public class AsyncLoader {
private String url;
private LoaderCallBackHandler mCallback;
private Context mContext;
private RequestParams params;
private RequestHandle handle;
public interface LoaderCallBackHandler {
public void onStartUploading();
public void uploadComplete(String response);
public void failedWithError(Throwable error);
public void progressUpdate(long bytesWritten, long bytesTotal);
public void onCancle();
public void onFinish();
}
public AsyncLoader(Context mContext,String url,RequestParams params, LoaderCallBackHandler callback) {
this.mContext = mContext;
this.url = url;
this.params = params;
this.mCallback = callback;
}
public void startTransfer() {
AsynchConfig.mClient.setTimeout(50000);
handle = AsynchConfig.mClient.post(mContext, url, params,handlerInterface);
}
private ResponseHandlerInterface handlerInterface = new ResponseHandlerInterface() {
#Override
public void sendStartMessage() {
if(mCallback != null) {
mCallback.onStartUploading();
}
}
#Override
public void sendResponseMessage(HttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
// TODO convert in stream to JSONObject and do whatever you need to
StringWriter writer = new StringWriter();
IOUtils.copy(instream, writer, Charset.defaultCharset());
String theString = writer.toString();
if(mCallback != null) {
mCallback.uploadComplete(theString);
}
}
}
#Override
public void sendSuccessMessage(int arg0, org.apache.http.Header[] arg1, byte[] arg2) {
}
#Override
public void sendFailureMessage(int arg0, org.apache.http.Header[] arg1,
byte[] arg2, Throwable error) {
if(mCallback != null) {
mCallback.failedWithError(error);
}
}
#Override
public void sendFinishMessage() {
if(mCallback != null) {
mCallback.onFinish();
}
}
#Override
public void sendProgressMessage(long bytesWritten, long bytesTotal) {
if(mCallback != null) {
mCallback.progressUpdate(bytesWritten, bytesTotal);
}
}
#Override
public void setUseSynchronousMode(boolean arg0) {
}
#Override
public void setRequestURI(URI arg0) {
}
#Override
public void setRequestHeaders(org.apache.http.Header[] arg0) {
}
#Override
public URI getRequestURI() {
return null;
}
#Override
public org.apache.http.Header[] getRequestHeaders() {
return null;
}
#Override
public void sendCancelMessage() {
if(mCallback != null) {
mCallback.onCancle();
mCallback.onFinish();
}
}
#Override
public void sendRetryMessage(int retryNo) {
// TODO Auto-generated method stub
}
#Override
public boolean getUseSynchronousMode() {
// TODO Auto-generated method stub
return false;
}
#Override
public void setUsePoolThread(boolean usePoolThread) {
// TODO Auto-generated method stub
}
#Override
public boolean getUsePoolThread() {
// TODO Auto-generated method stub
return false;
}
#Override
public void onPreProcessResponse(ResponseHandlerInterface instance,
HttpResponse response) {
// TODO Auto-generated method stub
}
#Override
public void onPostProcessResponse(ResponseHandlerInterface instance,
HttpResponse response) {
// TODO Auto-generated method stub
}
#Override
public void setTag(Object TAG) {
// TODO Auto-generated method stub
}
#Override
public Object getTag() {
// TODO Auto-generated method stub
return null;
}
};
/**
* Cancel upload by calling this method
*/
public void cancel() throws Exception {
AsynchConfig.mClient.cancelAllRequests(true);
handle.cancel(true);
}
}
Asynch config class
public final class AsynchConfig {
public static AsyncHttpClient mClient = new AsyncHttpClient();
}
Use
RequestParams params = new RequestParams();
params.put("fileTitle","MyFile1");
params.put("file", new File("File Path Here")); // e.g Environment.getExternalStorageDirectory().getPath() + "/test.mp3"
AsyncLoader asyncUploader = new AsyncLoader(this, "URL_HERE", params, callHandler);
asyncUploader.startTransfer();
CallHandler Interface object
LoaderCallBackHandler callHandler = new LoaderCallBackHandler() {
#Override
public void uploadComplete(String response) {
// TODO Auto-generated method stub
}
#Override
public void progressUpdate(long bytesWritten, long bytesTotal) {
// TODO Auto-generated method stub
}
#Override
public void onStartUploading() {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
}
#Override
public void onCancle() {
// TODO Auto-generated method stub
}
#Override
public void failedWithError(Throwable error) {
// TODO Auto-generated method stub
}
};
PHP service for handling uploaded file
if(isset($_FILES['file']) && isset($_POST['fileTitle']) ) {
include './config.php';
//Randomly genrate file name
$stickerTmp = explode(".", $_FILES["file"]["name"]);
$file = md5(date("l, F d, Y h:i" ,time()) . (microtime())).".".end($stickerTmp);
//geting the temp location of file
$filetemploc=$_FILES['file']['tmp_name'];
//path for uploading to the specific location
$pathandname="file_store/".$file;
// moving the file to specified path
$resultUpload = move_uploaded_file($filetemploc, $pathandname);
// if file is successfully moved to over specified path then insert the reference into the DB
if($resultUpload == TRUE) {
//echo "File has been moved from : ". $filetemploc . " to :".$pathandname;
$qInsert = "INSERT INTO file_lists values (null,'".$_POST['fileTitle']."','".$file."') ";
mysql_query($qInsert);
}
}
I extended the Application class in order to create singleton-like object in android.
in this object I have all the HTTP work with my server, and all the other activities can access it and call methods to GET, POST etc.
Code:
public class HttpManagerInstance extends Application {
private HttpClient httpClient;
private HttpGet get;
#Override
public void onCreate() {
httpClient = new DefaultHttpClient();
get = new HttpGet("http://10.100.102.9:8000/users/");
super.onCreate();
}
public Void getUsers() throws Exception {
new executeRequest().execute(get);
return null;
}
private class executeRequest extends AsyncTask<HttpRequest, Void, Integer> {
#Override
protected Integer doInBackground(HttpRequest... params) {
// TODO Auto-generated method stub
HttpRequest request = params[0];
HttpResponse response;
String result="";
try {
response = httpClient.execute((HttpUriRequest) request);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return responseCode;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
switch (result) {
case HttpStatus.SC_OK:
// request was fine
// Here I want to updated the GUI of the activity that called this method.
break;
}
}
}
}
This is how I call the method from the Activity:
HttpManagerInstance sampleApp = (HttpManagerInstance)getApplicationContext();
sampleApp.getUsers();
Again - I want to access the UI of the Activity that called the method to put an REQUEST ACCEPTED message.
Maybe pass a context? any ideas?
I'd create a listener:
public class HttpManagerInstance extends Application {
private HttpClient httpClient;
private HttpGet get;
public interface ResponseListener{
public void onSuccess(Object data);
}
#Override
public void onCreate() {
httpClient = new DefaultHttpClient();
get = new HttpGet("http://10.100.102.9:8000/users/");
super.onCreate();
}
public Void getUsers(ResponseListener listener) throws Exception {
new executeRequest(listener).execute(get);
return null;
}
private class executeRequest extends AsyncTask<HttpRequest, Void, Integer> {
private ResponseListener mListener;
public executeRequest(ResponseListener listener){
this.mListener = listener;
}
#Override
protected Integer doInBackground(HttpRequest... params) {
// TODO Auto-generated method stub
HttpRequest request = params[0];
HttpResponse response;
String result="";
try {
response = httpClient.execute((HttpUriRequest) request);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return responseCode;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
switch (result) {
case HttpStatus.SC_OK:
// request was fine
// Here I want to updated the GUI of the activity that called this method.
if(this.mListener != null) mListener.onSuccess(whatEverDataYouWant);
break;
}
}
}
}
Then, in your activity:
HttpManagerInstance sampleApp = (HttpManagerInstance)getApplicationContext();
sampleApp.getUsers(new ResponseListener(){
public void onSuccess(Object data){
//update your ui!
}
});
The short answer is you can't directly reference to the UI from another activity. My advice would be for you to set up a callback on your Application class and call in on executeRequest#onPostExecute then implement that callback on your Activity and update your UI from there.
If you need help to implement the callback check this question
If you need to show message is good option the Dialog Class or the Toast Class, you can see more info are here:
Dialogs: http://developer.android.com/guide/topics/ui/dialogs.html
Toasts: http://developer.android.com/guide/topics/ui/notifiers/toasts.html
But if you want to access or modify a control in your actual activity, then use Runnable class, and context.runOnUiThread() method if you work inside AsyncTask. The real problem is that you can't change UI in a AsyncTask using declaration of the controls. You need to throw a Runnable process to communicate with activity!!. For example:
context.runOnUiThread(new Runnable() {
public void run() {
//Declaration of variables
TextView MyTextView = (TextView) context.findViewById(R.id.txtvMyControl);
MyTextView.setText("My title");
}
}
If I can helps you say me, good luck!
I want to download stock from web using Web Service. Created Sync to delete current stock
new ResetStock().execute();
Here is ResetStock Async:
private class ResetStock extends AsyncTask<Void, Void, Void>
{
ProgressDialog pd;
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.cancel();
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
pd=new ProgressDialog(FrmMainMenu.this);
pd.setMessage("Please Wait. We are Downloading the Catalogue...");
pd.show();
pd.setCancelable(false);
pd.setCanceledOnTouchOutside(false);
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
DatabaseHandlerStock dbc=new DatabaseHandlerStock(FrmMainMenu.this);
dbc.deleteallstock();
dbc.close();
new AsyncStock(FrmMainMenu.this).execute();
return null;
}
}
Now I Called Another Async to download and xml and insert into my database
here is Asyncstock
List<Stock> mystocks = null;
Context mcontext;
int x=0;
public AsyncStock(Context context) {
super();
this.mcontext = context;
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
try{
URLConnection conn = new URL("http://192.168.1.2/mob2server.asmx/GetStock").openConnection();
mystocks = SAXXMLParser.parse(conn.getInputStream());
DatabaseHandlerStock dbc;
dbc=new DatabaseHandlerStock(mcontext);
String category, make, model, productcode, productname, smallimages, largeimages, description, mrp, unit, pkg;
for(Stock in :mystocks)
{
x++;
category=in.getCategory();
make=in.getMake();
model=in.getModel();
productcode=in.getProductcode();
productname=in.getProductname();
smallimages=in.getSmallimages();
largeimages=in.getLargeimages();
description=in.getDescription();
mrp=in.getMrp();
unit=in.getUnit();
pkg=in.getPkg();
dbc.addContact(new Catalogue(category.replace("$","&"), make.replace("$","&"), model.replace("$","&"), productcode, productname.replace("$","&"), smallimages, largeimages, description.replace("$","&"), mrp, unit, pkg));
}
dbc.close();
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(Void result) {
Toast.makeText(mcontext, "Total " + x + " Models Imported!", Toast.LENGTH_LONG).show();
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
}
My First dialog is cancel before the stock is inserted into stock.
I want my dialog to be there until stock is inserted into my database.
Create another class and pack your second asynctask stuff in it. You can than call this new class in your first asynctask. Also use the progress update to see what is going on. In this way you will have only one progress bar but will keep you informed.
I am trying to use the jsoup to return string from a website but my code breaks after the Jsoup.connect and it doesnt return any string
my code is:
class fetcher extends AsyncTask<Void,Void,Void>{
String myString = null;
#Override
protected Void doInBackground(Void... arg0) {
Document doc = null;
try {
doc = Jsoup.connect("http://www.ismmusalla.org/").get();
Elements divs = doc.select("div#title1");
for (Element div : divs) {
myString=myString+" " +div.text();
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result)
{
textview.setText(myString);
}
}
Because your AsyncTask's doInBackground() has void return type, just change it to String and put myString instead of null as return data,
Like,
protected String doInBackground(Void... arg0) {
return myString;
}
Also the declaration of AsyncTask is not suitable, extends AsyncTask<Void,Void,Void> it should be extends AsyncTask<Void,Void,String>.
Just look at http://developer.android.com/reference/android/os/AsyncTask.html
public class MainActivity extends Activity {
String myString="";
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
new TheTask().execute();
}
class TheTask extends AsyncTask <Void,Void,Void>
{
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
Document doc = null;
try {
doc = Jsoup.connect("http://www.ismmusalla.org/").get();
Elements divs = doc.select("div#title1");
for (Element div : divs) {
myString=myString+" " +div.text();
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
tv.setText(myString);
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
snap shot of emulator
Your title 1 in html code
Or
Edit:
Return string in doInbackground and update textview in onPostExecute
public class MainActivity extends Activity {
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
new TheTask().execute();
}
class TheTask extends AsyncTask <Void,Void,String> // change Void to String
{
String myString="";
#Override
protected String doInBackground(Void... arg0) { // return type is string
// TODO Auto-generated method stub
Document doc = null;
try {
doc = Jsoup.connect("http://www.ismmusalla.org/").get();
Elements divs = doc.select("div#title1");
for (Element div : divs) {
myString=myString+" " +div.text();
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return myString; //return string result
}
#Override
protected void onPostExecute(String result) { // recieve string result
// TODO Auto-generated method stub
super.onPostExecute(result);
tv.setText(result); // update textview with string result
}
}
}
Use below code:
class fetcher extends AsyncTask<Void,Void,String>{
String myString = "";
#Override
protected String doInBackground(Void... arg0) {
Document doc = null;
try {
doc = Jsoup.connect("http://www.ismmusalla.org/").get();
Elements divs = doc.select("div#title1");
for (Element div : divs) {
myString=myString+" " +div.text();
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return myString;
}
protected void onPostExecute(String result)
{
textview.setText(result);
}
}