Działanie w tle progress bar

0

Hej,
Mam takie pytanie chodzi ze mam taką aktywność w której jest progress bar i po upływie jakiegoś czasu odświeża się podany qr code. Problem jest taki ze jak wychodzę z aplikacji i wracam to tej samej aktywności odliczanie się stopuje cały progress bar jest pełen po jakeiś chwili następuje odliczanie

public class CardDetailsActivity extends AppCompatActivity {
    private static final String TIME = "Time ";
    private String cardNameEncrypt, intervalTotpEncrypt, path3Encrypt;


    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(newBase);
    }

    private ProgressBar progressBar;
    private TextView secondTimeTextView;
    private int interval, currentInterval;
    protected String cardName, intervalTotp, path3, getCode, uuidDevice, otpString, generateNewString, generateQrString, OtpString, NewXorString;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_card_details);

        Typeface custom_fonts = Typeface.createFromAsset(getAssets(), "fonts/OpenSans-Regular.ttf");
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);


        Default app = (Default) getApplicationContext();
        uuidDevice = app.getUuidString();

        if (savedInstanceState != null) {
            currentInterval = savedInstanceState.getInt(TIME);
            progressBar.setProgress(currentInterval);
        }

        Base32 code = new Base32();
        byte secret[] = code.decode(otpString);

        try {
            getCode = OtpAlgorithm.generateTotp(secret, intervalTotpEncrypt);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

        OtpString = path3Encrypt + getCode;
        generateQrString = Cryptography.xorHex(OtpString);
        interval = Integer.parseInt(intervalTotpEncrypt);

        TextView titleTextView = (TextView) findViewById(R.id.toolbar_title);
        titleTextView.setText(cardNameEncrypt);

        TextView subtitleTextView = (TextView) findViewById(R.id.subtitle_text);
        TextView second_text = (TextView) findViewById(R.id.second_text);
        TextView instantTextView = (TextView) findViewById(R.id.instant_text);
        instantTextView.setTypeface(custom_fonts);
        titleTextView.setTypeface(custom_fonts);

        TextView generationCardTextView = (TextView) findViewById(R.id.generationCardText);
        generationCardTextView.setTypeface(custom_fonts);

        secondTimeTextView = (TextView) findViewById(R.id.secondTimeTextView);
        secondTimeTextView.setTypeface(custom_fonts);

        TextView dotTextView = (TextView) findViewById(R.id.dotTextView);
        dotTextView.setTypeface(custom_fonts);
        subtitleTextView.setTypeface(custom_fonts);
        second_text.setTypeface(custom_fonts);
        setSupportActionBar(toolbar);

        UpdateQrCodeString(generateQrString);
        new UpdateQrCode().execute();


    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.card:
                Intent intent = new Intent(this, MainActivity.class);
                startActivity(intent);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.card, menu);
        return super.onCreateOptionsMenu(menu);
    }


    private class UpdateQrCode extends AsyncTask<Void, Integer, Integer> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressBar.setMax(interval);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            progressBar.setProgress(values[0]);
            currentInterval = values[0];
            secondTimeTextView.setText(String.valueOf(values[0]));

        }

        @Override
        protected Integer doInBackground(Void... params) {

            for (int i = interval; i >= 0; i--) {
                publishProgress(i);

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);


            try {
                NewXorString = generateQrCodeString(otpString, path3Encrypt, intervalTotpEncrypt);

            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }

            generateNewString = Cryptography.xorHex(NewXorString);

            UpdateQrCodeString(generateNewString);
            new UpdateQrCode().execute();

        }
    }

    // function with update QR Code Image

    private void UpdateQrCodeString(String generateStringQrCode) {

        WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
        Point point = new Point();
        display.getSize(point);

        int width = point.x;
        int height = point.y;

        int smallerDimension = width < height ? width : height;
        smallerDimension = smallerDimension * 3 / 4;

        QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(generateStringQrCode, null, Contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), smallerDimension);

        try {
            Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();
            ImageView myImageView = (ImageView) findViewById(R.id.qrCodeImageView);
            myImageView.setImageBitmap(bitmap);
        } catch (WriterException e) {
            e.printStackTrace();
        }

    }

    private String generateQrCodeString(String otpString, String path3String, String intervalTotp) throws InvalidKeyException, NoSuchAlgorithmException {

        Base32 code = new Base32();
        byte secret[] = code.decode(otpString);
        String totpString = OtpAlgorithm.generateTotp(secret, intervalTotp);
        return path3String + totpString;

    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        outState.putInt(TIME, currentInterval);
        progressBar.setProgress(currentInterval);
    }
}
1

Po pierwsze czy logika aplikacji znajduje się w wątku głównym czy tworzysz osobny? Po drugie może warto skorzystać z serwisu, jeżeli to ma działać w tle.

