Making Simultaneous App-to-Phone Calls (Android) - android

We are developing a new app using the sinch voice api to make app-to-phone calls for Android.
We’ve tried the sample project and everything works brilliant except that we can’t make simultaneous calls with the same app. We’ve installed the sample project in 2 different android phones and if that 2 devices try to make a call with sinch at the same time one of them can’t make the call. We’ve tried with different users and even tried to create a production app in the sinch dashboard but nothing worked.
So what can we do to make this work? We have to create an app and generate api keys for every device that we are going to use in order to make simultaneous app-to-phone calls?
Thanks

I can see you already added my answer as a comment to your own question, but I'll add it myself anyway for any other person looking for the same question. I'm also adding information on how to set the maxDuration.
When your application makes a PSTN call, our system reserves a sum on your account to make sure you have enough credit to actually pay for the call. If you don’t specify the maximum duration for a call, we reserve 240 minutes X minute price to the destination. If you don't have enough credit on your account, the call will be denied.
Suggestion 1: Set maxDuration to a level you can handle (see below for info on setting maxDuration from the SDK)
Suggestion 2: Make sure you have enough credit on your account and also that PayPal auto top-up is enabled.
If you're using one of our SDKs you need to set a callback URL that our service can talk to:
Set a callback URL for you application on sinch.com.
When a user tries to make a call, we send you a callback to this URL. This callback is called ICE (Incoming Call Event) and lets you decide if the call should be allowed or not.
You need to answer our callback for the call to go through. The action to send back is called ConnectPSTN and you can read more about it here: https://www.sinch.com/docs/voice/rest/#ConnectPSTNAction Use the maxDuration parameter to decide the maximum length a call is allowed.

Related

Why in Google App Engine Always 11 secs of Latency coming only for the first requests?

