Error creating an AsyncTask - android

I'm creating a login form. When the user logs in, it will lead to the home page.
I create an activity that has an AsyncTask. Here's the relevant part of my code:
public class iniTask extends AsyncTask<String, Void, String> {
private ProgressDialog Dialog = new ProgressDialog(GPSTracerActivity.this);
protected void onPreExecute() {
Dialog.setMessage("Connect to server...");
Dialog.show();
}
protected String doInBackground(String... url_req) {
String url = url_req[0];
try {
Log.v("doing background", executeHttpGet(url));
return executeHttpGet(url);
} catch(Exception e) {
Log.v("Exception doing background","Exception:"+e.getMessage());
return "";
}
}
protected void onPostExecute(String result) {
try {
Dialog.dismiss();
// here when thing go wrong
startNewAction(result);
} catch(Exception e) {
Log.v("Exception process response","Exception:"+e.getMessage());
}
}
}
Here's startNewAction(result):
public void startNewAction(String result){
if (result.substring(0, 6) == "300 OK"){
Intent i = new Intent(GPSTracerActivity.this, Home.class);
startActivity(i);
}
}
The task starts correctly, but when I call startNewAction(result),
it does not call a new activity. Why?
NOTE : when i enable if structure to test string == 300 OK it is not work ! why
I see this in logcat:
07-16 14:57:23.345: WARN/InputManagerService(37): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy#40777ee0

In your onPostExecute dismiss the dialog first.
Dialog.dismiss();

I just found the solution,there is an error because of the way i compare the string,
It should be,
if (result.substring(0, 6).equals("300 OK") ){
Intent i = new Intent(GPSTracerActivity.this, Home.class);
startActivity(i);
}
Anyway, Thanks for ideas !!!

Related

Error in starting activity from doInBackground()

