Android Shortcut is not working in VIVO 10 - android

I implementing shortcut in my app but this is not working in VIVO 10( Funtouch OS). Please help me. I am already used many method but not success.
Method 1: I am using this code but not working
#SuppressLint("NewApi")
private fun shortcut(){
val shortcutManager = getSystemService(ShortcutManager::class.java)
val nhentaiIntent = Intent(this, MainActivity::class.java)
nhentaiIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
nhentaiIntent.action = Intent.ACTION_VIEW
if (shortcutManager!!.isRequestPinShortcutSupported) {
val pinShortcutInfo = ShortcutInfo.Builder(this, "my-shortcut")
.setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
.setShortLabel("hello Shortcut")
.setIntent(nhentaiIntent)
.build()
val pinnedShortcutCallbackIntent = shortcutManager.createShortcutResultIntent(pinShortcutInfo)
val successCallback = PendingIntent.getBroadcast(this, /* request code */ 0, pinnedShortcutCallbackIntent, /* flags */ 0)
shortcutManager.requestPinShortcut(pinShortcutInfo, successCallback.intentSender)
}
}
Method 2: I am also used this code but not working
Intent nhentaiIntent = new Intent(context, MainActivity.class);
nhentaiIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
nhentaiIntent.setAction(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
if (shortcutManager.isRequestPinShortcutSupported()) {
ShortcutInfo info = new ShortcutInfo.Builder(context, "Shortcut")
.setIntent(nhentaiIntent)
.setIcon(Icon.createWithResource(context, R.mipmap.ic_launcher))
.setShortLabel("Hello ")
.setLongLabel("Lable")
.build();
Intent addIntent = shortcutManager.createShortcutResultIntent(info);
shortcutManager.requestPinShortcut(info, PendingIntent.getBroadcast(context, 0, addIntent, 0).getIntentSender());
Toast.makeText(context, "supported_launcher", Toast.LENGTH_LONG).show();
} else {
// TODO: Maybe implement this for launchers without pin shortcut support?
// TODO: Should be the same with the fallback for Android < O
// for now just show unsupported
Toast.makeText(context, "unsupported_launcher", Toast.LENGTH_LONG).show();
}
}
Method 3: I am also used this code but not working
private fun addShourcut() {
if (ShortcutManagerCompat.isRequestPinShortcutSupported(applicationContext)) {
val shortcutInfo =
ShortcutInfoCompat.Builder(applicationContext, "#1")
.setIntent(
Intent(applicationContext, MainActivity::class.java).setAction(
Intent.ACTION_MAIN
)
) // !!! intent's action must be set on oreo
.setShortLabel("Test")
.setIcon(
IconCompat.createWithResource(
applicationContext,
R.mipmap.ic_launcher
)
)
.build()
ShortcutManagerCompat.requestPinShortcut(applicationContext, shortcutInfo, null)
} else {
Toast.makeText(
this#MainActivity, "launcher does not support short cut icon",Toast.LENGTH_LONG).show()
}
}
Please help me anyone i spent more time for this issue.

I found that desktop shortcut is not created in default launcher of vivo devices. When I changed default launcher to some other launcher It's let me create desktop shortcut. So as far I did R&d I found below solution it's not complete solution but you can redirect to allow Desktop shortcuts screen using below code.
val sintent = Intent()
sintent .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
sintent .component = ComponentName("com.bbk.launcher2", "com.bbk.launcher2.installshortcut.PurviewActivity")
activity.startActivity(sintent )
I tried to get result if user allowed or not but it's not work for all VIVO devices.
var uri = Uri.parse("content://com.bbk.launcher2.settings/favorites")
var query = activity.contentResolver.query(uri, null, " itemType = ?", arrayOf("30"), null);
if (query != null && query.count > 0) {
var idIndex = query.getColumnIndexOrThrow("_id");
var intentIndex = query.getColumnIndexOrThrow("intent");
var shortcutPermissionIndex = query.getColumnIndexOrThrow("shortcutPermission");
while (query.moveToNext()) {
val long = query.getLong(idIndex)
val intent = query.getString(intentIndex)
val shortcutPermission = query.getInt(shortcutPermissionIndex)
var unflattenFromString = ComponentName.unflattenFromString(intent)
Log.e("bhavin->", "initView: getShortcutPerBtn id=$long packageName= ${unflattenFromString!!.packageName} shortcutPermission= $shortcutPermission")
if (unflattenFromString!!.packageName == activity.packageName && shortcutPermission != 0 && shortcutPermission != 16){
val intent = Intent()
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.component = ComponentName("com.bbk.launcher2", "com.bbk.launcher2.installshortcut.PurviewActivity")
activity.startActivity(intent)
query.close()
return#ensureBackgroundThread
}
else{
Log.e("bhavin->","abcd")
}
}
query.close()
}
For more details you can check this I found this git
Note: I found exception some devices vivo 1902 and Z3
java.lang.SecurityException: Permission Denial: opening provider
com.bbk.launcher2.data.LauncherProvider from ProcessRecord{f8f30af
16137:com.qiutinghe.change/u0a172} (pid=16137, uid=10172) requires
com.bbk.launcher2.permission.READ_SETTINGS or
com.bbk.launcher2.permission.WRITE_SETTINGS
If any one found how to check desktop permission is allowed in Vivo devices please add into this answer.

Related

How to open a Folder/directory from Notifications in Android

fun showNotification(){
val path = Environment.getExternalStorageDirectory().toString() + "/Android/media/"
val uri = Uri.parse(path)
val intent = Intent(Intent.ACTION_PICK)
intent.setDataAndType(uri, "*/*")
val activityPendingIntent = PendingIntent.getActivity(
context,
1,
intent,
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0
)
val notification = NotificationCompat.Builder(context, COUNTER_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_download_done)
.setContentTitle("Download Finished")
.setContentText("Files at Android/media/")
.setContentIntent(activityPendingIntent)
.build()
notificationManager.notify(1, notification)
}
here is my code, I only manage to open the folder but I couldn't open the files.
What I wanted to happen is simply redirection to the folder and access the files in there. Is this possible? Am I approaching it wrong?
After a thorough searching, I found an answer that works for me..
// my notification function
fun showNotification(){
// an intent to be initialized when:
lateinit var intent: Intent
// A) Android version is 10 or above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val sm = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
intent = sm.primaryStorageVolume.createOpenDocumentTreeIntent()
var startDir = "Android%2Fmedia" // here is the directory you wanted to open. feel free to test based on your needs.
var uri: Uri = intent.getParcelableExtra("android.provider.extra.INITIAL_URI")!!
var scheme = uri.toString()
scheme = scheme.replace("/root/", "/document/");
scheme += "%3A$startDir";
uri = Uri.parse(scheme);
intent.putExtra("android.provider.extra.INITIAL_URI", uri);
// B) Android Versions 9 and below
} else {
val path = Environment.getExternalStorageDirectory().toString() + "/Android/media/yourpackagename" // path of the directory you wanted to open
val uri = Uri.parse(path)
intent = Intent(Intent.ACTION_PICK)
intent.putExtra("android.provider.extra.INITIAL_URI", uri)
intent.setDataAndType(uri, "*/*")
}
val activityPendingIntent = PendingIntent.getActivity(
context,
1,
intent,
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0
)
// shows notification
val notification = NotificationCompat.Builder(context, COUNTER_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_download_done)
.setContentTitle("Download Finished")
.setContentText("Locate at Files:Android/media/net.pregi.netmesh2/NetMesh")
.setContentIntent(activityPendingIntent)
.build()
notificationManager.notify(1, notification)
}
Note that for android 9 and below, I only managed to open the folder, but couldn't manage to open the file inside it. Still looking for an answer to this. For reference, here are the links that I've found related to this matter. Still open for suggestions.
Android 11 ACTION_OPEN_DOCUMENT_TREE
How to open specific folder in the storage using intent in android

