In my application some data is there which is wrapped into an object.
I am sending this object to the server. Everything work correctly.
Here I want to show progress bar when the data is loading to the server.
For this I am using this code:
ProgressThread progThread;
ProgressDialog progDialog;
int typeBar;
int delay = 40;
int maxBarValue = 200;
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case 1:
progDialog = new ProgressDialog(this);
progDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progDialog.setMax(maxBarValue);
progDialog.setMessage("Data uploading to the Server..");
progThread = new ProgressThread(handler);
progThread.start();
return progDialog;
default:
return null;
}
}
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
// Get the current value of the variable total from the message data
// and update the progress bar.
int total = msg.getData().getInt("total");
progDialog.setProgress(total);
if (total <= 0) {
dismissDialog(typeBar);
progThread.setState(ProgressThread.DONE);
}
}
};
private class ProgressThread extends Thread {
final static int DONE = 0;
final static int RUNNING = 1;
Handler mHandler;
int mState;
int total;
ProgressThread(Handler h) {
mHandler = h;
}
#Override
public void run() {
mState = RUNNING;
total = maxBarValue;
while (mState == RUNNING) {
connectServerClass.saveOnServer(Object);
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total--; // Count down
}
}
public void setState(int state) {
mState = state;
}
}
When user click on button then:
typeBar = 1;
showDialog(typeBar);
connectServerClass.saveOnServer(Object)
by the above line I am sending object to the server. Actually I am sending data to the other class which is connectServerClass and this class send object to the server.
but this code not work correctly. This code connect to the server lots of time.
I use the following Code :
private class Uploader extends AsyncTask<Void, String, Integer>
{
private List<File> files;
private boolean canceled;
private int uploaded;
private Account account;
private ProgressDialog uploadSeekBar;
public Uploader(Account a, List<File> files)
{
this.account = a;
this.files = files;
}
#Override
protected void onPreExecute()
{
uploadSeekBar.setMax(files.size());
uploadSeekBar.setProgress(0);
uploadSeekBar.setVisibility(View.VISIBLE); //Error: the method setVisibility is undefined
}
#Override
protected void onPostExecute(Integer result)
{
uploadSeekBar.setVisibility(View.INVISIBLE);
Toast.makeText(Upload.this, result + " files uploaded", // Error: Upload cannot be resolved to a type
Toast.LENGTH_LONG).show();
}
#Override
protected void onCancelled()
{
// XXX need a way to actually cancel the last upload
Toast.makeText(Upload.this, "canceling upload", Toast.LENGTH_LONG)
.show();
this.canceled = true;
uploadSeekBar.setVisibility(View.INVISIBLE);
}
#Override
protected Integer doInBackground(Void... voids)
{
uploaded = 0;
try
{
Iterator<File> it = this.files.iterator();
while (!canceled && it.hasNext())
{
File file = it.next();
it.remove();
String msg = "";
try
{
if (debugMode) // what is this debugMode
{
//Put your uploading code here.
msg = ("fake uploading " + file);
Thread.sleep(3000);
} else
{
msg = ("uploading: " + file);
controller.uploadFile(file, this.account); //Error: controller cannot be resolved
}
uploaded++;
publishProgress(msg);
} catch (IOException e)
{
controller.te("error uploading file: " + file);
controller.te("error uploading file: " + e);
} catch (InterruptedException e)
{
}
}
} catch (Exception e)
{
publishProgress("error uploading: " + e);
}
return uploaded;
}
#Override
protected void onProgressUpdate(String... strings)
{
uploadSeekBar.setProgress(uploaded);
updateUploadMessage(files.size());
Toast.makeText(Upload.this, strings[0], Toast.LENGTH_LONG).show(); //Error: The method updateUploadMessage(int) is undefined for the type FirstActivity.Uploader
}
}
But I facing some error which I mention as comment in the right side of that line. Please suggest me.
I will strongly recommend you to Use AsyncTask.
Below Code snippet will help you on How your AsyncTask should look like.
package org.sample;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import android.accounts.Account;
import android.os.AsyncTask;
import android.view.View;
import android.widget.Toast;
private class Uploader extends AsyncTask<Void, String, Integer>
{
private List<File> files;
private boolean canceled;
private int uploaded;
public Uploader(Account a, List<File> files)
{
this.account = a;
this.files = files;
}
#Override
protected void onPreExecute()
{
uploadSeekBar.setMax(files.size());
uploadSeekBar.setProgress(0);
uploadSeekBar.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Integer result)
{
uploadSeekBar.setVisibility(View.INVISIBLE);
Toast.makeText(Upload.this, result + " files uploaded",
Toast.LENGTH_LONG).show();
}
#Override
protected void onCancelled()
{
// XXX need a way to actually cancel the last upload
Toast.makeText(Upload.this, "canceling upload", Toast.LENGTH_LONG)
.show();
this.canceled = true;
uploadSeekBar.setVisibility(View.INVISIBLE);
}
#Override
protected Integer doInBackground(Void... voids)
{
uploaded = 0;
try
{
Iterator<File> it = this.files.iterator();
while (!canceled && it.hasNext())
{
File file = it.next();
it.remove();
String msg = "";
try
{
if (debugMode)
{
//Put your uploading code here.
msg = ("fake uploading " + file);
Thread.sleep(3000);
} else
{
msg = ("uploading: " + file);
controller.uploadFile(file, this.account);
}
uploaded++;
publishProgress(msg);
} catch (IOException e)
{
controller.te("error uploading file: " + file);
controller.te("error uploading file: " + e);
} catch (InterruptedException e)
{
}
}
} catch (Exception e)
{
publishProgress("error uploading: " + e);
}
return uploaded;
}
#Override
protected void onProgressUpdate(String... strings)
{
uploadSeekBar.setProgress(uploaded);
updateUploadMessage(files.size());
Toast.makeText(Upload.this, strings[0], Toast.LENGTH_LONG).show();
}
}
Related
I have integrated PAYTM ALL IN ONE SDK to my android app. It is working fine in debug mode but in release mode it is throwing exception. There is small thing that i am missing because its working absolutely fine in debug mode but changing it to release it is throwing exception.
Deposit Activity
public class DepositActivity extends AppCompatActivity {
private TextView mmbalance, mgateway, mtext_imp3;
private DatabaseReference mmRef, mmtRef, mmbRef, mmcRef, mmcrRef, mmiRef, mmdRef, mmopRef, mmdbRef, yesRefty3, mmRefuc;
DatabaseReference databaseReference, tdatabaseReference, yesRef, mmRefu, mmRefr;
private ImageView mdep_back;
public EditText mtodepo;
private ConstraintLayout mcons_imp3;
private String TAG ="DepositActivity";
private ProgressBar progressBar;
private String midString="MY MERCHANT ID I HAVE HIDED", txnAmountString="", orderIdString="", txnTokenString="";
private Integer ActivityRequestCode = 2;
public CardView depobtn, depobtn2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_deposit);
mtodepo=(EditText)findViewById(R.id.amountdepo);
depobtn=(CardView) findViewById(R.id.depositbtn);
depobtn2=(CardView) findViewById(R.id.depositbtn2);
String mydep = mtodepo.getText().toString();
mmbalance = (TextView) findViewById(R.id.dbalance);
mgateway = (TextView) findViewById(R.id.gateway);
mcons_imp3 = findViewById(R.id.cons_imp3);
mtext_imp3 = findViewById(R.id.text_imp3);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("ddMMyyyy");
String date = df.format(c.getTime());
Random rand = new Random();
int min =1000, max= 9999;
// nextInt as provided by Random is exclusive of the top value so you need to add 1
int randomNum = rand.nextInt((max - min) + 1) + min;
orderIdString = date+String.valueOf(randomNum);
depobtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
txnAmountString = mtodepo.getText().toString();
String errors = "";
if(orderIdString.equalsIgnoreCase("")){
errors ="Enter valid Order ID here\n";
Toast.makeText(DepositActivity.this, errors, Toast.LENGTH_SHORT).show();
}else
if(txnAmountString.equalsIgnoreCase("")){
errors ="Enter valid Amount here\n";
Toast.makeText(DepositActivity.this, errors, Toast.LENGTH_SHORT).show();
}else{
int amountff = Math.round(Float.parseFloat(txnAmountString));
if (amountff <= 50000) {
if (amountff > 99) {
getToken();
} else {
Toast.makeText(DepositActivity.this, "Minimum amount > 100", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(DepositActivity.this, "Amount must be smaller than 50000", Toast.LENGTH_SHORT).show();
}
}
}
});
}
private void getToken(){
Log.e(TAG, " get token start");
progressBar.setVisibility(View.VISIBLE);
ServiceWrapper serviceWrapper = new ServiceWrapper(null);
Call<Token_Res> call = serviceWrapper.getTokenCall("12345", midString, orderIdString, txnAmountString);
call.enqueue(new Callback<Token_Res>() {
#Override
public void onResponse(Call<Token_Res> call, Response<Token_Res> response) {
Log.e(TAG, " respo "+ response.isSuccessful() );
progressBar.setVisibility(View.GONE);
try {
if (response.isSuccessful() && response.body()!=null){
if (response.body().getBody().getTxnToken()!="") {
Log.e(TAG, " transaction token : "+response.body().getBody().getTxnToken());
startPaytmPayment(response.body().getBody().getTxnToken());
}else {
Log.e(TAG, " Token status false");
}
}
}catch (Exception e){
Log.e(TAG, " error in Token Res "+e.toString());
}
}
#Override
public void onFailure(Call<Token_Res> call, Throwable t) {
progressBar.setVisibility(View.GONE);
Log.e(TAG, " response error "+t.toString());
}
});
}
public void startPaytmPayment (String token){
txnTokenString = token;
// for test mode use it
// String host = "https://securegw-stage.paytm.in/";
// for production mode use it
String host = "https://securegw.paytm.in/";
String orderDetails = "MID: " + midString + ", OrderId: " + orderIdString + ", TxnToken: " + txnTokenString
+ ", Amount: " + txnAmountString;
//Log.e(TAG, "order details "+ orderDetails);
String callBackUrl = host + "theia/paytmCallback?ORDER_ID="+orderIdString;
Log.e(TAG, " callback URL "+callBackUrl);
PaytmOrder paytmOrder = new PaytmOrder(orderIdString, midString, txnTokenString, txnAmountString, callBackUrl);
TransactionManager transactionManager = new TransactionManager(paytmOrder, new PaytmPaymentTransactionCallback(){
#Override
public void onTransactionResponse(Bundle bundle) {
}
#Override
public void networkNotAvailable() {
Log.e(TAG, "network not available ");
}
#Override
public void onErrorProceed(String s) {
Log.e(TAG, " onErrorProcess "+s.toString());
}
#Override
public void clientAuthenticationFailed(String s) {
Log.e(TAG, "Clientauth "+s);
}
#Override
public void someUIErrorOccurred(String s) {
Log.e(TAG, " UI error "+s);
}
#Override
public void onErrorLoadingWebPage(int i, String s, String s1) {
Log.e(TAG, " error loading web "+s+"--"+s1);
}
#Override
public void onBackPressedCancelTransaction() {
Log.e(TAG, "backPress ");
}
#Override
public void onTransactionCancel(String s, Bundle bundle) {
Log.e(TAG, " transaction cancel "+s);
}
});
transactionManager.setShowPaymentUrl(host + "theia/api/v1/showPaymentPage");
transactionManager.startTransaction(this, ActivityRequestCode);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.e(TAG ," result code "+resultCode);
// -1 means successful // 0 means failed
// one error is - nativeSdkForMerchantMessage : networkError
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ActivityRequestCode && data != null) {
Bundle bundle = data.getExtras();
if (bundle != null) {
for (String key : bundle.keySet()) {
Log.e(TAG, key + " : " + (bundle.get(key) != null ? bundle.get(key) : "NULL"));
}
}
/*Log.e(TAG, " data "+ data.getStringExtra("nativeSdkForMerchantMessage"));
Log.e(TAG, " data response - "+data.getStringExtra("response"));*/
Toast.makeText(DepositActivity.this, "Payment Cancelled", Toast.LENGTH_LONG).show();
/*
data response - {"BANKNAME":"WALLET","BANKTXNID":"1395841115",
"CHECKSUMHASH":"7jRCFIk6eRmrep+IhnmQrlrL43KSCSXrmMP5pH0hekXaaxjt3MEgd1N9mLtWyu4VwpWexHOILCTAhybOo5EVDmAEV33rg2VAS/p0PXdk\u003d",
"CURRENCY":"INR","GATEWAYNAME":"WALLET","MID":"EAcR4116","ORDERID":"100620202152",
"PAYMENTMODE":"PPI","RESPCODE":"01","RESPMSG":"Txn Success","STATUS":"TXN_SUCCESS",
"TXNAMOUNT":"2.00","TXNDATE":"2020-06-10 16:57:45.0","TXNID":"202006101112128001101683631290118"}
*/
/*Toast.makeText(this, data.getStringExtra("nativeSdkForMerchantMessage")
+ data.getStringExtra("response"), Toast.LENGTH_SHORT).show();*/
}else{
/*Log.e(TAG, " payment failed");*/
Toast.makeText(DepositActivity.this, "Payment Failed", Toast.LENGTH_LONG).show();
}
}
public static boolean isConnectionAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()
&& netInfo.isConnectedOrConnecting()
&& netInfo.isAvailable()) {
return true;
}
}
return false;
}
}
ServiceWrapper
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ServiceWrapper {
private ServiceInterface mServiceInterface;
public ServiceWrapper(Interceptor mInterceptorheader) {
mServiceInterface = getRetrofit(mInterceptorheader).create(ServiceInterface.class);
}
public Retrofit getRetrofit(Interceptor mInterceptorheader) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient mOkHttpClient = null;
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(1201, TimeUnit.SECONDS);
builder.readTimeout(901, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
// HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(loggingInterceptor);
}
mOkHttpClient = builder.build();
Gson gson = new GsonBuilder().setLenient().create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://mywebsitei_i_have_hided.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.client(mOkHttpClient)
.build();
return retrofit;
}
public Call<Token_Res> getTokenCall(String code, String mid, String order_id, String amount) {
return mServiceInterface.generateTokenCall(
convertPlainString(code), convertPlainString(mid), convertPlainString(order_id)
, convertPlainString(amount));
}
// convert aa param into plain text
public RequestBody convertPlainString(String data){
RequestBody plainString = RequestBody.create(MediaType.parse("text/plain"), data);
return plainString;
}
}
This is because of the new R8 code obfuscation. You need to disable it from your project by adding below line to the gradle.properties file -
android.enableR8=false
Also you need to add below lines to your proguard rules file -
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
#com.google.gson.annotations.SerializedName <fields>;
}
I'd like to get the string value output from AsyncTask. And store it into a variable on my main thread. How can I do so?
I tried to do store = new ReceiveData().execute().get() however it throws an execution exception error. But anyway, my question is not about the execution exception error. I just need a way to get the string out, please help!
Here is my activity code:
public class MainActivity extends AppCompatActivity { //MAIN ACTIVITIES (REMOTE)
double multiplier;
int seekbarvalue, finallumens;
#Override
protected void onCreate(Bundle savedInstanceState) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); //On orientation change socket will disconnect...
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Toast.makeText(MainActivity.this, LoginActivity.SERVER_IP, Toast.LENGTH_LONG).show();
//================START AFTER DEFAULT ON CREATE=================
SeekBar seekbarbrightness = (SeekBar) findViewById(R.id.seekbarbrightness);
final TextView tblumens, tbvolts, tbamps;
tblumens = (TextView) findViewById(R.id.tblumens);
seekbarvalue = seekbarbrightness.getProgress();
multiplier = (double) seekbarvalue / 100;
finallumens = (int) (multiplier * LoginActivity.enterlumens);
tblumens.setText(String.valueOf(finallumens) + " Lumens");
tbvolts = (TextView) findViewById(R.id.tbvolts);
tbamps = (TextView) findViewById(R.id.tbamps);
seekbarbrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekbarbrightness, int progress, boolean b) {
if (b == true) {
seekbarvalue = seekbarbrightness.getProgress();
multiplier = (double) seekbarvalue / 100;
finallumens = (int) (multiplier * LoginActivity.enterlumens);
tblumens.setText(String.valueOf(finallumens) + " Lumens");
if (LoginActivity.getSocket() != null) {
try {
LoginActivity.getSocket().getOutputStream().write(String.valueOf(multiplier).getBytes());
new ReceiveData().execute();
//infinite loop here to keep receiving volts and amperes.
//Do a split and assign value to volt and amp
//String[] strrecv= store.split("|");
//String volts = strrecv[0];
//String amps = strrecv[1];
//tbvolts.setText("Voltage: " + volts + " V");
//tbamps.setText("Amperes:" + amps + " A");
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "NOT connected To Socket, please disconnect and reconnect!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
And in my Asynctask I am doing this.
class ReceiveData extends AsyncTask<Void, Void, String> {
String str;
protected String doInBackground(Void... args) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(LoginActivity.getSocket().getInputStream()));
str = in.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
String str = "fail";
return str;
}
}
protected void onPostExecute(String str) {
//super.onPostExecute(str);
}
}
The purpose of AsyncTask is to perform asynchronous task in a separate thread to free the main thread and avoid UX issues. For your purpose, I suggest transferring all of the work inside your try block inside the AsyncTask and update the UI after execution.
Something like this
In MainThread
new ReceiveData().execute();
In AsyncTask
class ReceiveData extends AsyncTask<Void, Void, Boolean> {
String volts;
String amps;
protected Boolean doInBackground(Void... args) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(LoginActivity.getSocket().getInputStream()));
str = in.readLine();
String[] strrecv= store.split("|");
volts = strrecv[0];
amps = strrecv[1];
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
protected void onPostExecute(Boolean result) {
if (result) {
tbvolts.setText("Voltage: " + volts + " V");
tbamps.setText("Amperes:" + amps + " A");
}
}
}
Note that this only works if your AsyncTask is defined inside your Activity. If not, you need to create an interface from the AsyncTask and implement it in your activity and activate it onPostExecute
I have an activity with buttons on it. One of the buttons when clicked calls a static method from another class. This method then calls a series of AsyncTasks that are daisy-chained. It is like in the OnPostExecute of the first task, I will call a new AsyncTask, then in the OnPostExecute of the second AsyncTask, I again will call a new AsyncTask. This goes on for about 15 levels. I need to show a progress dialog while these tasks are running and show the appropriate status (percentage). I did this by creating a new ProgressDialog on the OnPreExecute of the first AsyncTask. My problem is when the device is rotated or when it goes to sleep, then the ProgressDialog disappears and an exception is raised when I call dismiss() from the final OnPostExecute.
Here's my code (toned down to 2 levels of Asynctasks)
Activity:
private class OnButtonMenuClick implements OnClickListener {
#Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.textViewDownload:
downloadReferenceFiles();
break;
case R.id.textViewProductNotes:
showProductNotes();
break;
case R.id.textViewCustomerNotes:
showCustomerNotes();
break;
case R.id.textViewAdjustOrders:
orderAdjustments();
break;
case R.id.textViewUploadOrders:
uploadDataToServer();
break;
case R.id.textViewToolsReconciliationIcon:
cashCount();
break;
case R.id.textViewToolsExpensesIcon:
expensesEntry();
break;
case R.id.textViewSalesSummaryIcon:
showSalesSummary();
break;
case R.id.textViewInventoryIcon:
showInventory();
break;
case R.id.textViewInventoryByVolumeIcon:
showInventoryByVolume();
break;
}
}
}
public void downloadReferenceFiles() {
ReferenceFilesDownloader.downloadData(ToolsActivity.this, true);
}
Reference files downloader class (separate file)
import java.util.ArrayList;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
public class ReferenceFilesDownloader {
private static ProgressDialog progress;
private static Context context;
private static boolean includeInventory;
public static void downloadData(Context ctx) {
context = ctx;
includeInventory = false;
new AsyncCheckServerDate().execute();
}
public static void setContext(Context ctx) {
context = ctx;
}
public static void downloadData(Context ctx, boolean inventory) {
context = ctx;
includeInventory = inventory;
new AsyncCheckServerDate().execute();
}
public static String buildProgress(int value, int max) {
int percent = (int)(((double)value / (double)max) * 100);
String current = value + " of " + max + " (" + percent + "% completed)";
return current;
}
public static void createProgress() {
if (progress == null) {
progress = new ProgressDialog(context);
progress.setIndeterminate(false);
progress.setCancelable(false);
progress.setCanceledOnTouchOutside(false);
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
}
if (!progress.isShowing()) {
progress.show();
}
}
protected static class AsyncCheckServerDate extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String today = "";
RestAPI api = new RestAPI();
try {
JSONObject jsonObj = api.GetDateToday();
JSONParser parser = new JSONParser();
today = parser.parseDateToday(jsonObj);
}
catch (NullPointerException e) {
}
catch (Exception e) {
}
return today;
}
#Override
protected void onPreExecute() {
//progress.show(manager, tag)
/*progress = new ProgressDialog(context);
progress.setMessage("Verifying server date. Please wait...");
progress.setCancelable(false);
progress.setCanceledOnTouchOutside(false);
progress.show();*/
}
#Override
protected void onPostExecute(String result) {
if (result.equals(StaticHolder.today())) {
new AsyncCustomers().execute();
}
else {
AppMessages.showMessage(context,
"The date on this device is not synchronized with the server. Please adjust it to the correct date.",
"Date Out of Sync",
AppMessages.MESSAGE_INFO,
null);
}
}
}
protected static class AsyncCustomers extends AsyncTask<Void, String, Void> {
#Override
protected Void doInBackground(Void... params) {
ArrayList<Customer> customers = null;
RestAPI api = new RestAPI();
try {
JSONObject jsonObj = api.GetReferenceFiles((byte)4);
JSONParser parser = new JSONParser();
customers = parser.parseCustomer(jsonObj);
CustomersTable.importData(context, customers, this);
}
catch (NullPointerException e) {
}
catch (Exception e) {
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
createProgress();
progress.setTitle("Downloading Customer Information");
}
#Override
protected void onPostExecute(Void result) {
new AsyncItems().execute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
progress.setMessage(values[0]);
}
public void showProgress(int value, int max) {
publishProgress(buildProgress(value, max));
}
}
protected static class AsyncItems extends AsyncTask<Void, String, Void> {
#Override
protected Void doInBackground(Void... params) {
ArrayList<Item> items = null;
RestAPI api = new RestAPI();
try {
JSONObject jsonObj = api.GetReferenceFiles((byte)6);
JSONParser parser = new JSONParser();
items = parser.parseItem(jsonObj);
ItemsTable.importData(context, items, this);
}
catch (NullPointerException e) {
}
catch (Exception e) {
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
createProgress();
progress.setTitle("Downloading Items Master File");
}
#Override
protected void onPostExecute(Void result) {
if (progress != null) {
progress.dismis();
}
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
progress.setMessage(values[0]);
}
public void showProgress(int value, int max) {
publishProgress(buildProgress(value, max));
}
}
}
CustomerTable class (separate file)
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
public class CustomersTable {
public static void importData(Context context, ArrayList<Customer> customers, ReferenceFilesDownloader.AsyncCustomers async) {
ADIDBContext dbContext = new ADIDBContext(context);
String query = "DELETE FROM Customers";
dbContext.execSQL(query);
try {
dbContext.beginTransaction();
int row = 0;
for (Customer customer : customers) {
ContentValues values = new ContentValues();
async.showProgress(++row, customers.size());
values.put("CustomerId", customer.customerId);
values.put("LastName", customer.lastName);
values.put("FirstName", customer.firstName);
values.put("MiddleName", customer.middleName);
values.put("Address1", customer.address1);
values.put("Address2", customer.address2);
values.put("ProvinceId", customer.provinceId);
values.put("CityId", customer.cityId);
values.put("BarangayId", customer.barangayId);
dbContext.getDatabase().insert("Customers", null, values);
}
dbContext.setTransactionSuccessful();
}
catch (Exception ex) {
}
dbContext.endTransaction();
dbContext.close();
}
}
ItemTable class (separate file)
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
public class ItemsTable {
public static void importData(Context context, ArrayList<Item> items, ReferenceFilesDownloader.AsyncItems async) {
ADIDBContext dbContext = new ADIDBContext(context);
String query = "DELETE FROM Items";
dbContext.execSQL(query);
try {
dbContext.beginTransaction();
int row = 0;
for (Item item : items) {
ContentValues values = new ContentValues();
async.showProgress(++row, items.size());
values.put("Barcode", item.barcode);
values.put("ItemId", item.itemId);
values.put("ItemDesc", item.itemDesc);
values.put("UnitId", item.unitId);
values.put("CompanyId", item.companyId);
values.put("UnitDescription", item.unitDescription);
values.put("UnitConversion", item.unitConversion);
values.put("Cost", item.cost);
values.put("SellingPrice1", item.sellingPrice1);
values.put("SellingPrice2", item.sellingPrice2);
values.put("SellingPrice3", item.sellingPrice3);
values.put("SellingPrice4", item.sellingPrice4);
values.put("SellingPrice5", item.sellingPrice5);
values.put("PiecePrice1", item.piecePrice1);
values.put("PiecePrice2", item.piecePrice2);
values.put("PiecePrice3", item.piecePrice3);
values.put("PiecePrice4", item.piecePrice4);
values.put("PiecePrice5", item.piecePrice5);
values.put("Taxable", item.taxable);
dbContext.getDatabase().insert("Items", null, values);
}
dbContext.setTransactionSuccessful();
}
catch (Exception ex) {
}
dbContext.endTransaction();
dbContext.close();
}
}
My problem is when the device is rotated or when it goes to sleep,
then the ProgressDialog disappears and an exception is raised when I
call dismiss() from the final OnPostExecute.
If I'm not wrong you are trying to handle the orientation change that causes the exception.
SOLUTION 1: Prevent the Activity from being recreated
Add this attribute into your activity manifest,
android:configChanges="keyboardHidden|orientation"
It hand off to your onConfigurationChanged() method and does nothing other than re-measuring the layout. That should solve the problem during rotation.
SOLUTION 2: Lock the screen orientation
Define a fixed orientation for your activity and that should solve the issue.
<activity
android:screenOrientation="portrait"
... />
SOLUTION 3: Temporarily lock the screen in onPreExecute(), and unlock it in onPostExecute()
This is a tricky way to handle orientation. Simply lock the orientation when the AsyncTask is about to start then unlock the orientation when the Task has been finished. See the example,
#Override
public void onTaskStarted() {
lockScreenOrientation();
progressDialog = ProgressDialog.show(CopyOfCopyOfMainActivity.this, "Loading", "Please wait a moment!");
}
#Override
public void onTaskFinished(String result) {
if (progressDialog != null) {
progressDialog.dismiss();
}
unlockScreenOrientation();
}
private void lockScreenOrientation() {
int currentOrientation = getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
private void unlockScreenOrientation() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
I've builded Updates class for my Android app. It works fine except Download inner AsyncTask-class.
I wanted to display progress dialog in LoadingActivity while file is downloading.
Firstly, I invoke the Updates class in onCreate method. As a parameter I send activity context. Then in Updates class constructor I invoke Check inner class (AsyncTask), which parse JSON response from URL (works properly) and invoke Download (next Updates inner class) and here it's problem.
When I'm trying to create ProgressDialog object, the compiler throws:
04-01 02:53:56.864 24393-24425/pl.com.mpkostrowiec.schedule E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:838)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:197)
at android.os.Handler.<init>(Handler.java:111)
at android.app.Dialog.<init>(Dialog.java:107)
at android.app.AlertDialog.<init>(AlertDialog.java:114)
at android.app.AlertDialog.<init>(AlertDialog.java:98)
at android.app.ProgressDialog.<init>(ProgressDialog.java:77)
at pl.com.mpkostrowiec.schedule.DownloadAsync.<init>(DownloadAsync.java:30)
at pl.com.mpkostrowiec.schedule.Updates$Check.doInBackground(Updates.java:128)
at pl.com.mpkostrowiec.schedule.Updates$Check.doInBackground(Updates.java:74)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:838)
I thought that ProgressDialog constructor can't access context variable from Updates class, so I tried to send it as parameter, but it doesn't resolve the problem.
LoadingActivity class:
package pl.com.mpkostrowiec.schedule;
import ...
public class LoadingActivity extends Activity {
private final Preferences preferences = new Preferences(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading);
preferences.savePreference("Preferences", "firstRun", "1");
// Check if first run
if (preferences.readPreference("Preferences", "firstRun").equals("0")) {
System.out.println("****************** Not first run");
} else {
// Create directory
File dir = this.getDir("Versions", MODE_PRIVATE);
new Updates(this);
}
}
}
Update class:
package pl.com.mpkostrowiec.schedule;
import ...
interface AfterExecuteListener {
public void afterDownload(String[] versionData, int type);
}
public class Updates implements AfterExecuteListener{
private static VersionsTable versionsTable;
private Context context;
public static Boolean status_current = false;
public static Boolean status_new = false;
private final int TYPE_CURRENT = 0;
private final int TYPE_NEW = 1;
private static final String URL = "http://www.mpkostrowiec.com.pl/preview/";
private static final String GET_VERSIONS = "includes/android/versions.php";
private static final String RESOURCES = "resources/android/versions/";
private static final String EXTENSION = ".db";
public Updates(Context context) {
this.context = context;
versionsTable = new VersionsTable(this.context);
new Check(TYPE_CURRENT).execute();
}
public final void afterDownload(String[] versionData, int type) {
// Add version data to DB
versionsTable.open();
versionsTable.add(versionData);
versionsTable.close();
// Set status
if (type == TYPE_CURRENT) {
System.out.println("****************** Downloaded: " + type);
status_current = true;
} else if (type == TYPE_NEW) {
System.out.println("****************** Downloaded: " + type);
status_new = true;
}
Schedule();
}
private void Schedule() {
if (status_current) {
if (status_new) {
System.out.println("****************** SUCCESS");
} else {
new Check(TYPE_NEW).execute();
}
}
}
private class Check extends AsyncTask<String, Integer, String> {
public AfterExecuteListener mListener;
private int type;
public Check(int type) {
this.type = type;
}
#Override
protected String doInBackground(String... Url) {
String[] typeStr = {"current", "new"};
// Get versions form URL
JSONObject json = null;
String versions = null;
HttpResponse response;
HttpClient myClient = new DefaultHttpClient();
HttpPost myConnection = new HttpPost(URL + GET_VERSIONS);
try {
response = myClient.execute(myConnection);
versions = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try{
JSONObject jObject = new JSONObject(versions);
json = jObject.getJSONObject(typeStr[type]);
if (json.length() > 1) {
String[] versionData = {json.getString("id"),
json.getString("name"),
json.getString("expDate")};
versionsTable.open();
Boolean idExist = versionsTable.check(versionData[0]);
versionsTable.close();
// Check version
if (!idExist) {
// Start downloading
Download download = new Download(versionData, type);
download.setListener(Updates.this);
download.execute(URL + RESOURCES + versionData[0] + EXTENSION);
}
} else {
// If array contains only false field then do not update
if (type == TYPE_CURRENT) {
Updates.status_current = true;
} else if (type == TYPE_NEW) {
Updates.status_new = true;
}
Schedule();
}
} catch ( JSONException e) {
e.printStackTrace();
}
return null;
}
}
private class Download extends AsyncTask<String, Integer, String> {
public ProgressDialog mProgressDialog;
public AfterExecuteListener mListener;
private String[] versionData;
private int type;
public Download(String[] versionData, int type) {
this.versionData = versionData;
this.type = type;
// Create progress dialog
mProgressDialog = new ProgressDialog(context);
// Set your progress dialog Title
mProgressDialog.setTitle("Updating...");
// Set your progress dialog Message
mProgressDialog.setMessage("Update in progress. Please wait.");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// Show progress dialog
mProgressDialog.show();
}
#Override
protected String doInBackground(String... Url) {
try {
java.net.URL url = new URL(Url[0]);
URLConnection connection = url.openConnection();
connection.connect();
// Detect the file lenghth
int fileLength = connection.getContentLength();
// Locate storage location
String filepath = context.getApplicationInfo().dataDir + "/Versions";
// Download the file
InputStream input = new BufferedInputStream(url.openStream());
// Save the downloaded file
OutputStream output = new FileOutputStream(filepath + "/" + versionData[0] + ".db");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// Publish the progress
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
// Close connection
output.flush();
output.close();
input.close();
} catch (Exception e) {
// Error Log
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// Update the progress dialog
mProgressDialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
// Dismiss the progress dialog
mProgressDialog.dismiss();
mListener.afterDownload(versionData, type);
}
private void setListener(AfterExecuteListener listener) {
mListener = listener;
}
}
}
I have an activity that creates an AsyncTask to test an ftp connection via an FTPHelper class. The Activity shows a Toast with the boolean status of the connection, either success or fail. How can I show the exact replycode or replystring in the Activity?
Activity:
TestConnection task = new TestConnection(NewSite.this,
_address, _user, _pass, p, new testConnInterface() {
#Override
public void testConnection(boolean result) {
if (result == true) {
Toast.makeText(NewSite.this,
"Connection Succesful",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(NewSite.this,
"Connection Failed:" + result,
Toast.LENGTH_LONG).show();
}
}
});
task.execute();
TestConection.java
public class TestConnection extends AsyncTask<Void, Void, Boolean> {
private Context mContext;
private testConnInterface mListener;
private FTPHelper ftpHelper = new FTPHelper();
private String _address;
private String _user;
private String _pass;
private int _port;
ProgressDialog progressDialog;
public interface testConnInterface {
public void testConnection(boolean result);
}
public TestConnection(Context context, String address, String user,
String pass, int port, testConnInterface mListener) {
mContext = context;
_address = address;
_user = user;
_pass = pass;
_port = port;
this.mListener = mListener;
}
// declare other objects as per your need
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(mContext, "Please wait",
"Attempting to connect", true);
// do initialization of required objects objects here
};
#Override
protected Boolean doInBackground(Void... params) {
boolean status = ftpHelper.ftpConnect(_address, _user, _pass, _port);
return status;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (mListener != null)
mListener.testConnection(result);
progressDialog.dismiss();
};
}
FTPHelper.java
public class FTPHelper {
public static FTPClient mFTPClient = null;
public FTPHelper() {
// TODO Auto-generated constructor stub
}
public boolean ftpConnect(String host, String username, String password,
int port) {
try {
mFTPClient = new FTPClient();
// connecting to the host
mFTPClient.connect(host, port);
// now check the reply code, if positive mean connection success
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
// login using username & password
boolean status = mFTPClient.login(username, password);
/*
* Set File Transfer Mode
*
* To avoid corruption issue you must specified a correct
* transfer mode, such as ASCII_FILE_TYPE, BINARY_FILE_TYPE,
* EBCDIC_FILE_TYPE .etc. Here, I use BINARY_FILE_TYPE for
* transferring text, image, and compressed files.
*/
mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
mFTPClient.enterLocalPassiveMode();
showServerReply(mFTPClient);
return status;
}
} catch (Exception e) {
// Log.d(TAG, "Error: could not connect to host " + host );
}
return false;
}
public boolean ftpDisconnect() {
try {
mFTPClient.logout();
mFTPClient.disconnect();
return true;
} catch (Exception e) {
// Log.d(TAG,
// "Error occurred while disconnecting from ftp server.");
}
return false;
}
public String ftpGetCurrentWorkingDirectory() {
try {
String workingDir = mFTPClient.printWorkingDirectory();
return workingDir;
} catch (Exception e) {
Log.i("Error working dir", e.toString());
}
return null;
}
Basically I want to know how to return the getReplyCode() to my Activity.