I'm looking to intercept calls in order to block all calls from numbers not stored in Contacts and to avoid all sorts of notifications set by default Phone app – in status bar, on its icon (number of missed calls), etc.
All devices are Samsung Galaxy Core Duos, so I have Blocking mode as an undesirable way of blocking all calls from numbers not stored in Contacts. My main problem is finding a way to disable (avoid) aforementioned notifications. I know I can empty my call log, and I am doing it, but notifications stay, both in status bar and on icon. That being said, I believe either both or none can be solved.
Is there a way to do this for rooted devices running Jelly Bean?
Since there's no proper way of using abortBroadcast() in this case, as android.intent.action.PHONE_STATE is not being received via an ordered broadcast (no system's sendOrderedBroadcast() call, like with received short message, but plain old sendBroadcast() instead), all receivers must receive this intent "at the same time".
To make my goal possibly impossible, as far as I can see, things start happening even before the broadcast. Furthermore, nothing "legally receivable" happens before the call to sendBroadcast(), as thoroughly yet briefly described in this blog post. By the way, this post was submitted in 2009. Has anything related to this problem changed since then?
Is it possible to solve this using shell? If yes, how?
The code that's emptying call log is the following:
context.getContentResolver().delete(android.provider.CallLog.Calls.CONTENT_URI, null, null);
I have permissions needed (for instance: WRITE_CALL_LOG, READ_CONTACTS, WRITE_CONTACTS) and this works. Call log shows to be empty when I touch Phone app icon or status bar notification.
I solved it using this piece of code:
Runtime runtime = Runtime.getRuntime();
try
{
runtime.exec("service call phone 5 \n");
}
catch (Exception e)
{
e.printStackTrace();
}
It marks call as ended, instead of marking it as missed, and ended calls do not show notifications of any kind.
If 5 doesn't work, try some other digits, like 4, 6, 8, etc.
Related
I have added to my phone authentication to my sign up process, in a send code activity - which sends the sms code to confirm the phone authentication process. Then, I have also added a "go-back"/"return" button which moves the user back to the main activity.
If I make the following request which sends the user a sms code to his phone:
PhoneAuthProvider.verifyPhoneNumber(options);
I won't be able to make another request before the defined timeout duration ends. Therefore, I thought about the easy and not messy approach, that would be to cancel the ongoing request, but unfortunately couldn't find how to do so, if even possible nowadays. I have also saw the unanswered post here: Android Firebase OTP auth: Is there a way to cancel OTP code request programatically before the actual timeout?
Couldn't work with this, even though it's what I am looking for, but it has no related answers.
Note: I am programming my project with Java and not Kotlin.
I have also thought about the second approach, which is to save current activity's phone number and then extract it with onRestoreInstanceState and onSaveInstanceState, then resend a code sms again. But of course, it's much more complicated and messier.
It is possible to cancel an ongoing verification request by calling the verifyPhoneNumber method again with the same phone number, but with the forceResendingToken parameter set to null. This will cancel the previous request and allow to start a new one.
It is also possible to use the PhoneAuthProvider.getInstance() method to get a reference to the PhoneAuthProvider instance, and then call the verifyPhoneNumber method on that instance instead of calling it directly. This allows to call the verifyPhoneNumber method multiple times without canceling the previous request.
Timeout duration for verification requests is typically around 5 minutes, so if you want to allow the user to request a new code before the timeout expires, provide a way for them to do so, such as by adding a "Resend code" button to the app.
Overall, it's best to design apps in a way that minimizes the need for canceling ongoing verification requests, as this can lead to a confusing user experience. Instead, focus on providing clear instructions and options for the user, and consider using the getInstance method to avoid having to cancel requests altogether.
The PeriodicTimeRequest has a minimum periodic time of 15 minutes. But I see, that for example Google Maps location sharing can update more frequently than that, and facebook messenger can also receive messages almost instantly.
I would like to send a notification to the user, when it got a new message. My application has to work on local network, so Firebase is not an option. I have to send a json request to the server, and if there is a new message, I show a notification to the user.
Regarding FCM:
FCM, which is available in all devices with Google Play takes the weight of subscribing to and receiving push events, under all the resource constraints Android has been ever introducing.
It's tightly coupled with the OS and is unified (one entity, one persistent connection for all apps in your device), which is why it works :)
Regarding Frequency of your Work:
Given your requirement of more frequent pings to the server, you'd need to have a service which runs all the time, i.e. A Foreground Service.
It is resource consuming though, so good luck convincing the user with a good reason why it should stay alive all the time.
I think you've managed to make the client-server interaction possible, since identifying a server in a local network is a huge task in itself.
use this in your service.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
CountDownTimer timer = new CountDownTimer(15 * 60 * 1000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
// execute your task here, every sec
//if you want increase the count down interval from 1000 to what you want
}
#Override
public void onFinish() {
this.start();
// it will start again.
}
};
timer.start();
return START_STICKY;
}
I am afraid it is not going to be possible without using a set of workarounds. Which means you might not get a consistent behavior.
#Arvind has done a very good job explaining the benefits of a Firebase Service and it is the recommended approach for achieving such task.
First I'd like to point out that such restrictions on the WorkManager exist because Android has been suffering (between other things) of developers trying to abuse some mechanisms to get their software working and at the end of the day, the battery of the users had been suffering from such abuses and since Android 6 Google has started trying to address these issues. There's a good read for you over here about Doze mode and how to work with it
I am pointing this stuff out because I've been trying to build a chat service that wouldn't rely on Firebase and I really don't want you to waste as much time as me banging your head against a wall. There are things that you simply can't fight. That means that if the device enters in a "deep-sleep" mode sometimes you can only accept it.
My approach
Please
keep in mind the user interests and the life of their batteries and try to be as smooth as you can with their devices and this is just a workaround over the restrictions that have been imposed upon us. And that I discourage this approach due to the amount of work that it takes to pull off and for how misused it can be.
My solution
Essentially, to get notified (ie getting your code running) in an Android App you're going to be wanting to receive system events or Broadcasts. This is where you set up a BroadcastReceiver and you get Intents delivered to it and you can act upon them accordingly. BUT YOU HAVE TO BE QUICK BECAUSE YOU HAVE ONLY 10 SECONDS OF RUNTIME BEFORE THE OS KILLS THE PROCESS AGAIN. Ideally you would have a really quick server so you can have very little IO times to ensure you can be within 10 second restriction as frequently as possible.
So essentially you would be using a combination various of services that you would like to be monitoring in order to get notifications (aka Broadcasts) whenever the state of those changes. Here are a few ideas:
WiFi state (which will also be useful to see if you can reach your local server)
Bluetooth Low Energy packets (or Nearby which may solve the entirety of your problem depending on Nearby's capabilities)
WorkManager as you already pointed out.
AlarmManager to schedule a broadcast of intents every so often.
Geofencing (although it involves reading the user's location; you can set really small geofences around the office building and get notified by a Broadacast when users go through that geofence)
So whenever you receive a Broadcast of these sources you would handle such notifications from within the same BroadcastReceiver
From the implementation body of this Broadcast receiver you would poll the local network's server to check whether if your user has new messages or not and lift up a notification. And it's important to keep the amount of work and IO times the app has to do at a minimum since those add up and you've got only 10 seconds.
You can get around the 10 second mark if you launch a ForegroundService. Then, that period of time is going to be extended until a 10 minute mark and you will need a visible notification for the user stating something that you're checking if it's got any new messages.
Keep in mind
Don't stress the user's battery too much. Or Android will penalise your app and you'll end up notified less often or even completely not notified.
Be gentle with the user. If the user has to force-kill your app at some point it will stop receiving any sort of Broadcasts or running any sort of WorkTasks.
This solution can behave differently accross devices. Since the decisions of notifying your app are made by the OS, different OS (redmi, samsung, meizu...) you are likely to not end up with a consistent behavior across all devices
You don't have control over things, the OS does
Within measure, try to time your Broadcasts to your BroadcastReceiver within spans of 3 minutes or so; so you are always receiving a Broadcast below the 15 minute mark.
I have written a managment application which has a function to put a bunch of events in multiple Google calendars.
On my computer everything works fine. But the main user of this application has a verry bad network connection. More percicely the ping to different server varies between 23ms and like 2000 ms and packets get lost.
My approach was, besides increasing the timout, to use an own thread for each API call and recall in case of an connection error.
And at this point I got stuck. Now every event is created. Unfortunately not once but at least once. So some events were uploaded mutiple times.
I have already tried to group them as batch requests, but google doesn't want events on multiple calendars in a single batch request.
I hope my situtaion is clear and someone has a solution for me.
I would first try to persuade the "main user" to get a better network connection.
If that is impossible, I would change the code to have the following logic:
// Current version
createEvent(parameters)
// New version
while (queryEvent(parameters) -> no event) {
createEvent(parameters)
}
with appropriate timeouts and retry counters. The idea is to implement some extra logic to make the creation of an event in the calendar idempotent. (This may entail generating a unique identifier on the client side for each event so that you can query the events reliably.)
I am writing an application in Java to make calls and view when people are in calls, their phone is ringing or are idle, using the library Jain-Sip and at the moment am trying to correctly implement presence with SUBSCRIBE and NOTIFY messages. I am able to get presence data to be received, but after a while the presence data stops being displayed by my program.
I believe this is because the overridden method "processRequest" is not being called. This is the earliest point in the program where NOTIFY messages are being handled and not even the print statements are being output.
The bizarre thing about this is that the notify messages are being sent when I make calls, and the presence data is there. I know this because I have done Wireshark traces when running the program.
Note: No exceptions are occurring during execution of the program, to cause erroneous behaviour.
If anybody has any insight into why this is happening, I would be very grateful.
Thanks a lot,
Adam
Make sure you add your listener class correctly. The only other possible cause would be if the NOTIFY is unsolicited, which should not be the case but it happens. Try to enable this flag gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY. See more about it here https://jsip.ci.cloudbees.com/job/jsip/javadoc/gov/nist/javax/sip/SipStackImpl.html
Otherwise you will need to attach DEBUG logs to figure it out, could be malformed request or something of the sort.
I can use this code to make outgoing call:
Intent dial = new Intent(Intent.ACTION_CALL);
dial.setData(Uri.parse("tel:5556") );
context.startActivity(dial);
But how to detect whether the call is picked up or the call is refused?
I tried PhoneStateListener, but it is not working.
Unfortunately, Android gives no mean to know when an outgoing call has been answered.
PhoneStateListener works fine but the 3 states notified by onCallStateChanged are not enough. An additional state like CALL_STATE_CONNECTED would be welcome.
There is an open issue requesting this feature but it didn't get much attention so far:
https://code.google.com/p/android/issues/detail?id=14266
Some people (like me) falls back using logcat and tries to infer if an outgoing call has been answered but this is far from an ideal solution.
I am also searching for an answer to the same problem, apparently no straight forward method is present to do this. But, I think we can combine a Call Log content observer with PhoneStateListener to get the call duration.
We could set a flag in the shared prefs when an outgoing call is started, if anything changes in call log and our shared prefs flag is true we could get the call duration from the call log to see if the call was ever connected :)
You can Check these Duplicate questions:
How can my android app detect a dropped call?
Detecting outgoing call and call hangup event in android