Replacing in call app - android

Background
I'm trying to develop a really simple in call app to replace the stock version. Basically, I just want to answer incoming calls and present the user with a really simple customized UI. There is no need for outgoing calls or any fancy stuff.
Searching the web I've found package android.telecom.incallservice (available in API 23). This service is implemented by any app that wishes to provide the user-interface for managing phone calls.
It seems promising but I'm having trouble getting it to work. I've created simple service extending InCallService and declared it in my manifest as described by the docs. However, I would expect to be able to change the default phone app in the settings to my own, but I can only find the stock phone app.
Code
This is the manifest declaration from the docs. I've replaced BIND_IN_CALL_SERVICE with BIND_INCALL_SERVICE since I guess this is a typo.
<service android:name="your.package.YourInCallServiceImplementation" android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
Questions
Is it even possible for third-party app to replace the default in call app?
Are there any sample implementations using this API out there I may use as a reference? I've found the google implementation, but this is a system app which makes use of some permissions that are not available for other apps (ex: android.permission.MODIFY_PHONE_STATE).
Am I correct in the assumption that after providing a correct InCallService manifest registration and a stub implementation I could expect to find my app under Default Apps -> Phone? Do I need to declare something else?
Thanks.

Is it even possible for third-party app to replace the default in call app?
Yes, starting with API 23 it is possible.
Are there any sample implementations using this API out there I may use as a reference? I've found the google implementation, but this is a system app which makes use of some permissions that are not available for other apps (ex: android.permission.MODIFY_PHONE_STATE).
The only one I'm aware of, is the sample I created https://github.com/arekolek/simple-phone that was already mentioned in the other answer as well.
Am I correct in the assumption that after providing a correct InCallService manifest registration and a stub implementation I could expect to find my app under Default Apps -> Phone? Do I need to declare something else?
Actually, no.
Like mentioned in another answer on the topic, you don't need InCallService at all to appear on that list.
What you need though, is to register an activity with two intent filters, one with a tel Uri scheme, and one with an empty scheme (having just one of them is not enough):
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<data android:scheme="tel" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
</intent-filter>
It is vaguely mentioned in the docs, and stated explicitly in AOSP code.
That is enough to appear on that list. Only then, to provide the UI for the call, will you actually need the InCallService.

According to the docs and as you comment yourself, you need to add this in your manifest:
<service android:name="your.package.YourInCallServiceImplementation"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
android:name must be replaced by the class that implements this service.
<activity android:name="your.package.YourDialerActivity">
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
android:name must be replaced by the class that implements the main activity for your own dialer implementation.
Here you can find more information about this:
https://developer.android.com/guide/topics/connectivity/telecom/selfManaged
And here's a sample project that you can use as a guide:
https://github.com/arekolek/simple-phone
And this: https://stackoverflow.com/a/49835987/1916449

Related

WearableListenerService only wakes up when I open my app

I have successfully implemented communication between my phone and watch app through WearableListenerServices in both modules. This works perfectly for the most part, however, if i don't use the phone app in a while the watch app stops communicating. This suggests the WearableListenerService is not "woken" up as expected. To fix this, I have to open the phone app and for the next while the watch app communicates perfectly again.
Is there a way I can guarantee that it will be "woken" up? Or am I missing something?
Phone manifest:
<service android:name=".app.util.ListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:scheme="wear" />
</intent-filter>
</service>
Wear app:
<service android:name=".util.ListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:scheme="wear" />
</intent-filter>
</service>
If you need more on the specific implementation of the listeners I'm happy to provide it, but it doesn't seem relevant. Thanks!
We all knew that the BIND_LISTENER for wearable app is already deprecated and it is replaced by a fine-grained intent filter. So make sure that you use a correct filters for your app. You can know the meaning and purpose of individual filters here.
Try to check this documentation for Building Apps for Wearables, it shows you how to use the WearableListenerService for your app. It also provide some sample code that you can verify if you properly implemented this code in your application.

Android detect usb storage for kitkat (4.4)