Android Package Manager install not showing

I'm trying to build an auto updater via github. The app so far detects new available versions and downloads the apk file. I however cannot get it to install the apk file.
There are no crashes or Log messages indicating an error. The install dialog just does not show up.
This is my code:
fun downloadAndInstall(link: Uri, fileName: String){
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val downloadUri = link
val request = DownloadManager.Request(downloadUri)
request.setMimeType(MIME_TYPE)
val destination = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/" + fileName
val destinationUri = Uri.parse("file://$destination")
request.setDestinationUri(destinationUri)
fun showInstallOption(destination: String) {
val onComplete = object : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent
) {
val contentUri = FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID + ".provider",
File(destination)
)
val installer = context.packageManager.packageInstaller
val resolver = context.contentResolver
resolver.openInputStream(contentUri)?.use { apkStream ->
val length =
DocumentFile.fromSingleUri(context, contentUri)?.length() ?: -1
val params =
PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
val sessionId = installer.createSession(params)
val session = installer.openSession(sessionId)
session.openWrite("INSTALL", 0, length).use { sessionStream ->
apkStream.copyTo(sessionStream)
session.fsync(sessionStream)
}
val intent = Intent(context, InstallReceiver::class.java)
intent.action = "com.blazecode.tsviewer.util.updater.SESSION_API_PACKAGE_INSTALLED"
val pi = PendingIntent.getBroadcast(
context,
3,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
session.commit(pi.intentSender)
session.close()
}
Toast.makeText(context, "done", Toast.LENGTH_LONG).show()
}
}
context.registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}
showInstallOption(destination)
downloadManager.enqueue(request)
Toast.makeText(context, context.getString(R.string.downloading), Toast.LENGTH_LONG).show()
}
I tested this on Android 13 and 8, both with the same result. Android 13 is a physical device. Android 8 is an emulator.

