Skip to content

Commit 4848891

Browse files
ShridharGoellukstbit
authored andcommitted
Text share to AnkiDroid should launch note editor
1 parent 8c3fa38 commit 4848891

File tree

2 files changed

+76
-5
lines changed

2 files changed

+76
-5
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/IntentHandler.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.ichi2.anki.common.utils.trimToLength
3131
import com.ichi2.anki.dialogs.DialogHandler.Companion.storeMessage
3232
import com.ichi2.anki.dialogs.DialogHandlerMessage
3333
import com.ichi2.anki.libanki.DeckId
34+
import com.ichi2.anki.noteeditor.NoteEditorLauncher
3435
import com.ichi2.anki.preferences.sharedPrefs
3536
import com.ichi2.anki.servicelayer.ScopedStorageService
3637
import com.ichi2.anki.services.ReminderService
@@ -94,6 +95,11 @@ class IntentHandler : AbstractIntentHandler() {
9495
handleImageImport(intent)
9596
finish()
9697
}
98+
LaunchType.SHARED_TEXT ->
99+
runIfStoragePermissions {
100+
handleSharedText(intent)
101+
finish()
102+
}
97103
LaunchType.SYNC -> runIfStoragePermissions { handleSyncIntent(reloadIntent, action) }
98104
LaunchType.REVIEW -> runIfStoragePermissions { handleReviewIntent(reloadIntent, intent) }
99105
LaunchType.DEFAULT_START_APP_IF_NEW -> {
@@ -261,6 +267,19 @@ class IntentHandler : AbstractIntentHandler() {
261267
.startActivities()
262268
}
263269

270+
private fun handleSharedText(data: Intent) {
271+
Timber.i("Handling shared text content for note creation")
272+
val noteEditorIntent =
273+
if (data.extras != null) {
274+
NoteEditorLauncher.PassArguments(data.extras!!).toIntent(this, data.action)
275+
} else {
276+
// Fallback if no extras, though this shouldn't happen for ACTION_SEND
277+
NoteEditorLauncher.AddNote().toIntent(this)
278+
}
279+
noteEditorIntent.setDataAndType(data.data, data.type)
280+
startActivity(noteEditorIntent)
281+
}
282+
264283
private fun deleteDownloadedDeck(sharedDeckUri: Uri?) {
265284
if (sharedDeckUri == null) {
266285
Timber.i("onCreate: downloaded a shared deck but uri was null when trying to delete its file")
@@ -304,6 +323,9 @@ class IntentHandler : AbstractIntentHandler() {
304323
/** image */
305324
IMAGE_IMPORT,
306325

326+
/** shared text content */
327+
SHARED_TEXT,
328+
307329
SYNC,
308330
REVIEW,
309331
COPY_DEBUG_INFO,
@@ -349,6 +371,9 @@ class IntentHandler : AbstractIntentHandler() {
349371
val mimeType = intent.resolveMimeType()
350372
when {
351373
mimeType?.startsWith("image/") == true -> LaunchType.IMAGE_IMPORT
374+
action == Intent.ACTION_SEND &&
375+
intent.hasExtra(Intent.EXTRA_TEXT) &&
376+
!intent.hasExtra(Intent.EXTRA_STREAM) -> LaunchType.SHARED_TEXT
352377
textMimeTypes.contains(mimeType) -> LaunchType.TEXT_IMPORT
353378
else -> LaunchType.FILE_IMPORT
354379
}
@@ -389,6 +414,7 @@ class IntentHandler : AbstractIntentHandler() {
389414
LaunchType.FILE_IMPORT,
390415
LaunchType.TEXT_IMPORT,
391416
LaunchType.IMAGE_IMPORT,
417+
LaunchType.SHARED_TEXT,
392418
-> true
393419
LaunchType.COPY_DEBUG_INFO -> false
394420
}

AnkiDroid/src/test/java/com/ichi2/anki/IntentHandlerTest.kt

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,42 @@ class IntentHandlerTest {
9999
testIntentType("content://valid", "text/csv", LaunchType.TEXT_IMPORT)
100100
testIntentType("content://valid", "text/tsv", LaunchType.TEXT_IMPORT)
101101

102-
// Test for ACTION_SEND
103-
testIntentType("content://valid", "text/tab-separated-values", LaunchType.TEXT_IMPORT, Intent.ACTION_SEND)
104-
testIntentType("content://valid", "text/comma-separated-values", LaunchType.TEXT_IMPORT, Intent.ACTION_SEND)
105-
testIntentType("content://valid", "text/csv", LaunchType.TEXT_IMPORT, Intent.ACTION_SEND)
106-
testIntentType("content://valid", "text/tsv", LaunchType.TEXT_IMPORT, Intent.ACTION_SEND)
102+
// Test for ACTION_SEND with file streams (should still be TEXT_IMPORT)
103+
testIntentTypeWithStream("content://valid", "text/tab-separated-values", LaunchType.TEXT_IMPORT)
104+
testIntentTypeWithStream("content://valid", "text/comma-separated-values", LaunchType.TEXT_IMPORT)
105+
testIntentTypeWithStream("content://valid", "text/csv", LaunchType.TEXT_IMPORT)
106+
testIntentTypeWithStream("content://valid", "text/tsv", LaunchType.TEXT_IMPORT)
107+
}
108+
109+
@Test
110+
fun sharedTextIntentStartsApp() {
111+
// Test that sharing plain text content (not files) opens the note editor
112+
// instead of attempting CSV import
113+
val intent =
114+
Intent(Intent.ACTION_SEND).apply {
115+
type = "text/plain"
116+
putExtra(Intent.EXTRA_TEXT, "Some shared text content")
117+
}
118+
119+
val expected = getLaunchType(intent)
120+
121+
assertThat(expected, equalTo(LaunchType.SHARED_TEXT))
122+
}
123+
124+
@Test
125+
fun sharePlainTextDoesNotTriggerCsvImport() {
126+
val intent =
127+
Intent(Intent.ACTION_SEND).apply {
128+
type = "text/plain"
129+
putExtra(Intent.EXTRA_TEXT, "This is some shared text that should create a note")
130+
// No EXTRA_STREAM means this is shared text content, not a file
131+
}
132+
133+
val launchType = getLaunchType(intent)
134+
135+
// Should NOT be TEXT_IMPORT (which would trigger CSV import and fail)
136+
// Should be SHARED_TEXT (which launches note editor directly)
137+
assertThat(launchType, equalTo(LaunchType.SHARED_TEXT))
107138
}
108139

109140
private fun testIntentType(
@@ -128,4 +159,18 @@ class IntentHandlerTest {
128159

129160
assertThat(expected, equalTo(LaunchType.DEFAULT_START_APP_IF_NEW))
130161
}
162+
163+
private fun testIntentTypeWithStream(
164+
data: String,
165+
type: String,
166+
expected: LaunchType,
167+
) {
168+
val intent =
169+
Intent(Intent.ACTION_SEND).apply {
170+
putExtra(Intent.EXTRA_STREAM, data.toUri())
171+
this.type = type
172+
}
173+
val actual = getLaunchType(intent)
174+
assertThat(actual, equalTo(expected))
175+
}
131176
}

0 commit comments

Comments
 (0)