I've created a webview app which hosts a website within the app in the assets-directory.
I want to update the website via an USBstick inserted in my tablets usbslot.
I tried it first with the .MEDIA_MOUNTED broadcast which doesn't work for my android 4.4. Tablet.
I've searched for an alternative and found the "MediaScannerConnection".
There are several examples here, which didn't help me much, to solve my issue.
I'm looking for an easy and clean solution and a little explanation would be nice too, to detect if an USB-Storage is connected and the chance to execute some code afterwards.
And how make this USB-check run all the time is a question in addition. I assume i have to put it in the OnResume method, but i'm not quite shure.
Please post code for your BroadcastReceiver and AndroidManifest.xml.
Manifest should look something like
<application>
<!--- ... --->
<receiver android:name=".UsbBroadcastReceiver"
android:exported="true"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
<data android:scheme="file" />
</intent-filter>
</receiver>
</application>
Note the data tag, it's often overlooked.
In your onReceive implementation the URI to root of mount can be obtained from Intent#getData().
Also note that this will not work on Android 6.0 (M) and above. For 6.0 and above your code must request access to USB via one of two ways:
1) UsbManager#requestPermission
2) Intent#ACTION_OPEN_DOCUMENT_TREE as part of Storage Access Framework

Targeting Glass as well as tablets. Are multiple intent-filters required?

My current Android application defines its intent filter as:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
In order to extend the application to run on Glass, I understand that I need the following intent filter:
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
If I replace my existing intent-filter with the one for Glass, would my application still work for tablets and other Android devices? Or, should I leave my existing filter as is and add a new filter for Glass? Regards.
Few existing applications (any?!) have the user interface design and presentation required to be good GlassWare. I would recommend that you create a separate application, but share the underlying code as it makes architectural sense.
For those interested, my testing shows that you can support Google Glass as well as other Android devices by adding both the intent filters.

Interact with Android Setup Wizard

I am trying to develop a setup wizard for Android, as I would like to add some functionality to the one existing from Google. Is it possible to somehow interact with the Android wizard? Because when I have searched for information I've seen that not using Google's Wizard might cause some trouble, regarding gmail account activation and so on.
If not, could an activity be called immediately before or after Google's wizard? Would it be enough to just listen to the BOOT_COMPLETED event?
Thank you very much in advance!
I don't know how you will use this unless you are making a rom and can add your app to system but basically you make your setupwizard add-on a Home activity with action MAIN, and categories HOME,DEFAULT. You should also set the priority higher than 1. If any of this is unclear you can look at the Launcher source/manifest that is publicly available.
When your activity is done it should deactivate itself with the PackageManager (setComponentEnabledSetting) and that should be it.
You can add additional activities that start the first time the phone is boot up. You just have to mimic the same behavior as Google's SetupWizardActivity.
Here's the relevant portion in the AndroidManifest.xml for reference:
<activity android:theme="#style/InvisibleNoTitle" android:label="#string/setup_wizard_title" android:name="SetupWizardActivity" android:excludeFromRecents="true" android:launchMode="singleTop" android:immersive="true">
<intent-filter android:priority="5">
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.DEVICE_INITIALIZATION_WIZARD" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
This will allow you to run your application before/after SetupWizardActivity, depending on your priority. I believe higher numbers for android:prioirity run first, but don't quote me on that.
You can find out the AndroidManifest xml for various Android-related apks using apktool. You can even inspect some of apks you picked up from the Play Store or whatever other sources.

Exported service does not require permission: what does it mean?

I created a service that is bound by other applications through AIDL, and I add it to the manifest as follows:
<service android:name=".MyService">
<intent-filter>
<action android:name="org.example.android.myservicedemo.IService" />
</intent-filter>
</service>
where IService is the AIDL interface.
In this way, Eclipse show me the warning Exported service does not require permission. If I remove the intent-filter, the warning disappear, but obviously the applications are unable to bind to the service.
What does this warning mean?
I had the same issue when I updated SDK to version 20. I removed it adding android:exported property android:exported="false" like so:
<service android:name=".MyService"
android:exported="false">
<intent-filter>
<action android:name="org.example.android.myservicedemo.IService" />
</intent-filter>
</service>
See this doc
If you want to restrict you activity usage to your own application, then you should add exported=false to your activity's manifest statement.
If you want to allow other applications to use it (explicitly through its class name or, better, by using an intent with a data type or action) then you have two choices :
restrict those applications by using a permission
allow all applications to use it, then you can add tools:ignore="ExportedActivity" to your activity's manifest statement.
--
Same reasonning applies to a service, with tools:ignore="ExportedService" and content providers with tools:ignore="ExportedContentProvider".
As Jens said, "It means that other (arbitrary) applications the user has on his phone can bind to your Service and call whatever method they please that is exposed through your AIDL interface."

Categories

Resources