/update: Dobra widzę, że dałaś kod. Po pierwsze gdy wychodzisz z aplikacji to Activity przechodzi w stan onPause(), a później onStop(), a nawet może zostać zniszczone przez OS onDestroy(). Po drugie nawet jak wyjdziesz z aplikacji, nawet jak Activity zostanie zniszczone onDestroy to AsyncTask sobie nadal radośnie działa, ponieważ Ty go w ogóle nie cancelujesz... Po trzecie widzę, że masz onSaveInstanceState i zapisujesz interval. Tak napisany kod sprawia, że interval zapisuje się przed onStop() czyli tuż przed wyjściem z aplikacji. Po czwarte w onCreate tymczasem widzę, że wczytujesz ten wcześniej zapisany interval do zmiennej currentInterval, aktualizujesz progress bar, a po chwili tworzysz nowy qr code i uruchamiasz nowy AsyncTask w którym to liczysz sobie od nowa od wartości interval, a nie od currentInterval, więc progress bar jest na nowo wypełniony i liczy od nowa -.- Poza tym jak wyjdziesz i wejdziesz z aplikacji 1000 razy to stworzysz sobie 1000 async tasków, które będą sobie radośnie odliczały interval nie wiadomo po co i nie wiadomo dla kogo.

Czyli aplikacja działa tak jak została napisana przez programistę. Nie dzieje się nic niezwykłego i niezrozumiałego.

0

@magdalena123:

tak czy siak najlepszym rozwiązaniem by była implantacja Serwisu ?

Serwis nie jest tu potrzebny. Błąd polega na tym, że gdy wznawiasz aplikację to liczysz zawsze od interval:

@Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressBar.setMax(interval);
        }

a powinnaś od currentInterval czyli od tego co odczytałaś z savedInstanceState, jeżeli z savedInstanceState nic nie odczytałaś to liczysz jak zwykle od interval.

0

Teraz poprawiłam projekt użyłam IntentServiców aby progress bar działał w tle, tylko problem jest nie wiem za bardzo jak zrobić aby licznik znów na okrągło liczył, skończy liczenie to od nowa żeby mógł odliczać

public class ProgressBarService extends IntentService {
    private int interval;
    private static final String TAG = ProgressBarService.class.getSimpleName();
    public static final String KEY_EXTRA_PROGRESS = "progress";

    public ProgressBarService() {
        super(ProgressBarService.class.getSimpleName());
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            interval = intent.getIntExtra("interval", 0);
            Intent broadcastIntent = new Intent(CardDetailsActivity.BROADCAST_EVENT_NAME);
            LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
            for (int i =  interval; i >= 0; i--) {
                broadcastIntent = new Intent(CardDetailsActivity.BROADCAST_EVENT_NAME);
                broadcastIntent.putExtra(KEY_EXTRA_PROGRESS, i);
                LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
                SystemClock.sleep(1000);
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}


public class CardDetailsActivity extends AppCompatActivity {

    private String intervalTotpEncrypt;
    private ProgressBar progressBar;
    private TextView secondTimeTextView;
    private int interval;
    protected String cardNameDecrypt, intervalTotpDecrypt;

    public static final String BROADCAST_EVENT_NAME = "broadcast-event-name";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_card_details);

        Default app = (Default) getApplicationContext();
        keyString = app.getUuidString();
        Bundle extras = getIntent().getExtras();

        Typeface custom_fonts = Typeface.createFromAsset(getAssets(), "fonts/OpenSans-Regular.ttf");
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

        progressBar = (ProgressBar) findViewById(R.id.refershProgrss);
        cardNameEncrypt = extras.getString("cardName");

        intervalTotpEncrypt = extras.getString("intervalTotp");

        try {
            intervalTotpDecrypt = AesCrypt.decrypt(keyString, intervalTotpEncrypt);
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }

        otpString = path3Decrypt + getCode;
        generateQrString = Cryptography.xorHex(otpString);
        interval = Integer.parseInt(intervalTotpDecrypt);

        progressBar.setMax(interval);
        progressBar.setProgress(interval);

        LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
                new IntentFilter(BROADCAST_EVENT_NAME));

        Intent intent = new Intent(this, ProgressBarService.class);
        intent.putExtra("interval", interval);
        startService(intent);
        setSupportActionBar(toolbar);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
    }

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.hasExtra(ProgressBarService.KEY_EXTRA_PROGRESS)) {
                progressBar.setProgress(intent.getIntExtra(ProgressBarService.KEY_EXTRA_PROGRESS, 0));
                secondTimeTextView.setText("" + intent.getIntExtra(ProgressBarService.KEY_EXTRA_PROGRESS, 0));
            }
        }
    };

}



1 użytkowników online, w tym zalogowanych: 0, gości: 1