VoIP, or Voice over Internet Protocol, is slightly different from a regular cellular phone call, but both types allow you to call someone. Regular cellular calls will connect you to another device by routing you from the nearest cell tower to the other device through the phone number you dialed.
VoIP utilizes a data connection, which could either be Wi-Fi or mobile data. To execute a VoIP call, you need a back-end service that can handle routing calls to other VoIP users, usually by the username they registered with. Once you've established a connection with a service and another user, your devices will begin exchanging data packets with the service. The protocol that is used to support VoIP is called Session Initiation Protocol (SIP).
This back-end service could be hand-rolled by a server team, but there are many great SIP service providers out there such as LinPhone, which even allows free registration. You can also utilize services such as Cisco Unified Connection Manager (CUCM). Have questions about setting up CUCM environments for your project? There are a handful of teams over at the ATC who can help.
In what ways can we leverage VoIP on Android?
Android SDK support
Android has support for VoIP directly in the Software Development Kit (SDK). The APIs provided by the Android SDK are a little bit dated and hard to work with, quite like the Android Bluetooth APIs. It's even a little bit tougher than Bluetooth since it has even less documentation and resources than the Android Bluetooth APIs.
We've proven that we can get these APIs to work by making an in-app VoIP call to another user with the app open, but the call quality was lacking and we had trouble figuring out how to improve the call volume.
Third party libraries
There are very few third party libraries for using VoIP on Android. The best one we found and tested was the Mizu-VoIP library (also known as JVoIP). This library has pros and cons, though the pros might outweigh the cons.
This library is quite dated, written in Java and the source code is incredibly immense and nearly impossible to sift through. The documentation is also lacking heavily in some parts, leaving a lot of debugging, guessing and checking.
There is a licensing fee to use this library. This fee ranges from $500 up to $3,900 depending on your needs. The library does a decent job of hiding most of the VoIP pain away though. While the APIs are pretty finicky, once you get to know them a little bit, it becomes more clear how to use them.
For more information on this library, including documentation, visit their website.
Native SIP calling
There is also another option which is the most straight forward, has the best call quality and reliability and is the quickest to implement. In Android, you can launch a phone call directly from your app using the Android SDK. This means you can start a VoIP call at the touch of a button that utilizes the native Android phone application.
There is a little bit of set up work to do on the device though. You'll need to go into the native phone application on the device and enter your account information for your SIP service provider. This is fairly easy and only takes a minute or 2 to get the settings correct. The only problem comes when a customer may need hundreds or thousands of devices configured regularly.
We haven't yet figured out an automated process for this. There is a great possibility that a Mobile Device Management (MDM) solution could provide this automation for us, but that wasn't explored for the purposes of our project.
Why Native SIP calling may be the best option
As stated earlier, native SIP calls are incredibly easy to make. A new Hello, World! app could make a native SIP call with less than an hour worth of writing code, and the call quality is that of a real phone call with no extra effort. The other two options listed above took weeks of writing code before a proof of concept was available, and even then the call quality was pretty poor.
Simplicity also implies maintainability which is incredibly important. Handing a project over to the customer to maintain, at any stage in development, is invaluable. With less cleaner code, the customer should have no problem clearly seeing the flow of events.
Being maintainable and using Android's built-in phone app means we indirectly get all of the benefits of Android software updates. This is good for two reasons: (1) Android constantly updates their OS for security reasons and (2) since you would be using Android's build in phone app, you would get these for free while maintaining functionality.
What if my client wants custom interfaces and app behavior?
Don't worry! While the actual in-call app interface can't really be changed (because it's a native device application), there is so much you can do to deliver a custom experience with features stacked on top of it in a custom Android application. The app you are writing for your client isn't just limited to placing calls. It can function just like any other custom app on top of that native layer.
What if they want custom in-call behavior?
This might be the main argument for pursuing either Android SDK VoIP calls or using the third party library I mentioned earlier: custom in-call behavior could be defined as wanting a custom in-call UI, behavior that doesn't exist in the native phone application or other complex features (such as video calls, conference calls, etc.).
There are many options when creating an SIP/VOIP app natively on Android. There are also a lot of unknowns when developing a fully custom application due to the ambiguity of the Android documentation and the lack of example code out there.
Ultimately, Native SIP calls that are routed from the app through the Native dialer application is recommended. This will provide the easiest and quickest development lead times and will give the user a typical and familiar Android experience.