Samsung A10 android 11 how to create other apps pinned shortcut programmatically from my app

Samsung A10 android 11 updated, Galaxy S9 and Galaxy S10 tested on these devices but its not working
This code is only for android Oreo and above
Here is the code which I used for creating the shortcut in android programmatically. In all other devices its work perfectly but on this specific device it create the short but generate my own app shortcut not for desired.
val shortcutIntent = finalPackageName?.let {
context?.packageManager!!.getLaunchIntentForPackage(
it
)
}
val shortcutManager: ShortcutManager? = context?.getSystemService(ShortcutManager::class.java)
if (shortcutManager != null) {
if (shortcutManager.isRequestPinShortcutSupported) {
val shortcut = ShortcutInfo.Builder(context, "unique_id")
.setShortLabel(finalAppName)
.setLongLabel("Open the Android Docu")
.setIcon(Icon.createWithBitmap(finalBitmap))
.setIntent(shortcutIntent!!)
.build()
((activity) as MainActivity).registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
findNavController().navigate(R.id.resultFragment)
context.unregisterReceiver(this)
}
}, IntentFilter("test_action"))
val intent = Intent("test_action")
val pendingIntent = PendingIntent.getBroadcast(context, 123, intent, 0)
shortcutManager.requestPinShortcut(shortcut, pendingIntent.intentSender)
} else
Toast.makeText(
context,
"Pinned shortcuts are not supported!",
Toast.LENGTH_SHORT
).show()
}
I solved it
if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)) {
val intent = Intent(context, MainActivity::class.java)
intent.action = "android.intent.action.MAIN"
intent.putExtra("appName", originalAppName)
intent.putExtra("pkgName", finalPackageName)
val build: ShortcutInfoCompat =
ShortcutInfoCompat.Builder(context, "uniqueId")
.setIntent(intent).setShortLabel(
finalAppName
).setIcon(IconCompat.createWithBitmap(finalBitmap)).build()
val shortcutManager =
context.getSystemService(ShortcutManager::class.java)
//context is required when call from the fragment
context.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
//this method is called when shortcut is created
Log.d("intent", intent.data.toString())
}
}, IntentFilter("test_action"))
val receiverIntent = Intent("test_action")
val pendingIntent =
PendingIntent.getBroadcast(context, 123, receiverIntent, 0)
ShortcutManagerCompat.requestPinShortcut(
context,
build,
pendingIntent.intentSender
)
return
}
Toast.makeText(
context,
"launcher does not support short cut icon",
Toast.LENGTH_SHORT
).show()
then go to your main activity and get the intent data
val stringExtra = intent.getStringExtra("pkgName")
if (stringExtra != null) {
startActivity(packageManager.getLaunchIntentForPackage(stringExtra))
finish()
}

why Intent.EXTRA_INITIAL_INTENTS not working in android 10

