Skip to content

Commit

Permalink
Fixed issue with Direct Share on Android 10 and above
Browse files Browse the repository at this point in the history
  • Loading branch information
xizzhu committed May 22, 2020
1 parent 2539a1f commit 8119087
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import kotlin.test.assertNotNull

@RunWith(AndroidJUnit4::class)
@SmallTest
class IntentHelperTest : BaseUnitTest() {
class ContextTest : BaseUnitTest() {
@Mock
private lateinit var packageManager: PackageManager

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ import me.xizzhu.android.joshua.reading.*
import me.xizzhu.android.joshua.ui.dialog
import me.xizzhu.android.joshua.ui.recyclerview.BaseItem
import me.xizzhu.android.joshua.ui.toast
import me.xizzhu.android.joshua.utils.chooserForSharing
import me.xizzhu.android.joshua.utils.copyToClipBoard
import me.xizzhu.android.joshua.utils.share
import me.xizzhu.android.logger.Log
import kotlin.math.max

Expand Down Expand Up @@ -94,12 +94,10 @@ class VersePresenter(
if (selectedVerses.isEmpty()) return

try {
activity.chooserForSharing(
activity.getString(R.string.text_share_with),
selectedVerses.toStringForSharing(currentVerseIndexViewData.bookName)
)
?.let { activity.startActivity(it) }
?: throw RuntimeException("Failed to create chooser for sharing")
activity.share(
activity.getString(R.string.text_share_with),
selectedVerses.toStringForSharing(currentVerseIndexViewData.bookName)
)
} catch (e: Exception) {
Log.e(tag, "Failed to share", e)
activity.toast(R.string.toast_unknown_error)
Expand Down
53 changes: 50 additions & 3 deletions app/src/main/kotlin/me/xizzhu/android/joshua/utils/Context.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,59 @@

package me.xizzhu.android.joshua.utils

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.app.Activity
import android.content.*
import android.content.pm.LabeledIntent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Parcelable
import androidx.annotation.VisibleForTesting

// On older devices, this only works on the threads with loopers.
fun Context.copyToClipBoard(label: CharSequence, text: CharSequence) {
(getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager)
.setPrimaryClip(ClipData.newPlainText(label, text))
}

fun Activity.share(title: String, text: String) {
val chooser = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Seems starting from Android 10, Direct Share doesn't work if we provides extra intents
// to Intent.createChooser through Intent.EXTRA_INITIAL_INTENTS. Therefore, simply do this,
// with the drawback that Facebook cannot be excluded.
Intent.createChooser(Intent(Intent.ACTION_SEND).setType("text/plain").putExtra(Intent.EXTRA_TEXT, text), null)
} else {
// Facebook doesn't want us to pre-fill the message, but still captures ACTION_SEND. Therefore,
// I have to exclude their package from being shown.
// Rants: it's a horrible way to force developers to use their SDK.
// ref. https://developers.facebook.com/bugs/332619626816423
packageManager.chooserForSharing("com.facebook.katana", title, text)
}
chooser?.let { startActivity(it) }
?: throw RuntimeException("Failed to create chooser for sharing")
}

@VisibleForTesting
fun PackageManager.chooserForSharing(packageToExclude: String, title: String, text: String): Intent? {
val sendIntent = Intent(Intent.ACTION_SEND).setType("text/plain")
val resolveInfoList = queryIntentActivities(sendIntent, 0)
if (resolveInfoList.isEmpty()) return null

val filteredIntents = ArrayList<Intent>(resolveInfoList.size)
for (resolveInfo in resolveInfoList) {
val packageName = resolveInfo.activityInfo.packageName
if (packageToExclude != packageName) {
val labeledIntent = LabeledIntent(packageName, resolveInfo.loadLabel(this), resolveInfo.iconResource)
labeledIntent.setAction(Intent.ACTION_SEND).setPackage(packageName)
.setComponent(ComponentName(packageName, resolveInfo.activityInfo.name))
.setType("text/plain")
.putExtra(Intent.EXTRA_TEXT, text)
filteredIntents.add(labeledIntent)
}
}
if (filteredIntents.isEmpty()) return null

return Intent.createChooser(filteredIntents.removeAt(0), title).apply {
val array = arrayOfNulls<Parcelable>(filteredIntents.size)
putExtra(Intent.EXTRA_INITIAL_INTENTS, filteredIntents.toArray(array))
}
}
58 changes: 0 additions & 58 deletions app/src/main/kotlin/me/xizzhu/android/joshua/utils/IntentHelper.kt

This file was deleted.

1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CHANGELOG
- Should close activity when failed to load annotated verses, reading progress, and Strong's numbers
- Properly nullify when jobs updating annotated verses complete
- Should scroll after chapter group is expanded / collapsed
- Fixed issue with Direct Share on Android 10 and above
- Changes:
- No longer show book name when simple reading mode is off
- Refactoring:
Expand Down

0 comments on commit 8119087

Please sign in to comment.