How to interrupt ACTION_CALL - Android Software Development

I'm a new android developer working on an extremely simple app and I just need a quick pointer! My app, once started, needs to call a certain phone number. This part was simple and works fine. However, I need that call to end after a specific amount of time (10 seconds is the number I'd like).
At this point I'm unsure how to proceed. I've tried spawning a thread that simply waits for 10 seconds, and then tries to call finishActivity() on the activity that I originally started. However, I'm assuming that one thread can't control another threads activities, so this clearly doesn't work. I've also tried a few other methods and none of them seem to work, or they simply crash my app.
If someone can even give me just a high level overview of what I need to do that would be great! My next thought is to spawn a timer thread and use RPC to call a function that will activate finishActivity() in the thread that is running the activity.
Any information you guys can provide me with will be fantastic!

The API won't let you, however, you could try to switch ON airplane mode and the switch it OFF, the inconvenience of this is that all your active connections will be droped (3G, GRPS, Bluetooth, WiFi)

Are you sure its not possible? Using various callbacks I've sent finishActivity() to the action with success. The problem is that there are no callbacks that occur around the time that I want the call to end.
Since it does work with callbacks, I was tempted to have finishActivity() be called when the app is backgrounded. That way after 10 seconds I can just hit the home key and it will close the app down entirely? Not exactly what I want, but could work for now.
Due to the fact that it can be finished during a call back I think it must be possible, I'm just not sure how to go about achieving it. Does anyone have any ideas?

Try the following code:
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class clazz = Class.forName(tm.getClass().getName());
Method m = clazz.getDeclaredMethod("getITelephony");
m.setAccessible(true);
ITelephony it = (ITelephony) m.invoke(tm);
it.endCall();
But you need to get ITelephony.aidl from Android sources and compile it.

Related

I am writing a program on my htc and have a problem with multithreading and timers