I am new to android development.
I want to perform some db operations and then, want to start a new activity. I have written AsyncTask code below.
I am getting error on startActivity call. Please help me out.
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
Context mainContext;
public AsyncTaskRunner(Context mainContext){
this.mainContext=mainContext;
}
#Override
protected String doInBackground(String... params) {
publishProgress("Sleeping..."); // Calls onProgressUpdate()
try {
sql.updateRelations();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
#Override
protected void onPostExecute(String result) {
InitActivity.progress.dismiss();
Intent intent = new Intent(mainContext, MainActivity.class);
if(mainContext!=null){
mainContext.startActivity(intent);
((Activity)mainContext).finish();
}
}
#Override
protected void onPreExecute() {
InitActivity.progress.show();
}
#Override
protected void onProgressUpdate(String... text) {
}
}
If your async task is an inner class of your activity then do the below
Intent intent = new Intent(YourActivityName.this, MainActivity.class);
if(mainContext!=null){
mainContext.startActivity(intent);
((Activity)mainContext).finish();
}
Else if your async task is a separate class then try the below
Intent intent = new Intent((YourActivityName)mainContext, MainActivity.class);
if(mainContext!=null){
mainContext.startActivity(intent);
((Activity)mainContext).finish();
}
If it doesn't work please post your logs so i can be of better help.

Best approach to make a login screen

I am writing here because this is my last solution of understanding this type of programming.The problem is that I got stuck on what to use to handle the connection to a server and log-in. Should I use async task, handler or thread ? I didn't find a concrete answer stating which one to use, only found that async task is used to download images or other download stuffs.
Until now I have used a thread to connect to the server. The problem I encountered was when I catch the exception ( Putting invalid username/password ) and try to log-in again. ( I needed to "close" the last thread and start one again )
After this I started to use async task but I don't really understand how it should work and I am stuck on a toast of invalid username/password.
private class connectStorage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
api = DefaultClientFactory.create(host, getUser, getPassword);
if (api.getAuthToken().trim().length() > 3) {
//TO DO LAYOUT CHANGE;
}
} catch (StorageApiException e) {
e.printStackTrace();
Log.i("TEST", "" + e.getMessage());
}
return null;
}
Also, I am 100% sure that calling inflate in the doInBackground method won't work too ( there I wanted to change the activity ).
I am starting the async task on a button press.
When you are using asynctask
You have doInBackground and onPostExecute
So basically get a json or string or boolean as a result from doinbackground
and in onpostexecute check if the login in succesful or not if its succesful save the data from server and start an intent to go to another activity or toast the user that that user login details are wrong and try again.
So your asynctask can be an inner class of your activity class which is login and onClickSubmit button call the asynctask class and on post execute parse the json and according to the result decide what to do
Example:
public class SignInAsycTask extends AsyncTask<RequestParams, Void, String> {
#Override
protected String doInBackground(RequestParams... params) {
return new HttpManager().sendUserData(params[0]);
}
#Override
protected void onPostExecute(String result) {
String[] details = parseJsonObject(result);
if (details != null) {
user.setUser_id(Integer.valueOf(details[0]));
user.setName(details[1]);
if (details.length > 2) {
user.setProfilePic(details[2]);
}
setSharedPreferences();
startActivity(new Intent(Signin.this, MainActivity.class));
finish();
} else {
Toast.makeText(Signin.this, "please try again",
Toast.LENGTH_LONG).show();
}
}
}
public String[] parseJsonObject(String result) {
JSONObject obj = null;
try {
obj = new JSONObject(result);
if (obj.has("success")) {
if (obj.getInt("success") == 1) {
if (obj.has("user_pic")) {
return new String[] {
String.valueOf(obj.getInt("user_id")),
obj.getString("user_name"),
obj.getString("user_pic") };
} else {
return new String[] {
String.valueOf(obj.getInt("user_id")),
obj.getString("user_name"), };
}
} else {
return null;
}
} else {
return null;
}
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
here my RequestParams are just a object where I stored all the details like url parameters to send etc and the output of the doinbackground is a String and I am parsing it in my postexecute method

Start activity is slow

I'm write a music application online.But i'm meet a problem... A new activity starts slowly when I select an item in listview...
I don't know resolve, please help me ! :(
Sorry. I'm speak English very bad :(
This is my code:
public class startNewActivity extends AsyncTask<String, Void, String> {
private Activity activity;
private String selectDoc = "div.gen img";
private String attr = "title";
private String result;
public String Quality;
public startNewActivity(Activity activity) {
this.activity = activity;
}
#Override
protected String doInBackground(String... arg0) {
nameSong = (String) lvSong.getItemAtPosition(positionId);
link = linkSong.get(Integer.valueOf(obj.toString()));
Quality = Utils.getQuality(link, selectDoc, attr, result);
Log.i("Quality", Quality);
changeLink = link.replace(".html", "_download.html").substring(15)
.replaceFirst("", "http://download")
.replace("nhac-hot", "mp3".concat("/vietnam/v-pop"));
Log.i("Change link", changeLink);
try {
//Connect internet
linkIntent = Utils.getLinkPlay(selectLinkPlay, changeLink,
afterChangeLink);
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"Server has problem... Please while for minutes",
Toast.LENGTH_SHORT).show();
}
return linkIntent;
}
#Override
protected void onPostExecute(String result) {
//i'm want help here
Intent i = new Intent(SongActivity.this, PlayMusicActivity.class);
i.putExtra("song", linkIntent);
i.putExtra("namesong", nameSong);
i.putExtra("Quality", Quality);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(i);
pDialog.dismiss();
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
pDialog = ProgressDialog.show(SongActivity.this, "",
"Please wait...");
}
}
You're starting the new activity inside onPostExecute() which executes only after you've completed doInBackground(). Hence, the time delay.
Ideally, you should start the activity just after you execute your AsyncTask. The AsyncTask will continue in the background while your activity changes.

Queue-ing image paths for later upload

I'm having difficulties keeping track of my queue and uploading them at a later moment.
The upload image is a asynctask and in the postexecute a mail is going out to send the uploaded picture.
This is my UploadImage AsyncTask. I think i'm doing way too difficult and that it can be done much easier than it is right now.
private class UploadImageTask extends AsyncTask<Void, Void, Integer> {
ProgressDialog dialog;
/**
* Private integer which counts how many times we've tried to upload the
* Image.
*/
private int _counter = 0;
private List<String> imageUploadList = new ArrayList<String>();
#Override
protected void onPreExecute() {
super.onPreExecute();
if(AppStatus.haveNetworkConnection(_context)){
if(isPhotoTaken()){
dialog = new ProgressDialog(Step4.this);
dialog.setCancelable(false);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(getString(R.string.uploadingMessage));
dialog.setTitle(getString(R.string.uploadingTitle));
dialog.show();
}
}
}
protected Integer doInBackground(Void... params) {
init();
postData();
return null;
}
public void init(){
_counter = 0;
_beenHere = true;
for(String path : imageUploadList){
Debug.out("Path: "+path);
}
}
public void postData() {
if (isPhotoTaken()) {
if(AppStatus.haveNetworkConnection(_context)){
if(_beenHere){
ImageUploader.uploadFile(getPhotoPath(),
"http://obo.nl/android-upload-image.php", Step4.this);
} else {
for(String path : imageUploadList){
Debug.out(path);
ImageUploader.uploadFile(path,
"http://obo.nl/android-upload-image.php", Step4.this);
}
}
} else {
if (_counter == 0) {
_counter++;
_activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(_context,
getString(R.string.noInternetImageNotUploaded),
Toast.LENGTH_LONG).show();
}
});
imageUploadList.add(getPhotoPath());
}
try {
if(_beenHere){
_beenHere = false;
goToNextIntent();
}
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
postData();
}
}
}
private void goToNextIntent(){
Intent intent = new Intent(Step4.this, Step5.class);
intent.putExtra(EXTRA_MESSAGE, (Serializable) _user);
intent.putExtra(EXTRA_MESSAGE2, _isRepairable);
intent.putExtra(EXTRA_MESSAGE3, _injury);
intent.putExtra(EXTRA_MESSAGE4, _category);
intent.putExtra(EXTRA_MESSAGE5, _inch);
intent.putExtra(EXTRA_MESSAGE6, _size);
startActivity(intent);
}
protected void onPostExecute(Integer result) {
if(isPhotoTaken()){
if(dialog != null){
dialog.dismiss();
}
}
mailing(_isRepairable);
new MyAsyncTask().execute(_mail);
}
}
The line:
if(AppStatus.haveNetworkConnection(_context))
returns a boolean true if the user has a working internet connection. false otherwise.
What I want is to queue all the image paths (and mails sent afterwards) in the desired ArrayList so i can send them all at a later moment when the user has a working internet Connection. Please help me out!
You could store your image paths in a list (or something similar) and persist the list, let's say in Shared Preferences. As you finish uploading a picture, you will remove it from that list and continue to the next one, and so on until your list is empty.
While uploading, if the internet connection drops it will not affect you, you will always have persisted the list of images that are still to be uploaded.
Register a broadcast receiver to listen for wi-fi connection, when it gets connected it could automatically continue the upload - this is just a suggestion.