I am trying to share some text, In Android 10 always show max 3 apps in my mobile have WhatsApp but this not displaying here
This code is properly working in below 10 devices but could not find the reason why in android 10 is filtering out.
fun onShareClick() {
val intentShareList = ArrayList<Intent>()
val shareIntent = Intent()
shareIntent.action = Intent.ACTION_SEND
shareIntent.type = "text/plain"
val resolveInfoList = packageManager.queryIntentActivities(shareIntent, 0)
for (resInfo in resolveInfoList) {
val packageName = resInfo.activityInfo.packageName
val name = resInfo.activityInfo.name
if (packageName.contains("com.facebook") ||
packageName.contains("com.twitter.android") ||
packageName.contains("com.google.android.gm") ||
packageName.contains("com.android.mms") ||
packageName.contains("com.whatsapp")
) {
val intent = Intent()
intent.component = ComponentName(packageName, name)
intent.action = Intent.ACTION_SEND
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_SUBJECT, "Your Subject")
intent.putExtra(Intent.EXTRA_TEXT, "Your Content")
intentShareList.add(intent)
}
}
if (intentShareList.isEmpty()) {
Toast.makeText(this#MainActivity, "No apps to share !", Toast.LENGTH_SHORT).show()
} else {
val chooserIntent = Intent.createChooser(intentShareList.removeAt(0), "Share via")
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS,
intentShareList.toTypedArray()
)
startActivity(chooserIntent)
}
}
In the intentShareList contains WhatsApp info but not displaying
I had the same issue. It seems the problem is in some Android 10 devices (like Samsung), not all. I solved using Intent.EXTRA_EXCLUDE_COMPONENTS instead of Intent.EXTRA_INITIAL_INTENTS, and creating an array of ComponentName to be excluded. Refactoring your code:
fun onShareClick() {
val excludedComponents = ArrayList<ComponentName>()
val shareIntent = Intent()
shareIntent.action = Intent.ACTION_SEND
shareIntent.type = "text/plain"
val resolveInfoList = packageManager.queryIntentActivities(shareIntent, 0)
for (resInfo in resolveInfoList) {
val packageName = resInfo.activityInfo.packageName
val name = resInfo.activityInfo.name
if (!(packageName.contains("com.facebook") ||
packageName.contains("com.twitter.android") ||
packageName.contains("com.google.android.gm") ||
packageName.contains("com.android.mms") ||
packageName.contains("com.whatsapp"))
) {
excludedComponents.add(ComponentName(packageName, name))
}
}
if (excludedComponents.size()==resolveInfoList.size()) {
Toast.makeText(this#MainActivity, "No apps to share !", Toast.LENGTH_SHORT).show()
} else {
val chooserIntent = Intent.createChooser(shareIntent , "Share via")
chooserIntent.putExtra(
Intent.EXTRA_EXCLUDE_COMPONENTS,
excludedComponents.toTypedArray()
)
startActivity(chooserIntent)
}
}
I think you should create your chooser using the initial intent and add your intentShareList as extra, like this:
val chooserIntent = Intent.createChooser(shareIntent, "Share via")
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS,
intentShareList.toTypedArray()
)
startActivity(chooserIntent)
I think it will bring what you want. Let me know if it helps :)
EDIT: Even if you put on your shareIntent a inicial EXTRA_INTENT and a type, Android Q will ignore what you added on EXTRA_INITIAL_INTENTS, so it wont help
I was reading about this on that issue and I think it wont be fixed, take a look = https://issuetracker.google.com/issues/134367295
Also, there some information on documentation that says using EXTRA_INITIAL_INTENTS to personalized data is not recomended, and its was made to helping share links and it can reduce the apps who will appear, take a look = https://developer.android.com/training/sharing/send
Well, Im very sad about that, Idk what do to also, maybe a unique text... :(
My answer may not answer OP's question but if you want to exclude a specified package, you can refer to it. This solution also works on pre-Android 11 OS.
For me, EXTRA_INITIAL_INTENTS doesn't work on Android 11. So I handled 2 flows for 2 cases (Android 11 or later and pre-Android).
The below code will exclude Facebook out of share options.
1. Add the Facebook package to Android Manifest for expanding package visibility on Android 11. You can check out
<manifest ...>
...
<queries>
...
<package android:name="com.facebook.katana" />
</queries>
...
</manifest>
2. Create an intent chooser:
private fun getShareChooserWithoutFacebook(
context: Context,
template: Intent
): Intent {
// get available share intents
val targets: MutableList<Intent> = mutableListOf()
val candidates: List<ResolveInfo> =
context.packageManager.queryIntentActivities(template, 0)
val excludedComponents = ArrayList<ComponentName>()
// remove facebook which has a broken share intent
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R) {
for (candidate in candidates) {
val packageName = candidate.activityInfo.packageName
if (!packageName.equals("com.facebook.katana")) {
val target = Intent(Intent.ACTION_SEND)
target.type = "text/plain"
target.putExtra(
Intent.EXTRA_SUBJECT,
template.getStringExtra(Intent.EXTRA_SUBJECT)
)
target.putExtra(
Intent.EXTRA_TEXT,
template.getStringExtra(Intent.EXTRA_TEXT)
)
target.setPackage(packageName)
targets.add(target)
}
}
} else {
for (candidate in candidates) {
val packageName = candidate.activityInfo.packageName
val name = candidate.activityInfo.name
if ((packageName.equals("com.facebook.katana"))) {
excludedComponents.add(ComponentName(packageName, name))
}
}
}
var chooserIntent = Intent.createChooser(template, context.getString(R.string.settings_send_via))
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R) {
chooserIntent =
Intent.createChooser(targets.removeAt(0), context.getString(R.string.settings_send_via))
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS,
targets.toTypedArray()
)
} else {
chooserIntent.putExtra(
Intent.EXTRA_EXCLUDE_COMPONENTS,
excludedComponents.toTypedArray()
)
}
return chooserIntent
}
3. Open the intent chooser
fun openShareChooser(context: Context, title: String?, content: String?) {
val template = Intent(Intent.ACTION_SEND)
template.type = "text/plain"
template.putExtra(Intent.EXTRA_SUBJECT, title)
template.putExtra(Intent.EXTRA_TEXT, content)
context.startActivity(
getShareChooserWithoutFacebook(context, template)
)
}

