I made an android application that simply calls the number range you enter.
Starts with starting number you enter and finishes with the "finish" number you enter. Application automatically hangs up after 7 seconds of ringing.
Code is below.
public void onClick(View view){
EditText starte = (EditText) findViewById(R.id.start);
EditText finishe = (EditText) findViewById(R.id.finish);
EditText prefixes = (EditText) findViewById(R.id.prefixes);
String prefix = prefixes.getText().toString();
/** Get Telephone number String **/
int startOriginal = Integer.parseInt(starte.getText().toString());
int finish = Integer.parseInt(finishe.getText().toString());
for (int start = startOriginal; start<=finish; start++) {
startCall(prefix, Integer.toString(start));
try {
Thread.sleep(7000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
new CallUtilities("endcall");
}
private void startCall(String prefix, String nr){
Intent intent = new Intent("android.intent.action.CALL");
Uri data = Uri.parse("tel:"+ prefix + nr);
/** Setting intent data */
intent.setData(data);
/** Starting the caller activity by the implicit intent */
startActivity(intent);
}
CallUtilities class is written by my end is simply ends the call via reflection methods. Now my problem is that when you enter a starting number and a finishing number the app always seems to call the first number for example 1 and after hanging it up it goes straight to 3 and then to 4 and 5 and so on like it should do. Any idea on what is wrong?
Also is it possible to use DisconnectCause here to get the reason of disconnect in case calls hangs up prematurely?
Thank you in advance!
This is a recipe for disaster. For a few reasons.
You are (assuming onClick(View v) runs on the UI Thread) attempting to sleep the UI Thread.
If the UI Thread hangs for longer than 5 seconds, it will cause an ANR.
Additionally, you appear to be attempting to launch multiple Activities at the same time. This is certainly not the right way to be designing your App.
Not to mention using Reflection to access core Android components to end the calls. That may cause issues for your App in the future.
My suggestion for the multiple Activities / sleep problem:
Remove the loop
Store next attempted number
Run the call function
In onActivityResult you can determine the next number to try
Go to 2. (make sure to include an end condition!
Related
I want to make a loop, the times the user wants but with a delay of 3 seconds.
This is the code:
for (i = 0;i < n1; i++){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(KeyMapCreator.this, "Try number " + i,Toast.LENGTH_SHORT).show(); ActionIwantToDo();
}
},3000);
}
The variable i is the one that the user sets.
The problem is that the toast doesn't show up every 3 seconds, it just do like a normal loop without delay. I thought it was because of the time of the toast but if i set the time to 20 secs still being the same.
Someone knows how to make a proper delay inside a loop???
The problem you have is that your loop creates many handlers at once that delay for 3 seconds and then show a toast. They do not wait for each other, and because they are created within milliseconds of each other they will show the toast at the same time.
I'm not sure what you are trying to accomplish, and a loop is probably not what you want. However this is a way to get the toast to display after 3 seconds and every 3 seconds after for a number of times.
For this we will use recursion because it will make it so that you are not blocked on the main thread.
Call doSomething (the recursive function) from where you need the function to start (remember that the second variable is the number of times you want it to run, and 0 is just required as a counter)
doSomething(0, 3)
create doSomething
private void doSomething(int i, int n) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (i < n) {
Toast.makeText(KeyMapCreator.this, "Try number " + i,Toast.LENGTH_SHORT).show();
actionIWantToDo();
doSomething(i+1, n);
}
}
}, 3000);
}
A Handler just schedules some work for later execution. It doesn't actually block the current thread. All you're doing is scheduling n1 items of work to execute three seconds later, which will all execute in sequence on that exact delay.
You don't really ever want to write code to block the main thread. Ever. It will make your app appear to be unresponsive.
This app talks to a serial device over an usb to serial dongle. I have been able to get it to process my single queries no problem but I have a command that will send multiple queries to the serial device and It seems to me the buffer if getting overrun. Here is part of my code:
This is my array with 20 query commands:
String [] stringOneArray = {":000101017d", ":0001060178", ":00010B016C", ":000110017D",
":0001150178", ":00011A016C", ":00011F0167", ":0001240178", ":0001290173",
":00012E0167", ":0001330178", ":0001380173", ":00013D0167", ":0001420178",
":0001470173", ":00014C0167", ":0001510178", ":0001560173", ":00015B0167", ":0001600178"};
This is how I use the array:
getVelocitiesButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ftDev.setLatencyTimer((byte) 16);
int z;
for (z = 0; z < 19; z++) {
String writeData = (String) stringOneArray[z];
byte[] OutData = writeData.getBytes();
ftDev.write(OutData, writeData.length());
try {
Thread.sleep(50);
} catch (InterruptedException e) { }
}
}
});
Not sure the rest of the code is necessary but will add it if needed.
So ftdev is my serial device. It sends the query command to the serial device, it receives the response in bytes, I use a For loop to build the response until all bytes (31 bytes per response) then I process that response and at that time it should receive the second query command from the array, so on until the last command is sent.. It is all fine an dandy if I allow the FOR loop to send only one or 2 queries but with a larger number of array index and it crashes. Figured I just slow down the FOR loop and add the thread.sleep but it freezes the app and crashes... What gives? Is there any other way to control the speed to which the commands are sent? I rather send them as soon as it is possible but I am afraid I don't know java as much. This has been so far my major stepping stone in finishing this personal project, been stuck for 2 days researching and trying solutions.
Looks like you're sleeping for ~1000ms (well 950 to be exact because your last operation is not being sent to the serial device) plus the time needed to perform the writes over your serial connection. That's a pretty long time to do nothing. Remove the Thread.sleep(50) call and put the entire contents of the onClick into the run method of the following code:
AsyncTask.execute(new Runnable {
#Override
public void run() {
// talk to device here
}
});
Then, ask a different question about the quick writes crashing your connection.
Below I have a Runnable "updater" ...and an OnClick function that uses Handler.PostDelayed function to run the runnable after a delay...
After a little editing, cutting of useless parts here are the functions:
(passtog = Toggle Button)
final Runnable updater = new Runnable() {
#Override
public void run() {
if (passTog.isChecked()) {
now = System.currentTimeMillis();
time = now - init;
if (time > 5000) {
Toast.makeText(getApplicationContext(), "WAKE UP !",
Toast.LENGTH_SHORT).show();
}
handler.postDelayed(this, 25);
}
}
};
passTog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
init = System.currentTimeMillis();
flag = true;
handler.postDelayed(updater,
(new Random().nextInt(4000) + 3000));
}
});
}
Explaination
Basically, The user toggles the Toggle button. Now it's on: The runnable can run completely (Everything is in the if block).
If the user doesn't press the button again, and switches it off The app sends a Toast "Wake Up!" ..It runs and checks every 25 millisecs to update the time...
Pretty straightforward... Yet I'm having a problem.
Before the program actually gets to the runnable, I absolutely NEED there to be a minimum time delay of 3 seconds + Some Random value ... So it varies between 3 sec - 7 sec. It SHOULD vary between 3-7 , but it doesn't.
When I run it: The problem
I notice that the first time, it works great... I get atleast a 3 sec delay + a random value= Perfect
The second time, that is after the switch goes on ->off-> on : Now It acts like it doesn't see the +3000 ...and just the ~randInt(4000) function... So it may give 0 sec or it may give 4 sec delay...
In all my experience, I've never really come across this.. I've rewritten the entire code, My other apps use this function in exactly the same sytax and seem to do pretty great.. Why is this creating a problem ? Could the Toast's time possibly be causing a problem..
How to solve this ?
(I'm open to other methods, preferably quick to implement. I want a minimum 3 sec delay which I'm not getting for some reason... I need the UI to be responsive though So no thread sleeping.)
You probably should call Handler.removeCallbacksAndMessages(null) when the switch goes off.
As the question says, here's the code.
What I want to do basically is I have a list of array, says "myArray". This array contains stored time points in millisecond. Next thing is I want to call a method based on those time points. So, I need to run a time counter from 0 while the music is playing, compare the time counter with the time points in the array progressively (from first array index until finished).
The first method "timeCounter" is a method to start a time counter while a music is playing through MediaPlayer.
public void timeCounter(){
Runnable myRunnable = new Runnable(){
#Override
public void run(){
while(musicPlaying){
startCounter(arrayPos);
}
}
};
Thread musicPlayer = new Thread(myRunnable);
musicPlayer.start();
}
This is where the comparison of time counter and time in the array takes place.
public void startCounter(List<Long> array){
elapsedTime = System.currentTimeMillis() - timeStart;
if(elapsedTime == array.get(arrayPos)){
arrayPos += 1; //Continue comparing with the next number in the array
Log.v("DEBUG", "TIME MATCHES!");
if(arrayPos>= array.size()){
arrayPos= 0; //Prevent out of array index
}
}
}
I have the code running correctly and the result from the LogCat is correct.
Now the problem is sometimes the Thread is not running until the music finished playing (I have set onCompletionListener and set "musicPlaying" to false when music finished). The stopping point is totally random, sometimes when it's just started, or around 50%, or even when it's near to completion. Sometimes it doesn't even start!
I've been trying to figure out why but I couldn't find any info about Thread stopping halfway or such in anywhere. Thanks in advance! =)
If musicPlaying is modified and read between threads, make sure it is declared volatile.
I suspect your if(elapsedTime == array.get(arrayPos)) should be if(elapsedTime >= array.get(arrayPos)).
You need to remember that the millisecond timer does not necessarily have a one millisecond tick. On Windows, for example, the returned value will only change every 15 ms or so. You may therefore completely miss a particular time and therefore never get past that entry in your list.
In android if a button is clicked i want a countdown to start from 30 and countdown to 0. I created a code with a basic countdown method but the problem is it doesn't continue to countdown if the activity or application closes.
What i want to do is for the activity or just the countdown to continue ticking down in the background until it hits 0 in which it'll change variable B to the value of 1.
I have expanded from my original model thinking i could compare dates times from when the button was clicked + 30 seconds to when the activity is called up upon again. But so far i have come to a stump in comparing two datetimes in android.
Any help?
What you likely want is an async task to run in the background. Something like:
private class JohnnysPollTask extends AsyncTask<Integer, Void, Integer> {
/**
* The system calls this to perform work in a worker thread and delivers
* it the parameters given to AsyncTask.execute()
*/
protected Integer doInBackground(Integer... millis) {
try {
int waited = 0;
int duration = 30000;
while (waited < duration) {
Thread.sleep(1000);
waited += 1000;
if (waited>=duration) {
b=1;
break;
}
}
} catch (InterruptedException e) {
// do nothing
}
return 1;
}
Implement CountDownTimer
inside service.
You could try using a service instead of an activity.