I have two activities: MainActivity6 (parent) and tool1mode1 (Child)
from the parent activity:
if (tool == 1) {
switch (mode) {
case 1:
intentTool1mode1.putExtra("Type", typekey);
intentTool1mode1.putExtra("Key", Key);
intentTool1mode1.putExtra("Tool", "Tool 1");
intentTool1mode1.putExtra("Mode", "Home");
Toast.makeText(MainActivity6.this, "Type: " + typekey + "\n" + "Key: " + Key + "\n" + "Tool: " + "1" + "\n" + "Mode: " + "Home" + "\n", Toast.LENGTH_LONG).show();
if(key_60.isChecked())
{
String number = "480000";
long val = Long.parseLong(number);
intentTool1mode1.putExtra("Time",val);
startActivityForResult(intentTool1mode1, 1);
}
if(key_90.isChecked())
{
String number = "720000";
long val = Long.parseLong(number);
intentTool1mode1.putExtra("Time",val);
startActivityForResult(intentTool1mode1, 1);
}
break;
And this is the part from the child Activity:
private long START_TIME_IN_MILLIS;
private long mTimeLeftInMillis = START_TIME_IN_MILLIS;
private CountDownTimer mCountDownTimer;
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent = getIntent();
START_TIME_IN_MILLIS = intent.getLongExtra("Time", 0);
newbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startTimer();
}
});
The code below represents both function I used to start and update the counter in the child Activity:
private void startTimer()
{
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
progress++;
pb.setProgress((int)progress*100/(480000/1000));
}
#Override
public void onFinish()
{
progress++;
pb.setProgress(100);
//Vibration
if (Build.VERSION.SDK_INT >= 26)
{
((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(VibrationEffect.createOneShot(150, VibrationEffect.DEFAULT_AMPLITUDE));
Toast.makeText(com.example.ticwatch_1.tool1mode1.this,"Done",Toast.LENGTH_SHORT).show();
}
else
{
((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(VibrationEffect.createWaveform(new long[]{150}, new int[]{VibrationEffect.EFFECT_CLICK},-1));
}
}
}.start();
}
private void updateCountDownText()
{
//time in minutes and seconds
int minutes = (int)(mTimeLeftInMillis/1000)/60;
int seconds = (int)(mTimeLeftInMillis/1000)%60;
//formating the above to appear as String
String timeLeftFormatted = String.format("%02d:%02d",minutes,seconds);
timer.setText(timeLeftFormatted);
}
What I want is to fetch the value from the Parent Activity and to update the value of START_TIME_IN_MILLIS with the value I fetched. So I I want the timer to run for 8 min I'll fetch 480000. What I get instead is the counter is 0 when I start it as in it already finished and didn't start from 8 min or any other value. I don't know what to do and I'm exhausted.
Related
Hi I am new in android studio and i made a chronometer with a couple of other functions in my app but i have a problem when I change the fragment or screen rotates everything is good except my chronometer is set back to 00:00:00. Can someone help me please and show me how can I keep my chronometer running when those changes are made or even let it run when app is closed...
here is my code:
public class HomeFragment extends Fragment {
private Chronometer chronometer;
private Button buttonStart, buttonMinus;
private TextView mTVCount, gTVCount, lTVCount;
private int mCount;
private Double gCount=0.00, lCount=0.00;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home, container, false);
chronometer = v.findViewById(R.id.simpleChronometer);
gTVCount = v.findViewById(R.id.textView67);
mTVCount = v.findViewById(R.id.textView62);
lTVCount = v.findViewById(R.id.textView69);
buttonStart = (Button) v.findViewById(R.id.button);
buttonMinus = (Button) v.findViewById(R.id.button2);
buttonStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
increment();
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
if (mCount > 20) {
Toast.makeText(buttonStart.getContext(), "Du wirst zu einem Schornstein!",
Toast.LENGTH_SHORT).show();
} else if (mCount >= 15) {
Toast.makeText(buttonStart.getContext(), "Du willst doch aufhören...oder?",
Toast.LENGTH_SHORT).show();
} else if (mCount >= 10) {
Toast.makeText(buttonStart.getContext(), "Ok Großer, mach eine Pause!",
Toast.LENGTH_SHORT).show();
} else if (mCount >= 5) {
Toast.makeText(buttonStart.getContext(), "Ganz Langsam!",
Toast.LENGTH_SHORT).show();
} else if (mCount > 0) {
Toast.makeText(buttonStart.getContext(), "Nicht so schlimm...",
Toast.LENGTH_SHORT).show();
}
}
private void increment() {
mCount++;
mTVCount.setText(String.valueOf(mCount));
lCount += 5;
lTVCount.setText(String.valueOf(String.format("%.0f", lCount) + " min"));
if (lCount >= 60) {
lTVCount.setText(String.valueOf(String.format("%.2f", lCount / 60)) + " h");
}
gCount += 0.36;
gTVCount.setText(String.valueOf(String.format("%.2f", gCount) + "€"));
}
});
Chronometer timeElapsed = (Chronometer) v.findViewById(R.id.simpleChronometer);
timeElapsed.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer cArg) {
long time = SystemClock.elapsedRealtime() - cArg.getBase();
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
String hh = h < 10 ? "0" + h : h + "";
String mm = m < 10 ? "0" + m : m + "";
String ss = s < 10 ? "0" + s : s + "";
cArg.setText(hh + ":" + mm + ":" + ss);
}
});
buttonMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
decrement();
}
private void decrement() {
mCount--;
mTVCount.setText(String.valueOf(mCount));
lCount -= 5;
lTVCount.setText(String.valueOf(String.format("%.0f", lCount) + " min"));
if (lCount >= 60) {
lTVCount.setText(String.valueOf(String.format("%.2f", lCount / 60)) + " h");
}
gCount -= 0.36;
gTVCount.setText(String.valueOf(String.format("%.2f", gCount) + "€"));
}
});
if (savedInstanceState != null){
mCount = savedInstanceState.getInt("count");
mTVCount.setText(String.valueOf(mCount));
gCount = savedInstanceState.getDouble("geld");
gTVCount.setText(String.valueOf( gCount) + "€");
lCount = savedInstanceState.getDouble("leben");
lTVCount.setText(String.valueOf(String.format("%.0f", lCount) + " min"));
if (lCount >= 60) {
lTVCount.setText(String.valueOf(String.format("%.2f", lCount / 60)) + " h");
}
}
return v;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("count", mCount);
outState.putDouble("geld", gCount);
outState.putDouble("leben", lCount);
super.onSaveInstanceState(outState);
}
}
I have a variable of its kind int.
I've allocated value in it through another value from within another object ,but there's a problem.
The problem is happening when i press the button 3
after i set the required time values for each object.
I'll show you the wrong message ,and the code used.
I want to change the code to work properly.
// Logcat:
java.lang.NullPointerException: Attempt to read from field 'int com.ahmedco.testcode2.TimePickerDialog.hourOfDay' on a null object reference
at com.ahmedco.testcode2.MainActivity$3.onClick(MainActivity.java:65)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
// class 1
public class MainActivity extends AppCompatActivity {
Button b1, b2, b3;
DialogFragment timePickerDialog1, timePickerDialog2;
int hourTimer1, hourTimer2, minuteTimer1, minuteTimer2;
String time1Format, time2Format, AM_PMTimer1, AM_PMTimer2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1 = (Button) findViewById(R.id.button);
b2 = (Button) findViewById(R.id.button2);
b3 = (Button) findViewById(R.id.button3);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
timePickerDialog1 = new TimePickerDialog(1);
timePickerDialog1.show(getSupportFragmentManager(), "timePicker");
}
});
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
timePickerDialog2 = new TimePickerDialog(2);
timePickerDialog2.show(getSupportFragmentManager(), "timePicker");
}
});
b3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
hourTimer1 = ((TimePickerDialog) timePickerDialog1).hourOfDay;
hourTimer2 = ((TimePickerDialog) timePickerDialog2).hourOfDay;
minuteTimer1 = ((TimePickerDialog) timePickerDialog1).minute;
minuteTimer2 = ((TimePickerDialog) timePickerDialog2).minute;
AM_PMTimer1 = ((TimePickerDialog) timePickerDialog1).AM_PM;
AM_PMTimer2 = ((TimePickerDialog) timePickerDialog2).AM_PM;
//Log.i("trace1","test "+((TimePickerDialog) timePickerDialog1).hourOfDay);
//Log.i("trace2","test "+((TimePickerDialog) timePickerDialog2).hourOfDay);
time1Format = "" + hourTimer1 + ":" + minuteTimer1 + " " + AM_PMTimer1;
time2Format = "" + hourTimer1 + ":" + minuteTimer1 + " " + AM_PMTimer2;
Log.i("time1Format", "" + time1Format);
Log.i("time2Format", "" + time2Format);
}
});
}
}
// class 2
public class TimePickerDialog extends DialogFragment implements android.app.TimePickerDialog.OnTimeSetListener {
public String AM_PM = "";
public int hourOfDay = 0;
public int minute = 0;
public TimePickerDialog(int id) {
// currentEditText = id;
}
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
// Use the current time as the default values for the picker
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
return new android.app.TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
}
#Override
public void onTimeSet(TimePicker view, int hourOfDay_, int minute_) {
// "11:06 PM"
if (hourOfDay_ > 12) {
AM_PM = "PM";
hourOfDay_ = hourOfDay_ - 12;
} else {
AM_PM = "AM";
}
///Log.i("hourOfDay",""+hourOfDay_+":"+hourOfDay_+" "+AM_PM);
hourOfDay = hourOfDay_;
minute = minute_;
}
}
You having problem inside b3.setOnClickListener because you are not initialized object so you have to initialize objects timePickerDialog1 and timePickerDialog2 globally.
DialogFragment timePickerDialog1=new TimePickerDialog(1), timePickerDialog2=new TimePickerDialog(2);
or
b3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(timePickerDialog1==null)
timePickerDialog1=new TimePickerDialog(1);
if(timePickerDialog2==null)
timePickerDialog1=new TimePickerDialog(2);
hourTimer1 = ((TimePickerDialog) timePickerDialog1).hourOfDay;
hourTimer2 = ((TimePickerDialog) timePickerDialog2).hourOfDay;
minuteTimer1 = ((TimePickerDialog) timePickerDialog1).minute;
minuteTimer2 = ((TimePickerDialog) timePickerDialog2).minute;
AM_PMTimer1 = ((TimePickerDialog) timePickerDialog1).AM_PM;
AM_PMTimer2 = ((TimePickerDialog) timePickerDialog2).AM_PM;
//Log.i("trace1","test "+((TimePickerDialog) timePickerDialog1).hourOfDay);
//Log.i("trace2","test "+((TimePickerDialog) timePickerDialog2).hourOfDay);
time1Format = "" + hourTimer1 + ":" + minuteTimer1 + " " + AM_PMTimer1;
time2Format = "" + hourTimer1 + ":" + minuteTimer1 + " " + AM_PMTimer2;
Log.i("time1Format", "" + time1Format);
Log.i("time2Format", "" + time2Format);
}
});
You declare your TimePickerDialog in the beginning (DialogFragment timePickerDialog1, timePickerDialog2;)
But only initialise it when Button 1 or 2 are pressed respectively
timePickerDialog2 = new TimePickerDialog(2);
Therefore timePickerDialog2is nulluntil Button 2 was pressed.
When trying to call .hourOfDay in Button 3 when timePickerDialog2has not been initialised yet, you get a NullPointerException. You can't call methods on an object that is null.
I making a timer in my android app. I have a scenario where I dont need to stop the timer even if the app is closed. If the timer is running and user closes the app and reopen it after sometime. He should see the latest time on the timer. But currently I am not able to show the latest time. I am only able to show the time when the user killed the app. I am storing the time of the timer and when the user open the app I am putting the stored time back to the timer. But I want to show the latest time. Here what I have done till now. I am using chronometer widget.
MainActivity.class:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = MainActivity.class.getSimpleName();
Chronometer tvTextView;
Button btnStart, btnStop;
private int state = 0; //0 means stop state,1 means play, 2 means pause
SharedPreferences sharedPreferences;
private boolean running = false;
private long pauseOffSet = -1;
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTextView = findViewById(R.id.textview);
progressBar = findViewById(R.id.puzzleProgressBar);
btnStart = findViewById(R.id.button1);
btnStop = findViewById(R.id.button2);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
sharedPreferences = getSharedPreferences("myprefs", MODE_PRIVATE);
state = sharedPreferences.getInt("state", 0);
tvTextView.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
long time = SystemClock.elapsedRealtime() - chronometer.getBase();
pauseOffSet=time;
Log.e(TAG,"pauseOffSet "+pauseOffSet);
if (time >= 79200000) {
tvTextView.setBase(SystemClock.elapsedRealtime());
tvTextView.stop();
running = false;
progressBar.setProgress(0);
} else {
chronometer.setText(setFormat(time));
int convertTime = (int) time;
progressBar.setProgress(convertTime);
}
}
});
if (state == 1) { // its in play mode
running = true;
tvTextView.setBase(SystemClock.elapsedRealtime() - sharedPreferences.getLong("milli", 0));
tvTextView.start();
} else if (state == 2) { //its in pause mode
running = false;
pauseOffSet = sharedPreferences.getLong("milli", -1);
long time = SystemClock.elapsedRealtime() - pauseOffSet;
tvTextView.setBase(time);
int convertTime = (int) pauseOffSet;
progressBar.setProgress(convertTime);
} else {
running = false;
tvTextView.setBase(SystemClock.elapsedRealtime());
}
}
public void onClick(View v) {
if (btnStart == v) {
if (!running) {
if (pauseOffSet != -1) {
pauseOffSet = sharedPreferences.getLong("milli", -1);
}
tvTextView.setBase(SystemClock.elapsedRealtime() - pauseOffSet);
tvTextView.start();
state = 1;
pauseOffSet = 0;
running = true;
}
} else if (btnStop == v) {
if (running) {
tvTextView.stop();
pauseOffSet = SystemClock.elapsedRealtime() - tvTextView.getBase();
state = 2;
running = false;
}
}
}
#Override
protected void onStop() {
super.onStop();
sharedPreferences.edit().putLong("milli", pauseOffSet).commit();
sharedPreferences.edit().putInt("state", state).commit();
}
#Override
protected void onDestroy() {
Log.e(TAG, "onDestroy called, state: " + state);
super.onDestroy();
}
String setFormat(long time) {
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
String hh = h < 10 ? "0" + h : h + "";
String mm = m < 10 ? "0" + m : m + "";
String ss = s < 10 ? "0" + s : s + "";
return hh + ":" + mm + ":" + ss;
}
}
Probably you want to jump to Update 2 and check the code if needed
I am building a barcode scanner and having difficulty in passing data that I have captured from an inner class that extends BroadcastReceiver to MainActivity class, I do understand the difference between static and non static objects, but I got stuck.
Cant invoke my logic method from the inner class.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
protected void onCreate(Bundle savedInstanceState){...}
public void Logic(String result){// Do something...}
//Inner Class
public static class ScanResultReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {...
// data here captured fine!
// Here I want to send my data to MainActivity Logic(result)
Logic(result);
}
}
If I make "Logic()" as Static method, I get a lot of errors regards to calling non static from static method from Toaster/variables..etc
Update
This method is inside MainActivity, I do want to call it from the inner class
public void Logic(String result) throws Exception {
//prepare the results
if (mDecodeResult.decodeValue.substring(0, 1).equals("{") && mDecodeResult.decodeValue.substring(mDecodeResult.decodeValue.length() - 1).equals("}")) {
if (!(mDecodeResult.decodeValue.equals("SCAN AGAIN"))) {
mDecodeResult.decodeValue = mDecodeResult.decodeValue.substring(1);
mDecodeResult.decodeValue = mDecodeResult.decodeValue.substring(0, mDecodeResult.decodeValue.length() - 1);
}
}
if (mDecodeResult.decodeValue.equals("SCAN AGAIN")) {
Toast toast = Toast.makeText(getApplicationContext(),
"No scan data received! Please Scan Again", Toast.LENGTH_SHORT);
toast.show();
} else if (mDecodeResult.decodeValue != null && tourFlag) {
String formattedDate = getTime();
String scanContent = mDecodeResult.decodeValue;
boolean found = false;
if (ForcedOrRandom.equals("Random")) {
String[] b;
for (String l : ToBeScanned) {
b = l.split(":");
if (scanContent.equals(b[0])) {
Log.d("remove", "scanned: " + scanContent);
Log.d("remove", "remove : " + b[0]);
found = true;
}
}
} else if (ForcedOrRandom.equals("Forced")) {
String[] b;
for (String I : FTobeScannedNext) {
b = I.split(":");
if (scanContent.equals(b[0])) {
Log.d("remove", "scanned: " + scanContent);
Log.d("remove", "remove : " + b[0]);
found = true;
}
}
}// end Skip/Forced
if (listLoaded && found) {
theResult[resultCount].setTourID(currentTourId);
theResult[resultCount].setBarcode(scanContent);
BarcodeObject a = getBarcodeInfo(scanContent);
if (ForcedOrRandom.equals("Random")) {
} else {
if (myTimer != null) {
myTimer.cancel();
Timer = (TextView) findViewById(R.id.timertext);
Timer.setText("");
PlayOrPause.setVisibility(View.INVISIBLE);
}
boolean isTimed = a.getForceNextBarCode().equals("");
if (!(isTimed)) {
PlayOrPause = (ImageButton) findViewById(R.id.PlayPause);
PlayOrPause.setVisibility(View.VISIBLE);
PlayOrPause.setImageResource(R.drawable.pause);
final AlertDialog.Builder timealert = new AlertDialog.Builder(this);
PlayOrPause.setEnabled(true);
long duration = Integer.parseInt(a.getForceNextBarCode());
duration = duration * 60000;
myTimer = new CountDownTimer(duration, 1000) {
#Override
public void onTick(long millisuntilFinished) {
int seconds = (int) (millisuntilFinished / 1000) % 60;
int minutes = (int) ((millisuntilFinished / (1000 * 60)) % 60);
Timer = (TextView) findViewById(R.id.timertext);
Timer.setText(minutes + ":" + seconds);
timeLeft = millisuntilFinished;
}
String value = "";
#Override
public void onFinish() {
Timer = (TextView) findViewById(R.id.timertext);
theResult[resultCount].setScanstatus(scanStatusTimeElapsed);
timealert.setTitle("Site Secure");
timealert.setMessage("Time Elapsed! Enter reason");
// Set an EditText view to get user input
final EditText input = new EditText(MainActivity.this);
timealert.setView(input);
timealert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
value = input.getText().toString();
// Do something with value!
while (value.equals("")) {
timealert.setView(input);
timealert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
value = input.getText().toString();
}
});
}
theResult[resultCount].setComments(value);
}
});
timealert.setIcon(android.R.drawable.ic_dialog_alert);
timealert.show();
Timer.setText(R.string.Time_Elapsed);
}
};
myTimer.start();
}
}
theResult[resultCount].setBarcodeID(a.getBarCodeId());
theResult[resultCount].setDateScanned(formattedDate);
theResult[resultCount].setSkipped(getResources().getString(R.string.Scanned));
}// end big if listLoaded && found
contentTxt.setText(scanContent);
Toaster(getResources().getString(R.string.TScan_Complete));
if (mainScanCounter == 0) {
if (tourDecider(scanContent)) {//tour decider is called to determine if this is boolJanamScanner random or forced tour
tourId = scanContent;
if (!(readFileOffline(siteSecurePath + "/doneTourNumber.txt").equals(""))) {
SYNC.setEnabled(true);
}
}
} else if (mainScanCounter > 0) {
if (ForcedOrRandom.equals("Random")) {
ListManager(scanContent);
} else {
ForcedListManager(scanContent);
}
}
} else if (mDecodeResult.decodeValue != null && officerScanFlag) {
TextView officertextview = (TextView) findViewById(R.id.officerid);
UserObject theofficer = getUserInfo(mDecodeResult.decodeValue);
if (theofficer == null) {
popUps("Error", "Invalid Officer ID, Please Rescan", "TITLE");
officerScan.setEnabled(true);
} else if (theofficer != null) {
// officer ID found need to store it for backup
officerId = theofficer.getOfficerid();
makeFileOffline(officerId, "officerID");
officertextview.setText(theofficer.getUsername());
officerScanFlag = false;
startTimersOfficerID = getTime();
tourBtn.setEnabled(true);
}
}
if (mDecodeResult.decodeValue != null && exceptionFlag) {
Log.d("check", "exception was clicked");
String ex_result = mDecodeResult.decodeValue;
for (int i = 0; i < theExceptions.length; i++) {
if (!(theExceptions[i].getBarcode().equals(ex_result))) {
String refnum = theExceptions[i].getRefNum();
i = theExceptions.length;
theResult[resultCount - 1].setException(refnum);
}
}
exceptionFlag = false;
Toaster(getResources().getString(R.string.TScan_Complete));
}
} // Logic Ends
Update 2
Not sure if I need to have another thread for this but I will put what I have found, my issue have narrowed to the following:
I am waiting on an intent called
<action android:name="device.scanner.USERMSG" />
with a permission
android:permission="com.permission.SCANNER_RESULT_RECEIVER"
now my issue
if a user tap button and released in less than .5 second onKeyup() event will be fired before my onReceive() that is inside the static class which is extends BroadcastReceiver, and that causes problem because Logic() will be invoked before updating the String inside onReceive()
if user hold the button long enough, onReceive will be invoked and everything is good and happy.
How can I make sure that onReceive() always invoked first?
public boolean onKeyUp(int keycode, KeyEvent event) {
if (keycode == 221 || keycode == 220 || keycode == 222) {
Logic(result);
}
return true;
}
Move this line of code:
public void Logic(String result){// Do something...}
inside your class ScanResultReceiver and it will work for sure. Your code should look like this:
public static class ScanResultReceiver extends BroadcastReceiver {
public ScanResultReceiver() {
//empty constructor
}
#Override
public void onReceive(Context context, Intent intent) {...
// data here captured fine!
// Here I want to send my data to MainActivity Logic(result)
Logic(result);
}
public void Logic(String result){/* ... */}
}
I'm trying to implement a CountDownTimer in an Android Application. This timer will, while running, countdown from a value, than reset, than countdown from a different value. Switching back and force between values until either a set number of rounds have elapsed or the stop button has been pressed. I can get the CountDownTimer samples to work, but I guess I'm missing something here. Below is the applicable button press code;
CounterState state = CounterState.WORKOUT;
private WorkoutTimer workoutTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.workout_stopwatch);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Set up OnClickListeners
((Button) findViewById(R.id.start_button)).setOnClickListener(this);
((Button) findViewById(R.id.stop_button)).setOnClickListener(this);
((Button) findViewById(R.id.reset_button)).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.start_button:
if (!timer_running) {
timer_running = true;
Log.d(TAG, "clicked on Start Button");
// If the state is unknown, set it to Workout first
int State = state.getStateValue();
if (State == 0) {
state.setStateValue(1);
}
workoutTimer.start();
}
break;
case R.id.stop_button:
Log.d(TAG, "clicked on Stop Button");
if (timer_running); {
timer_running = false;
workoutTimer.cancel();
}
break;
private class WorkoutTimer extends CountDownTimer{
public WorkoutTimer(long interval) {
super(getThisTime(), interval);
Log.d(TAG, "WorkoutTimer Constructed...");
}
TextView digital_display = (TextView) findViewById(R.id.digital_display);
TextView numOfRounds = (TextView) findViewById(R.id.number_of_rounds);
public void onFinish() {
int State = state.getStateValue();
int roundsLeft = 0;
if (State == 1) {
state.setStateValue(2);
} else {
state.setStateValue(1);
}
decrementRounds();
try {
roundsLeft = Integer.parseInt(numOfRounds.getText().toString());
} catch(NumberFormatException nfe) {
roundsLeft = 999;
}
if (roundsLeft > 0 || roundsLeft != 999) {
workoutTimer.start();
}
}
public void onTick(long millisUntilFinished) {
final long minutes_left = ((millisUntilFinished / 1000) / 60);
final long seconds_left = (millisUntilFinished / 1000) - (minutes_left * 60);
final long millis_left = millisUntilFinished % 100;
String time_left = String.format("%02d:%02d.d", minutes_left, seconds_left,
millis_left);
digital_display.setText(time_left);
}
}
private long getThisTime() {
long time = 0;
TextView workout_time = (TextView) findViewById(R.id.workout_time);
TextView rest_time = (TextView) findViewById(R.id.rest_time);
switch(state) {
case WORKOUT:
try {
time = Integer.parseInt(workout_time.getText().toString());
} catch(NumberFormatException nfe) {
time = 999;
}
// time = 90;
Log.d(TAG, "Workout time = " + time);
break;
case REST:
try {
time = Integer.parseInt(rest_time.getText().toString());
} catch(NumberFormatException nfe) {
time = 999;
}
// time = 30;
Log.d(TAG, "Rest time = " + time);
break;
case UNKNOWN:
time = 0;
break;
}
return time;
}
Everything starts up okay, but crashes when I click either button. If I comment out my calls to the workoutTimer, no crash. I never see my log in the constructor of the workoutTimer class, so obviously I'm missing something here. Any help would be appreciated.
-Ian
You have not initialized your workoutTimer. You need to add the following line in your onCreate method.
workoutTimer = new WorkoutTimer(...);