Android ConnectionService incoming calls

I'm trying to implement iOS callkit behavior on Android. I'm receiving a push notification from firebase and I want to show "incoming call" screen to the user. To do it I use ConnectionService from android.telecom package and other classes.
Here is my call manager class:
class CallManager(context: Context) {
val telecomManager: TelecomManager
var phoneAccountHandle:PhoneAccountHandle
var context:Context
val number = "3924823202"
init {
telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
this.context = context
val componentName = ComponentName(this.context, CallConnectionService::class.java)
phoneAccountHandle = PhoneAccountHandle(componentName, "Admin")
val phoneAccount = PhoneAccount.builder(phoneAccountHandle, "Admin").setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED).build()
telecomManager.registerPhoneAccount(phoneAccount)
val intent = Intent()
intent.component = ComponentName("com.android.server.telecom", "com.android.server.telecom.settings.EnableAccountPreferenceActivity")
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
}
#TargetApi(Build.VERSION_CODES.M)
fun startOutgoingCall() {
val extras = Bundle()
extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true)
val manager = context.getSystemService(TELECOM_SERVICE) as TelecomManager
val phoneAccountHandle = PhoneAccountHandle(ComponentName(context.packageName, CallConnectionService::class.java!!.getName()), "estosConnectionServiceId")
val test = Bundle()
test.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle)
test.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL)
test.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras)
try {
manager.placeCall(Uri.parse("tel:$number"), test)
} catch (e:SecurityException){
e.printStackTrace()
}
}
#TargetApi(Build.VERSION_CODES.M)
fun startIncomingCall(){
if (this.context.checkSelfPermission(Manifest.permission.MANAGE_OWN_CALLS) == PackageManager.PERMISSION_GRANTED) {
val extras = Bundle()
val uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null)
extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri)
extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle)
extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true)
val isCallPermitted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
telecomManager.isIncomingCallPermitted(phoneAccountHandle)
} else {
true
}
Log.i("CallManager", "is incoming call permited = $isCallPermitted")
telecomManager.addNewIncomingCall(phoneAccountHandle, extras)
}
}
}
And my custom ConnectionService implementation:
class CallConnectionService : ConnectionService() {
override fun onCreateOutgoingConnection(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?): Connection {
Log.i("CallConnectionService", "onCreateOutgoingConnection")
val conn = CallConnection(applicationContext)
conn.setAddress(request!!.address, PRESENTATION_ALLOWED)
conn.setInitializing()
conn.videoProvider = MyVideoProvider()
conn.setActive()
return conn
}
override fun onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?) {
super.onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount, request)
Log.i("CallConnectionService", "create outgoing call failed")
}
override fun onCreateIncomingConnection(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?): Connection {
Log.i("CallConnectionService", "onCreateIncomingConnection")
val conn = CallConnection(applicationContext)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
conn.connectionProperties = Connection.PROPERTY_SELF_MANAGED
}
conn.setCallerDisplayName("test call", TelecomManager.PRESENTATION_ALLOWED)
conn.setAddress(request!!.address, PRESENTATION_ALLOWED)
conn.setInitializing()
conn.videoProvider = MyVideoProvider()
conn.setActive()
return conn
}
override fun onCreateIncomingConnectionFailed(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?) {
super.onCreateIncomingConnectionFailed(connectionManagerPhoneAccount, request)
Log.i("CallConnectionService", "create outgoing call failed ")
}
}
And my Connection implementation is like that:
class CallConnection(ctx:Context) : Connection() {
var ctx:Context = ctx
val TAG = "CallConnection"
override fun onShowIncomingCallUi() {
// super.onShowIncomingCallUi()
Log.i(TAG, "onShowIncomingCallUi")
val intent = Intent(Intent.ACTION_MAIN, null)
intent.flags = Intent.FLAG_ACTIVITY_NO_USER_ACTION or Intent.FLAG_ACTIVITY_NEW_TASK
intent.setClass(ctx, IncomingCallActivity::class.java!!)
val pendingIntent = PendingIntent.getActivity(ctx, 1, intent, 0)
val builder = Notification.Builder(ctx)
builder.setOngoing(true)
builder.setPriority(Notification.PRIORITY_HIGH)
// Set notification content intent to take user to fullscreen UI if user taps on the
// notification body.
builder.setContentIntent(pendingIntent)
// Set full screen intent to trigger display of the fullscreen UI when the notification
// manager deems it appropriate.
builder.setFullScreenIntent(pendingIntent, true)
// Setup notification content.
builder.setSmallIcon(R.mipmap.ic_launcher)
builder.setContentTitle("Your notification title")
builder.setContentText("Your notification content.")
// Use builder.addAction(..) to add buttons to answer or reject the call.
val notificationManager = ctx.getSystemService(
NotificationManager::class.java)
notificationManager.notify("Call Notification", 37, builder.build())
}
override fun onCallAudioStateChanged(state: CallAudioState?) {
Log.i(TAG, "onCallAudioStateChanged")
}
override fun onAnswer() {
Log.i(TAG, "onAnswer")
}
override fun onDisconnect() {
Log.i(TAG, "onDisconnect")
}
override fun onHold() {
Log.i(TAG, "onHold")
}
override fun onUnhold() {
Log.i(TAG, "onUnhold")
}
override fun onReject() {
Log.i(TAG, "onReject")
}
}
According to the document to show user incoming calcustomon UI - I should do some actions in onShowIncomingCallUi() method. But it just does not called by the system.
How can I fix it?
I was able to get it to work using a test app and Android Pie running on a Pixel 2 XL.
From my testing the important parts are to ensure:
That Connection.PROPERTY_SELF_MANAGED is set on the connection. Requires a minimum of API 26.
You have to register your phone account.
You have to set PhoneAccount.CAPABILITY_SELF_MANAGED in your capabilities when registering the phone account. That is the only capability that I set. Setting other capabilities caused it to throw an exception.
Finally, you need to ensure that you have this permission set in AndroidManifest.xml. android.permission.MANAGE_OWN_CALLS
So, I would check your manifest to ensure you have the permissions and also ensure the capabilities are set correctly. It looks like everything else was set correctly in your code above.
Hope that helps!

Categories

Resources