Performing data loading unitl succesfull or user break

In my app I performing loading data from web and then displaying it to user. Before loading data app shows progress dialog. I have problem if user locks phone in the middle of loading operation, or server is overloaded and can't respond in time my application freezes, because it doesn't dismiss progress dialog, or in some cases it crashes because lack on needed data.
If some error happened while loading data I want show some dialog to user to let him know about error and ask him should application repeat last request. I tried to use AlertDialog for it, but I haven't succeed.
Here is code of one activity (There is no progress dialog here, but it demonstrates how I loading data):
#EActivity(R.layout.layout_splash)
#RoboGuice
public class SplashScreenActivity extends Activity {
#Inject
private AvtopoiskParserImpl parser;
#Bean
BrandsAndRegionsHolder brandsAndRegionsHolder;
#ViewById(R.id.splash_progress)
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadData();
}
#Background
protected void loadData() {
publishProgress(10);
LinkedHashMap<String, Integer> brands = null;
try {
brands = parser.getBrands();
} catch (IOException e) {
Log.e(e.getMessage());
}
publishProgress(50);
LinkedHashMap<String, Integer> regions = null;
try {
regions = parser.getRegions();
} catch (IOException e) {
Log.e(e.getMessage());
}
publishProgress(70);
populateData(brands, regions);
}
#UiThread
protected void populateData(LinkedHashMap<String, Integer> brands, LinkedHashMap<String, Integer> regions) {
Intent intent = new Intent(SplashScreenActivity.this, SearchActivity_.class);
brandsAndRegionsHolder.brandsMap = brands;
brandsAndRegionsHolder.regionsMap = regions;
publishProgress(100);
startActivity(intent);
finish();
}
#UiThread
void publishProgress(int progress) {
progressBar.setProgress(progress);
}
}
parser.getBrands() and parser.getRegions() are loading data from the web.
I want to do something like this:
boolean repeatRequest = true;
while (repeatRequest) {
try {
brands = parser.getBrands();
repeatRequest = false;
} catch (IOException e) {
Log.e(e.getMessage());
repeatRequest = showErrorDialog();
}
}
But I didn't manage to do so because this code executes in background thread, but dialog should be shown in UI thread.
I believe that it should be standard approach of doing so, but didn't manage to find it.
Any ides how can I implement this?
The best way is to use AsyncTask.
private class LoadDataTask extends AsyncTask<Void, Integer, Object> {
private ProgressDialog mProgress;
protected Object doInBackground(Void... params) {
// This method runs in background
Object result = null;
try {
result = parser.parse();
} catch (Exception e) {
result = e.getMessage();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
// This method runs in UI thread
mProgress.setProgress(progress[0]);
}
protected void onPreExecute() {
// This method runs in UI thread
mProgress = new ProgressDialog(context);
mProgress.show();
}
protected void onPostExecute(Object result) {
// This method runs in UI thread
mProgress.dismiss();
if (result instance of String) {
// Here you can launch AlertDialog with error message and proposal to retry
showErrorDialog((String) result);
} else {
populateData(result);
}
}
}

Categories

Resources