I am working on a test application that is going to be used for automated bluetooth device testing. My application basically connects a phone to a Bluetooth device so that the device can be tested with an Android device, the nature of the testing isn't relevant to this question really.
My issue is, one of the Bluetooth devices I am working with has voice prompts that will speak the name of your phone contact when getting an incoming call from them. In order to do this the Bluetooth device needs access to the Android's phone book. So the first time the device connects, I get a dialog message that pops up with a Phone book access request, saying the device is requesting access to contacts and call history. I am trying to find a way to respond to this request inside of the test application, the idea of this application is that it is supposed to be automated, so I don't want to have to have somebody come by the phone and click yes to this request, but I definitely need to respond yes or else the voice prompts won't work properly.
I am able to find when the request pops up using the onWindowFocusChanged function, and I confirmed using the debugger that this function is called when the request pops up. At first I thought maybe I could dismiss it with ACTION_CLOSE_SYSTEM_DIALOGS, but as it turns out this won't work, and even if it did dismiss the dialog (and it doesn't dismiss it), according to the documentation this Intent only requests that a dialog is dismissed and ultimately the dialog will decide how it wants to handle that.
//This function will be called when the dialog is shown.
#Override
public void onWindowFocusChanged(boolean isTrue) {
super.onWindowFocusChanged(isTrue);
if (!isTrue) {
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
this.sendBroadcast(closeDialog);
}
}
Dismissing it isn't really what I wanted to accomplish anyways because I want to be able to chose the yes option so my device gets access to the contacts properly. My other idea, which is sort of a hack would be to just figure out where on the screen the notification is located and inject a touch event at the location of the yes option. This is not really how I want to do it because I would have to basically figure out the location with trial and error because I don't believe I can get access to the dialog from inside an app to figure out it's exact location. Also it would constrain me to only being able to use whatever specific devices I took the time to find the coordinates of the yes button.
Any ideas?
Related
I'm trying to get an idea of what's possible and what isn't in terms of using a custom dialler app for internet calls.
The idea is that the standard Android dialler be used when no internet connection is available, but use a custom-written VOIP dialler / caller app whenever an internet connection is available.
I see that in the Android call settings you can set it to use Internet calling whenever a connection is available. How does this work? Does this simply tell the native dialler app to use internet calling, or is there actually a specific Intent or something that gets fired when an internet call is made so that I can open my custom SIP app?
And also, is the 'standard phone app' icon always linked to the standard phone app, or can you override this phone icon to open your custom VOIP app when a connection is present?
So basically, is there a way to seamlessly and automatically switch between the standard dialler and the custom SIP dialler based on whether or not the phone is connected to the internet?
If not, is this something that could be done by customizing Android?
Thanks,
There are four possible ways of doing what you want that I know of:
1. Replace the Android Dialer
This is hard and a lot of work. The Android Dialer (last time I checked anyway) WAS the telephony stack in Android. So to replace it you have to replace the complete telephony stack (including any public API) i.e. handle all cellular (and now sip) calls in and out of the device. Also the only way to replace it is to root the device as it can't be replaced normally.
2. Provide your own Dialer that is separate to the main dialer.
This has it's advantages that you will never get into "trouble" with anything else.
3. Hook into the outbound call API (ACTION_NEW_OUTGOING_CALL)
This is something that is pretty cool and I haven't seen any other OS allow you to do. Basically you can trap when either the normal dialer starts to dial a number (or when another application starts to dial a number as well) and you can either allow it through, modify it or cancel it. Behavior I've seen from sip clients is that they will cancel the call and put up a selection screen prompting where you want to send the call (sip, cellular or something else).
Here is an example of it's use.
The downsides are:
You can be fighting with other applications to which gets first go. There is a 'priority' setup, but all I've seen is everybody wants to be number one.
On some Android devices where the OEM providers that own Dialer, they don't always fire it!!!
4. Detect when the dialer is shown and show your own dialer in front of it.
This works and does allow you to provide a nicer more integrated feel as you can provide call type selection within the dialer, as well as other custom number lookups but that can be a little tricky to do on some devices.
I would suggest 3 to begin with as it's pretty easy to do and you can get something up going pretty fast. In code that I have worked on, we have done 2, 3 and 4 and also looked into 1.
I have implemented the RecognizerIntent and called google's voice recognition service and it works fine and i get results. However, sometimes if i mumble or am too far away from my device i get the message "Didn't catch that. Try speaking again." message. Is there a way to bypass this and not show this message as i don't want the users to have to press OK to continue?
Thanks
Use SpeechRecognizer if you want to be in control of the UI.
If I understand correctly then you are launching the RecognizerIntent and this gets handled by one of the activities in the Google Search app (or Google Voice Search, or whatever it happens to be called currently). Now, since this is an activity, it takes over the UI, i.e. it pops up a dialog box, shows a prompt and a VU meter, etc. In case of an error condition, it could in principle return control to your app by sending one of the error codes e.g. RESULT_NO_MATCH (as the documentation suggests), but it chooses not to. Instead it pops up a "try again" message. The only way to return to your activity is by pressing BACK, or hoping that the recognition succeeds.
If you want to control more of the user experience then use SpeechRecognizer. This way your are calling a service and then interact with it via callbacks. You will be in full control of the UI. Or almost, e.g. the Google app makes a beep when the recognition starts, and there is no way to turn it off and provide your own beep.
Note that this answer is specific (to a specific version) of Google's voice recognition service which is not part of Android proper. It implements part of the RecognizerIntent/SpeechRecognizer API but its different versions differ in the API coverage and their exact behavior. So this answer might become wrong in the future.
I have developed an android app that uses a timer with a call back. When a specific criteria has been satisfied, the app either rings or vibrates the phone depending on user settings. It will continue to ring until the user acknowledges an alert box. This all works fine. However, if the user has brought another app to the front then he may not realize it is my app causing the phone to ring and re-open it. Is there a way I can force my App to the front or at least the Alert Message to be on top of anything else?
Notifications are your friend. They wont interrupt a users workflow and with the new JellyBean apis you can put actions and other dynamic components in them.
Instead of doing that, you could just use a notification with a specific ringtone once it has been sent instead of annoying the user this way.
My first question, (but long time lurker on StackOverflow) so please don't be too scathing.
I am creating an Android App that has the capability of using a web service to update an SQLite database. Of course, this can only happen if the phone has internet connectivity. I understand how to navigate to the phone settings from the App, but I would like to know if the phone is now connected to the internet upon the user returning to the App.
I have considered using the onStart() and onResume() methods, but is there any way to determine where the user 'came from'. A good example would be the Google Maps/Navigation App. If the user is in Google Maps and presses the Navigation icon, it opens the Navigation App/activity and if GPS is not on, a dialog box shows asking the user if he or she wants to be taken to the GPS settings. They can choose OK, turn on GPS and press the back button to return to the Navigation App. If GPS is now on, they can proceed, otherwise the App shows the dialog box again.
This is good, except the user is allowed to continue, in my case, if there is no internet connectivity. But if there is initially no connectivity, and the user goes away and turns it on, and comes back, then I want to call the method to call the service.
I only want the internet check to happen on opening the App, and upon returning from the phone settings. If I use the onStart() method, the check will happen every time the user opens the activity.
So my question is, how do I check that there is internet connectivity only in the onCreate() method AND when the user returns from the phone settings?
Thanks in advance.
I am looking to add a Notification when the app is started. That will ask the user if they have a WiFi or unlimited connection. If they pick yes then they can go into the app, if no then the app closes with a message 'Try again later...'
To find out if wifi is available, you don't need to ask the user, you can ask the OS to give you that information using this method:
http://developer.android.com/reference/android/net/NetworkInfo.html#getTypeName%28%29
If you wish, you can also check if there is a connection using isConnected() and if you want to test if the connection is working, you could make a network call to confirm.
If you want to have the user confirm (I don't think you need to) then create an activity that runs when the app starts, it asks them to confirm, and then depending on their selection either starts the app's main activity, or shows a message and exits.
I don't know the details of your app, but if it were me I would probably:
- Automate the network detection
- If there's no network, run the app as usual, but just grey out and disable the main UI, and show a message like "Please connect to a Wifi network".
- Consider including a user interface within the app that the user can use to turn on wifi.
I think that's much tidier than just exiting the app, as that means if they get the "no wifi" warning the app assists them by providing an option to enable it.