Hi I didn't know where I could get help on this topic but seeing as some of the guys in here have made such excellent programs I thought you might be familar with c# on windows mobile.
here is my problem.
I have a task I need to do every x seconds I want to be able to start and stop this repeating task immediately.
I have attempted to solve this by creating a class which holds the taks I want to do, in this class I have put a windows.forms.timer with the task as its timer.tick event. this task has a method called start() which sets the timer going.
to start the process in my main thread i create a new thread which creates an instance of my class(mentioned above) and calls its start method.
The problem is the tick event never seems to fire is this because its in a seperate thread to the one which has focus, is it because it doesnt have an asociated form?
is there a better way to do this?
I want an object I can create which I can call methods to start and stop a repeating task.
many thanks,
I hope some one can help.
(sorry if this is completely the wrong place to post this)
Have you set the timer.Enabled = true?
Instead of windows.forms.timer try system.threading.timer!
comparison of timer classes in .net
Why have you put this in a thread, so you can abort it midway through processing its tick event?
Is there a better way you could do this than adding the complexity of threads? Perhaps add a bool to you class and your tick event can check at safe points if it is false (and exit)?
My initial thought to the problem as you have outlined it is that your thread is finished after completing its Start() method, so the tick event never gets called (as the timer no longer exists). You would need to keep the thread alive (without interfereing with your timer).
Windows.Forms.Timer is a bad choice for this as it uses the calling thread - so if you add a System.Threading.Thread.Sleep() (or some other blocking action) to keep your thread alive, your timer wont work. System.Threading.Timer is a better choice as it uses its own thread.
Hi thanks so much for the info I will have a look at threading timers.
I have put it in its own thread so I can abort it early because each "tick" could be between 5-15 mins and the task takes between 1 second and 5 mins so I wanted to be able to make sure the task is started at regular intervals and have the ability to stop the process immediately.
I was just thinking that neither timers or using a bool will allow me to stop the process immediately, is it safe to use thread.abort? i.e. if part of the task is to update a field could it be stopped half way through and corrupt the data?
if it is unsafe is there a safe thread abort i.e. abort as soon as the thread has finished updating any fields or database records(this thread wont update database but its good to know)
also to the point you raised about the thread finishing when my start() method finishes I kept that going using a while loop and a bool i.e.
while(keepGoing)
{
}
this seemed like a really horrid thing to do but do I have any other choice?
I think my design is not good my app basically wants to start off this running process when it loads but needs to be able to interupt it when some data changes.
(as an extra question does any one know if sqlce 3.5 has built in thread safety or will I have to lock functions that access data in my database?)
Threads can be somewhat unpredictable. Thread.abort calls an exception, so as far as i know if you have something like
var1 = "blah";
that would finish - var1 would not be corrupt. But, if you were doing something more complicated such as your database example you cant be sure when it will cut you off. Of course, you can catch the ThreadAbortException, and do some checking if required.
As for your while loop, that almost certainly blocked the thread and is why your timer did not work. Windows forms timers are based around events and will not typically run while one of your methods is still working, unless it yields somehow. Infact, on a single cpu device like your phone that loop would probably block a System.Threading.Timer because while(true); results in 100% cpu usage.
This is a quick example of how I would impliment your timer requirement - mostly stolen from the msdn page on System.Threading.Timer.
Code:
private void ThreadMethod()
{
System.Threading.ManualResetEvent resetEvent = new System.Threading.ManualResetEvent(false);
int interval = 10 * 1000;
System.Threading.Timer timer = new System.Threading.Timer(new System.Threading.TimerCallback(timer_Tick), resetEvent, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
while (true)
{
resetEvent.Reset();
timer.Change(interval, System.Threading.Timeout.Infinite);
resetEvent.WaitOne();
DoStuffThatTakesOneToFiveMinutes();
}
timer.Dispose();
}
private void timer_Tick(object timerObject)
{
System.Threading.ManualResetEvent resetEvent = (System.Threading.ManualResetEvent)timerObject;
resetEvent.Set();
}
private void DoStuffThatTakesOneToFiveMinutes()
{
MessageBox.Show("hi");
}
ThreadMethod can just be directly called from your thread.
timer.Change starts the timer off. The Infinite means it is not a repeating timer.
resetEvent.WaitOne() simply waits for the event to be triggered. The nice thing about doing it that way is your processing is done by the calling method, and you can be sure at what point in your process. (Well, as much as you can with it all running inside a larger thread.)
Edit:
Infact, that timer.Dispose() is pointless as it will never get called. Probably a good idea to call it if you catch the threadabortexception though.
Also, I think var1 (first example) would simply not change, but im not sure. I dont think it would get corruped either way.
Thanks so much for this information it looks excellent. So if I want to tidy up some stuff on exit I see on msdn it says the finally block will exitcuted before exit or I could catch the abortexception as you suggest, where would I put this code would it be inside the threadMethod? or does it go somewhere else?
also imagine this example I am updating a record in my database, I throw the abort exception and it stops the process midway, is there a way in code to say ignor this exception and continue? i.e. when updating database i could set a bool and then check this bool in the finally or catch block and if its true say ignor this and continue and then outside my thread I could do a check on the thread to see if its still running if it is then i wait for x amount of time and try the abort again?
what would be a good way to notify the calling thread that the thread with the timer is still running as the isAlive property is not included as part of the compact framework, I suppose I could have a bool in the calling thread which the timer thread could change in the finally catch block when the abort exception is passed, but this would mean passing the calling thread to the called thread is there any problems doing this?
sorry this is quite a complicated situation I have made for myself, I really appreciate the help.
Im afraid we have hit the limit of my knowledge on threads and exceptions.
My thought was you could wrap the database parts in a try-catch, at least allowing you to handle the abort gracefully. As far as I know you can not continue the thread at the point it stopped - you can merely ignore it and carry on after the catch. Of course, exceptions are not meant to be used on a trial basis, they are more worst case.
Events may suit you a bit better, as they do not halt the flow. That way your thread could keep track anytime it is doing something important like database access - and the event would only close if safe.
You should be able to have your thread access a bool in the parent object, aslong as you are careful with synchronization. Making sure all parts that read/write to it use lock should be sufficient.
http://www.blackwasp.co.uk/CSharpEvents.aspx
http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
Thanks again isangelous,
I have thought that events would be a good idea but found them a little confusing, I will have another look and see if I can use them somehow.(thanks for the link)
btw I used the code you provided and tweaked it a bit to get my first problem working, i put the contence of the threadmethod inside a try block catch the abort exception and then call timer.dispose(), seems to work quite nicely so far, although I dont think i have managed to abort half way through a process, it always seems to be before or after but seeing as I dont use any of the variables after its stopped I assume all would be safe anyway.
to make the updating database part safer I was thinking that I would also put that in another thread and if its running when I send the abort exception I would wait until it is free and then stop the timer, what do you think? does sending an exception to a thread halt all its created threads as well? because if so my plan wont work.
btw im alomst 100% confident that actually calling abort using my app while it is updating is impossible but I dont want there to be a bug present I know about.
anyway thanks again you have given me loads of things to try.

keeping a service and an activity in-sync

I'm working on a music player and I'm running my MediaPlayer object within a service so that I can run other stuff while the music is playing. For the most part this works. If I leave the activity for any reason (like hitting the "home" key), then go back, I BindService in OnCreate and this usually links me to the already running service and I can pick up where I left off. However, sometimes BindService launches a new service and the original becomes orphaned. Then I've got two songs playing on top of each other and I have to kill the whole process with a task killer to stop the orphaned service. I can't seem to figure out what set of conditions causes this so it's difficult to debug.
Any ideas?
After tons of searching, I found some informative posts over at stackoverflow.com. Seems that if you bind to a service using the default ContextWrapper, you can get a different context with a different instance of an activity. If you use the application context (from GetApplicationContext) for binding, it should always bind to the same service.
Thank you for posting the solution.

[Q] Android app auto starts again when device rotated

Hello all,
I've written a simple audio player app and testing it in Samsung Galaxy S.
It is a simple app with can create playlist and some buttons to play the mp3 file.
However, there's a funny bug in it.
After starting the app, whenever I rotate the phone, the running app will launch another instance of the app. If I rotate again, another instance (3rd) would be started. So u can hear 3 copies of the same audio being played simultaneously.
What could be wrong with it?
Is there some code which can prevent program re-entry?
Thanks.
It's not a bug, that's the way andorid OS works. You need to account for this in OnCreate for your activity. I assume you are spawning off the actual playing of the MP3 in a thread or service. You need to check if the service is already running in OnCreate and attach, else spawn a new one.
Hello Gene,
How do I check if an activity is already running?
I could not find the answer on the android developer page (the topic on application fundamentals).
And no, I'm not converting it to a service yet as this is my first app.
Haven't explore service yet.
Thanks.
I read on another article, a simple way to prevent this is to add overwrite the onConfigurationChanged function
@Override
public void onConfigurationChanged(Configuration newConfig) {
//ignore orientation change
super.onConfigurationChanged(newConfig);
}
and modify the androidmanifest.xml
<activity android:name="selectCategories" android:configChanges="orientation|keyboardHidden"></activity>
But it still launch multiple instance of the app.
Thanks.
This is a good question and should be in an FAQ somewhere.
As already mentioned, changing the display orientation basically restarts your app. Read the Android dev page on Activity lifecycle for more info.
A short answer for your question is: the Bundle parameter for onCreate() will be null when your app is first run. When your app is paused and restarted, that Bundle will be non-null. You can store data in that Bundle by overriding onSaveInstanceState(), then check for that data in onCreate(). It's a good idea to learn how to do this (save/read app data on pause/restart). Once you start testing apps by rotating the display at various times, you'll find a lot of them FC at unexpected places.
This is indeed a topic that keeps surprising people who are new to android (ahem, like me 4-5 months ago ).
The solutions above are perfect, however in certain situations there's another trick that might make your life much easier. I suspect it won't help you in this case, but it might help others who tackle the problem and see this thread.
Certain applications, mainly games, should be fixed in a single orientation. I.E. you won't be playing angry birds on portrait - that game is locked to landscape, as it should be. In order to lock your activity in a certain orientation you add this attribute to the manifest under the Activity tag. So a standard activity might look something like that, combined with the ignore tag from the previous posts:
Code:
<activity android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden"
android:name="whatever">
The great thing about this combination is that your activity will not restart at all when the phone is rotated. Of course, for a standard activity you'd usually want to support both landscape and portrait, but if you need your app to be in a fixed orientation this is the way to go - no weird FCs or annoying bugs
Hi,
How do I check the bundle?
And also, what to do if the bundle is not null? Just return?
Thanks.
regards
r_p_ang said:
This is a good question and should be in an FAQ somewhere.
As already mentioned, changing the display orientation basically restarts your app. Read the Android dev page on Activity lifecycle for more info.
A short answer for your question is: the Bundle parameter for onCreate() will be null when your app is first run. When your app is paused and restarted, that Bundle will be non-null. You can store data in that Bundle by overriding onSaveInstanceState(), then check for that data in onCreate(). It's a good idea to learn how to do this (save/read app data on pause/restart). Once you start testing apps by rotating the display at various times, you'll find a lot of them FC at unexpected places.
Click to expand...
Click to collapse

Communication between Service & Activity

Hello
I want to create an Android App. In the last days i read a lot of Android API Documentations, Tutorials and "how do do's". Now I'm really confused, because on one hand, it's nice to have so many possibility, but on the other it confuses me, whats the best way to do it. So I played a little with Activity life-cycle.
Now I'm going to start to build my first 'real' App.
This App should download initial data from a Webservice, process these data with a database, download more data related to results from a database, save these data again to database, and make it accessible in the Acitvity.
So please correct me if I'm wrong from this point on:
I assumend that a Android Service is the best way, to process these Data in a background-worker-thread.
So far so good. So I read about the Android Handler which seems to be a pipeline, so Threads can work on the Handler message queue. I can Access the Service from within my MainActivity over the ServiceConnection.onServiceConnetcted where I recieve a simple Binder which gives me access to my Service. From there i can put Messages in the Message queue from the HandlerThread. But how I can tell my Acitivity from within the Service, that it has finished Processing and send the Data to it?
I read that I don't have to use AIDL since the Service is running in the same Process. But How can I do it then? I tried to call onBind() in the Service, hoping OnServiceConnected will be triggered in the Acitvity which initially Binds these Services, but it doesn't seem to work. I also tried to "hack" the Funktionality, by spending my Service a singleton member "MyMainActivity" with corresponing static setMainActivity(MyMainActivity activity), calling it in the ServiceConnector onServiceConnected, with the same result: Runtime Error
I even don't think I understand the functionality behind these HandlerThread.
will it loop infinitly waiting for HandlerMessages while draining the Battery, or is it on a wait() status since it recieves a message?
I read the Android API about Services but for me, it seems that they only describe to Access the Service from the Activity, and not the other way round.
If I call a method of my Service within my Activity over the ServiceBinder, which has a return value, but was started in another Thread in my Service, how will my Activity know that it processes finish? 'busy waiting' on a boolean member of my Service doesn't seem to be the way to go. If I do that, like I saw in a tutorial, I don't see a reason not to do the work in the Activity Thread itself.
I read also about an AsyncTask, but this doesn't seem to be practicable for me, because I have to do different work related to JSON Objects I get.
Please you expirienced Android guys: show me the way.
You probably don't need a full-fledged service if you just need a background thread. Services can run independent of an activity and reconnect, etc. If you don't intend for the thread to be stand-alone, then just use a class that implements Runnable. Since you seem to have a handle (no pun intended) on handlers, this won't be too hard. Just post a message to your handler from your thread to let the activity know what's going on.

[Q] Debugging help needed

I have a user of my app who is having a problem running it. My code launches another activity in the same app, and he is saying it is stopping before it should & returning to the previous activity, and he doesn't see any Force Close warnings.
I have run my code in the emulator & on my phone, I can't reproduce the error. We both run Android 2.2 on our phones, his is an HTC EVO & mine is a HTC Wildfire, as far as I can tell his specs are better than mine so shouldn't cause an issue - I deliberately chose a low spec for for my dev work so the code ought to run on anything.
As a bit of an Andoid dev noob (but been coding for years), is there any easy way I can make a special build of the app to send to him that would log any errors that happen ? I'd like to get a stack dump as well if possible, as I'm not sure exactly what routine in the activity its crashing out in. The activity that crashes is Gallery with 9 images in it, he can't flick through them or select one. I'm stumped as to whats causing it, any assistance would be gratefully received.
Thanks.
Why not point to your app and let others here try it on their phones? It could simply be other apps installed on his phone interfering with your app.
Long time programmer here too and when I get to where you're at (and I"m sure you've put some hours into this LOL), I go back to STEP 1.
I comment-out any and all code but the bare minimum; break it down to the Intent, startActivity and maybe a Toast message in the second activity. Even parse down your XML files to bare minimum.
See if that works. Then, ADD BACK ONE LINE OF CODE AT A TIME Run program and make sure it works. Yeah, it's painful, but in my 20 years of coding, I've learned to put my pride aside and to not "pretend" all the code I've written is correct.
Sometimes on bigger projects, I"ll change or add a couple of lines of code, run a back up and test. Rinse and repeat LOL. That way, I know I"m only a couple of lines of code from what "used" to work.
Good Luck!
Thanks both of you.
old_dude - Its a paid app. Only £0.99 but I don't think people would pay to help me. There is a free version of the same app (with less functionality) that this guy can get to work. If your really interested the 2 versions are -
Plink Log - Free Version
Plink Log Pro - Paid version
Rootstonian - agreed thats the approach I'd normally take if I was having problems on my dev phone or the emulator. The problem is that its OK on my HTC Wildfire/Android2.2 but on this guys HTC EVO/Android2.2 its having problems. I dont really want to keep sending him .apks with 1 or 2 lines extra enabled just to see if that fixes his specific issue. I was hoping there was something I could code to catch whatever crashes the activity & log it somewhere for me to analyse. When I do PC dev work, I have a global exception handler that catches anything I dont explicitly handle, and dumps the full call stack into a Log File I can read later.
I think I'll just have to take the existing app & put loads of debug code into it to save messages into a log file & see what bits of code are being called & what isn't & then get him to email me the results.
Thanks for the ideas guys, its always useful to get input from another perspective.
Dave
Hmmmm, just discovered setDefaultUncaughtExceptionHandler - might be able to use that with printStackTrace. Sounds interesting.

Categories

Resources