I am deploying my Nodejs sample app to Google App Engine Flexible env and when I am using google app engine URL which is in the form appspot.com to hit my API, it is taking around 11 secs to send response from my mobile data, but other APIs are sending response in milisecs.
Also, the time delay is only happening when I am opening my android app and sending request to the server after that all requests are taking normal time, and again delay is coming when I again open the app and send request to the server.
Edit - I found that
This can be a caused when your application is still booting up or warming up instances to serve the request and can be called as loading latency. To avoid such scenarios you can implement health check handler like readiness check so that your application will only receive traffic when its ready
That's why I checked in my Logs that readiness check is performed sometimes around 1 sec
and sometimes around 200 ms
Can anyone please tell me is there anything wrong in warming up my instances because I don't think cold boot time is causing this problem.
Edit 2
I have also tried to set min_num_instances: 2 so that once loaded atleast my 2 instances will again not get boot up, but the thing is delay is again same.
Edit 3
runtime: nodejs
#vm: true
env: flex
automatic_scaling:
min_num_instances: 2
max_num_instances: 3
Edit 4
I am noticing a strange behaviour that when I am using this app Packet Capture to capture traffic, then all https requests (if I am not enabling SSL Proxying) and all Http requests are executing in milisecs whereas without using this app all Http/Https requests are taking 11-16 secs of delay.
I don't know how but is there any certificate kind of issue here?
Edit 5
Below I have attached Network Profiler where delay is coming 15 secs
Please Help
Depends on which App Engine you are using and how you setup the scaling, there's always a loading time if you don't have a ready instance to serve a request. But if you have readiness check to ensure your instance is ready (and not cold started for the request), then there shouldn't be a problem.
Can you find a loading request or any corresponding slow request in your logs? If not, then it's likely an issue with the app. If possible, instead of calling this API on your app, do it from two apps (one is already open, one is not). So you make calls from both apps and if you notice that the one that's already open is getting a response faster than the other one, that means that's a problem with the app itself. App Engine can't determine whether or not your app is pre-opened so any difference would be client side.
=== Additional information ===
In the your logs, there's no delay at all. The request enter Google and was processed within a few milliseconds. I am sure there's something application-side. Maybe your app is constructing the request URL (first request) from some other source that results in the delay? App Engine has no knowledge of whether or not your app is opened or not or whether it's sending a first request after being opened, it cannot act differently based on it. As long as your App Engine instance is ready and available, it will treat your request the same way regardless of whether or not it's your first request after the app is opened.
The issue is resolved now, it was happening because of network service provider which is Bharti Airtel, their DNS lookup was taking the time to resolve the hostname. After explicitly using alternative DNS like Google 8.8.8.8 the issue got completely resolved. Maybe it's a compatibility issue of Airtel with Google Cloud.
Last time I checked I remember having to put a warmup request handler so that Google would know that the instance is up and running and can be used to answer calls. Keep in mind that code has to be EXACTLY under the endpoint you specify in the handler under the yaml file. (Wouldn't be the first time someone forgets that)
Here are the docs https://cloud.google.com/appengine/docs/standard/python/configuring-warmup-requests this is python specific, but you can also check other languages like Go, Java, and such in the docs.
If the problem is client dependant (each time a new clients spawns and makes a call it gets the latency) then it is most likely, either a problem with the client app itself or with initialization, registration or DNS resolution.
You could also try to reproduce the requests with CURL or similar, and see if also with those you see the mentioned delay.

Keep Twilio clientDevice in memory on Android so call can be placed immediately

I am developing an app that is designed to allow emergency calls using Twilio - my code is derived from https://github.com/twilio/twilio-client-quickstart-android.
All I've done which is different to the GitHub code is create a separate AlertManager class that does the Twilio initialisation outside of an Activity.
At any moment a user must be able to open the app and tap a button which will (as quickly as possible) make an emergency call using Twilio.
My issue is that Twilio requires the creation of a clientDevice by requesting a "capabilityToken" from my server. That is fine, but the token expires after an hour.
Assuming there is always an external internet connection, how can I make it so my application always has a clientDevice (with a valid token) object available in memory somewhere, such that when the user enters the Activity to make an emergency call, they are able to do it immediately without the app having to request a new token nor create a new clientDevice?
From a quick test using Airplane mode and hard coding a valid token it appears the Twilio SDK can create a clientDevice as long as it has a token, i.e. only one network request is required to retrieve the token, rather than two if another is required to create the clientDevice.
I know I could use some kind of Service to fetch tokens, but I'm not entirely sure where I can store my clientDevice. It can't reside inside an Activity since the app will not always be running. I did wonder about creating my own Application class but as I understand it Android can and will create new instances of that class when it needs to which would then result in my clientDevice being removed from memory. Or is it possible to store it in the Service and then send some kind of broadcast to the Service to make the call?
I hope that makes some kind of sense and if anyone has any ideas it would be much appreciated.
Twilio developer evangelist here.
I have a couple of ideas about the token expiry.
First up, you can set the token expiry time up to 24 hours.
Second, you could use Twilio's AccessManager library that takes an access token and lets you listen to events for when a token is close to expiry or when it expires.
I don't know about keeping live objects while your application is in the background though I'm afraid. Hopefully someone else can help you here.

Android BLE BluetoothGatt.writeDescriptor() return sometimes false

I'm trying to write BLE Android app. I found that sometimes when I call
BluetoothGatt.writeDescriptor() it returns false.
I have not found in documentation any note of limitation to this function. But ppl on stack overflow says that I need to wait for BluetoothGattCallback.onDescriptorWrite() before I try to write another descriptor.
Here is one reply saying that BLE is busy with writeDescriptor() and can not do other write.
Here is another thread saying that you can not call twice writeCharacteristic().
My questions are
is it really true?
is there really missing some internal android API buffer for serializing BLE requests and every developer has to do it on it's own?
Is it true for different functions? For example when I call writeDescriptor() I understand I can not call second time writeDescriptor() before I receive onDescriptorWrite(). But do I have to wait for onDescriptorWrite() when I want to call writeCharacteristic()?
Also if there is inter-function dependency then what else function have this limitation (namely: readCharacteristic(), readDescriptor(), requestMtu()...)?
And additionally is there interdependency between BluetoothGattServer and BluetoothGatt. So for example when I call BluetoothGattServer.notifyCharacteristicChanged() shall I wait forBluetoothGattServerCallback.onNotificationSent before I can call BluetoothGatt.writeDescriptor() or BluetoothGatt.writeCharacteristic()? (BTW praise for google documentation onNotificationSent() is by luck documented properly. Doc says:
When multiple notifications are to be sent, an application must wait
for this callback to be received before sending additional
notifications.
Lastly having all this questions - I feel that Android BLE API is under-documented. Or am I wrong and there is documented somewhere what are allowed methods calling sequences? If yes can you please point me to such documentation? If not is there some channel we can open issue with google and ask them to add to documentation something? I mean it may not be much text - some function like onNotificationSent() is arleady properly documented. They just need to copy this sentence to other functions.
The documentation lacks information. However you can read the source code to find out the rules, which (currently) are the following:
For each BluetoothGatt object, you can only have one outstanding request at a time, including requestMtu, readCharacteristic, writeCharacteristic, readDescriptor, writeDescriptor and executeReliableWrite. So if you issue a read request you need to wait for the read response before you issue a write request. While they implemented the code that returns false if there is an ongoing operation in BluetoothGatt.java, they forgot to do this for requestMtu, so if you have multiple requests at a time where requestMtu is one of them, you will get random errors sooner or later (in the latest versions at the time of this post).
So yes, every developer has to manually serialize the requests. Note that the Bluetooth stack actually has a queue of requests, but it is limited to only one request per client (i.e. BluetoothGatt object). So if two apps on the same phone talk to the same device simultaneously you will never get "busy" errors. The only exception is if you use Write Without Response for which the current data flow implementation is quite buggy (see https://issuetracker.google.com/issues/37121017 which Google seems to have ignored).
You can send notifications at the same time as you write a characteristic, since the server and client roles are separated.
Regarding updating the documentation, you can always try to file an issue at https://issuetracker.google.com (but I get the feeling nobody reads that), or, since Android is open source, send a pull request to https://android-review.googlesource.com/ which updates the Javadoc from which the documentation is generated.

Is there a better way than making getPurchases call on every app startup?

I have an app which provides in-app purchase to unlock few features. Based on which features are purchased, the app might need to switch layouts. So, the main activity on start makes this check by calling getPurchases(). Since this call is over network so I need to show a loading dialog until I get a response. I can then store this info in memory for the rest of the session.
However, my worry is bad user experience. Every time the app starts the user will be greeted with the loading dialog, which seems bad. Furthermore, if at that moment if the internet is down then the user could be stuck at loading for a really long time (until that times out), and then the app will behave as if he did not make any purchases.
Alternatively I can choose to store the purchase history as flags in Android sqllite DB. So, the app will fetch the details from Google Billing API if that is not already in DB. If the flags are set then the app will skip this check. However, my worry is that users with rooted phones might then be able to simply turn on these flags.
How are fellow developers handling this?
I'm following the android developer training for in-app billing, it doesn't seem like you're following the same documentation, because there doesn't appear to be a getPurchases() method. Nonetheless, you are right to be concerned that network calls have a negative impact on the user experience and this can be avoided by threading. There's no need to right the code yourself, just following the android documentation and take a look at the sample code <<android-sdk>>/extras/google/play_billing/samples/TrivialDrive/src/com/example/android/trivialdrivesample, which will be available once you have installed the necessary packages.
As for your concerns about rooted phones, I suspect they cannot be economically justified, that is, the cost to defend your app will probably be greater than any expected loses due to rooted phones.

Android: How to determine if the number being called is valid or invalid

I have a big list of opt-in numbers.
Some of them are bogus or fake.
I need to write a small app that does the following:-
Read numbers from an excel file
Call each number: if the call gets through (the phone rings or is busy/engaged), we mark the number as valid in a new column in the excel sheet. If the number is invalid, we mark the number as invalid.
Is it possible to achieve this in Android?
Can we get the response status while making a call from the app?
Example: Status=Ringing, Status=Busy/Engaged, Status=Invalid etc
Is there a better way of finding if a phone number is valid or invalid?
You can't. You are unable to call any phone number other way than firing out an intent to invoke device's Phone app do the job, therefore full and smooth automation is hardly possible. You may try to do that and at the same time set up own listener to know if the call succeeded or not, but that's far from what you wanted.
You cannot do it in Android but you can develop it in a cloud-based IVR system using Call Control XML (CCXML) and a platform that has good call progress analysis, like Voxeo. Take a look at this Answer which provides more detail. Be careful with this type of solution as there are laws which govern automatic notification. Make sure people opt in for this type of notification/verification.

Categories

Resources