A week ago, for a week I tried to have an app I'm making completely independent detecting call states. I'm on Lollipop 5.1, so I can't use PRECISE_CALL_STATE that exists from Marshmallow upwards. I'm restricted to the usual CALL_STATE_RINGING, OFFHOOK and IDLE.
My extensive research (majority here on StackOverflow) with Google's help made me realize there's possibly no other way of detecting call states without these 3 on Lollipop or lower, or without system permissions on newer Android versions. There are very precise call states on all firmwares. But from a thread here on SO, it seems they can only be used by the current phone app (which I won't replace - will still be the normal Phone app). So no way to use those states in this case, it seems.
I'm also writing this question and answering it right away because I was able to make something which works just fine for me with the app I'm making. If it were a phone app, it would have to be more precise though. But in my case, I don't mind at all.
And as I see so many questions about parts of this question, I decided to put it all in the same question and answer it with something I tried to do and went well enough for me, and hopefully for some others. Feel free to suggest improvements and/or post other solutions!
If I did anything wrong on asking and answering right away please correct me. I never did this before.
With what I wrote on the question in mind, I was forced to use these 3 states, or use the call history. As I wanted the app to be as independent as possible, I tried to make the app detect the
PRECISE_CALL_STATEs from itself. Except when there are too many calls. In case they're 3 or more, I must go get the call state of some from the call history (except one case if there are 3 calls, which is explained in the code). I just can't detect calls on hold, sadly.So far I can detect the following cases:
And this is the code which I made to make this happen. By the way, as this has some lines already and I found out Stack Exchange network websites have an automatic license, then add this one to it (as I say in my profile), so anyone can do whatever they want with it, including copy-pasting (may or may not take time to understand, since when I did this first without comments, I had a hard time understanding what I had done):
Hope this is big enough to worry about license issues. Saw about this a week ago and I've began to think when to put license notice of CC0 on code I post. If it's not necessary here, please tell me so I can improve the "detection" next times.
I call this from inside TelephonyManager.listen() method, when the phone state changes. That method I have in a constructor of a class which is instanciated on a service that never stops and it's the main service of the entire app. Basically, this object is always on memory. Read method description there to know what to do with it. Hopefully I explained decently. If I didn't, please tell me what I can explain better.
If anyone has a better solution, please feel free to share! I'd appreciate it! A better way than this one that I see is on every phone state change, go see if there was a change in the call history, depending on which change it was. But that would take even more time from me and I don't have enough for that. A week for this was already too much, since I had to borrow my mother, father and brother's phones, and sometimes the house phone to get to this hahaha. And they're not home all the time.
I'll leave a GitHub link here for the rest of what is needed to understand the code completely. I talk there about case number X and Y, for example. That's here: https://github.com/DADi590/Detect-better-call-states-on-Android, along with ideas that I had and didn't work or that I had but will not implement for lack of time.