Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[InitialActivity::getStartupFailureType] StorageAccessException: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid #17373

Closed
Tracked by #17370
david-allison opened this issue Nov 7, 2024 · 4 comments · Fixed by #17470
Labels
2.19 Good First Issue! Help Wanted Requesting Pull Requests from volunteers Priority-High

Comments

@david-allison
Copy link
Member

david-allison commented Nov 7, 2024

InitialActivity::getStartupFailureType

https://ankidroid.org/acra/app/1/bug/250465/report/e6b0ece8-4a72-451e-957e-97b9ff508b12

com.ichi2.anki.exception.StorageAccessException: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid
	at com.ichi2.anki.exception.StorageAccessException.<init>(StorageAccessException.kt:22)
	at com.ichi2.anki.exception.StorageAccessException.<init>(StorageAccessException.kt:19)
	at com.ichi2.anki.CollectionHelper.initializeAnkiDroidDirectory(CollectionHelper.kt:88)
	at com.ichi2.anki.CollectionManager.collectionPathInValidFolder(CollectionManager.kt:264)
	at com.ichi2.anki.CollectionManager.ensureOpenInner(CollectionManager.kt:243)
	at com.ichi2.anki.CollectionManager.getColUnsafe$lambda$11$lambda$10(CollectionManager.kt:299)
	at com.ichi2.anki.CollectionManager$withQueue$3.invokeSuspend(CollectionManager.kt:103)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.java:111)
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:99)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:811)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:715)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:702)
11-07 10:10:46.431 I/AnkiDroid(14499): Timber config: PRODUCTION
11-07 10:10:46.431 I/AnkiDroid(14499): initialize()
11-07 10:10:46.530 I/AnkiDroid(14499): Not participating in analytics sample (sample percentage vs random: 10 24)
11-07 10:10:46.530 I/AnkiDroid(14499): setOptIn(): from false to false
11-07 10:10:46.530 I/AnkiDroid(14499): Not participating in analytics sample (sample percentage vs random: 10 23)
11-07 10:10:46.537 I/AnkiDroid(14499): Creating notification channel with id/name: General Notifications/AnkiDroid
11-07 10:10:46.538 I/AnkiDroid(14499): Creating notification channel with id/name: Synchronization/Sincronização
11-07 10:10:46.538 I/AnkiDroid(14499): Creating notification channel with id/name: Global Reminders/Cartões pendentes
11-07 10:10:46.538 I/AnkiDroid(14499): Creating notification channel with id/name: Deck Reminders/Lembretes
11-07 10:10:46.550 E/AnkiDroid(14499): Instrumentation/ Could not initialize AnkiDroid directory
11-07 10:10:46.550 E/AnkiDroid(14499): c4.a: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid
11-07 10:10:46.550 E/AnkiDroid(14499): 	at P3.l3.p(SourceFile:36)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at com.ichi2.anki.AnkiDroidApp.onCreate(SourceFile:671)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1279)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7033)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2243)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.os.Handler.dispatchMessage(Handler.java:111)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.os.Looper.loopOnce(Looper.java:238)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.os.Looper.loop(Looper.java:357)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.ActivityThread.main(ActivityThread.java:8194)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at java.lang.reflect.Method.invoke(Native Method)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957)
11-07 10:10:46.550 E/AnkiDroid(14499): 
11-07 10:10:46.550 E/AnkiDroid(14499): c4.a: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid
11-07 10:10:46.550 E/AnkiDroid(14499): 	at P3.l3.p(SourceFile:36)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at com.ichi2.anki.AnkiDroidApp.onCreate(SourceFile:671)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1279)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7033)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2243)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.os.Handler.dispatchMessage(Handler.java:111)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.os.Looper.loopOnce(Looper.java:238)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.os.Looper.loop(Looper.java:357)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at android.app.ActivityThread.main(ActivityThread.java:8194)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at java.lang.reflect.Method.invoke(Native Method)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
11-07 10:10:46.550 E/AnkiDroid(14499): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957)
11-07 10:10:46.555 I/AnkiDroid(14499): AnkiDroidApp: Starting Services
11-07 10:10:46.555 W/AnkiDroid(14499): AnkiDroidApp/ BootService - unexpected action received, ignoring: null
11-07 10:10:46.564 I/AnkiDroid(14499): IntentHandler::onCreate
11-07 10:10:46.564 I/AnkiDroid(14499): Setting theme to BLACK
11-07 10:10:46.575 I/AnkiDroid(14499): Launching DeckPicker
11-07 10:10:46.657 I/AnkiDroid(14499): AnkiDroid Version = 2.19.1 (6953d60532ee2762d29b06fd1d76e69203ad8455)
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): Backend Version = 0.1.43-anki24.06.3 (24.06.3 d678e39350a2d243242a69f4e22f5192b04398f2)
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): Android Version = 13 (SDK 33)
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): ProductFlavor = play
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): Manufacturer = motorola
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): Model = motorola edge 40 neo
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): Hardware = mt6879
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): Webview User Agent = Mozilla/5.0 (Linux; Android 13; motorola edge 40 neo Build/T3TMS33.23-100-3-1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Mobile Safari/537.36
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): ACRA UUID = 73a767f6-183a-409c-8e7a-3788c8d11119
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): FSRS = 0.6.4 (Enabled: null)
11-07 10:10:46.657 I/AnkiDroid(14499): 
11-07 10:10:46.657 I/AnkiDroid(14499): Crash Reports Enabled = true
11-07 10:10:46.661 I/AnkiDroid(14499): Setting theme to BLACK
11-07 10:10:46.668 I/AnkiDroid(14499): DeckPicker::onCreate
11-07 10:10:46.726 W/AnkiDroid(14499): Activity/ c4.a: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid
11-07 10:10:46.726 W/AnkiDroid(14499): 	at P3.l3.p(SourceFile:36)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at P3.s3.b(SourceFile:14)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at P3.s3.d(SourceFile:24)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at B4.q.invoke(SourceFile:312)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at P3.r3.q(SourceFile:10)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at p5.a.i(SourceFile:9)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at Q6.D.run(SourceFile:115)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at B1.d.run(SourceFile:828)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at X6.j.run(SourceFile:3)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at X6.a.run(SourceFile:96)
11-07 10:10:46.726 W/AnkiDroid(14499): 
11-07 10:10:46.726 W/AnkiDroid(14499): c4.a: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid
11-07 10:10:46.726 W/AnkiDroid(14499): 	at P3.l3.p(SourceFile:36)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at P3.s3.b(SourceFile:14)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at P3.s3.d(SourceFile:24)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at B4.q.invoke(SourceFile:312)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at P3.r3.q(SourceFile:10)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at p5.a.i(SourceFile:9)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at Q6.D.run(SourceFile:115)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at B1.d.run(SourceFile:828)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at X6.j.run(SourceFile:3)
11-07 10:10:46.726 W/AnkiDroid(14499): 	at X6.a.run(SourceFile:96)
@david-allison david-allison changed the title https://ankidroid.org/acra/app/1/bug/250465/report/e6b0ece8-4a72-451e-957e-97b9ff508b12 StorageAccessException: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid Nov 7, 2024
@david-allison david-allison changed the title StorageAccessException: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid [InitialActivity::getStartupFailureType] StorageAccessException: Failed to create AnkiDroid directory /storage/emulated/0/AnkiDroid Nov 7, 2024
@david-allison david-allison added this to the 2.19.2 release milestone Nov 7, 2024
@david-allison
Copy link
Member Author

david-allison commented Nov 12, 2024

Do we need to do anything here? This is what the user sees on Android 13 when this error is triggered:

I'd propose that we silence this exception if using the default path. Nothing further that we can do

Image

EDIT: Code I used to trigger the exception

Index: AnkiDroid/src/main/java/com/ichi2/anki/preferences/DevOptionsFragment.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/preferences/DevOptionsFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/preferences/DevOptionsFragment.kt
--- a/AnkiDroid/src/main/java/com/ichi2/anki/preferences/DevOptionsFragment.kt	(revision 6953d60532ee2762d29b06fd1d76e69203ad8455)
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/preferences/DevOptionsFragment.kt	(date 1731426260433)
@@ -17,11 +17,13 @@
 
 import android.content.Context
 import androidx.appcompat.app.AlertDialog
+import androidx.core.content.edit
 import androidx.preference.Preference
 import androidx.preference.SwitchPreferenceCompat
+import com.ichi2.anki.AnkiDroidApp
 import com.ichi2.anki.BuildConfig
+import com.ichi2.anki.CollectionHelper
 import com.ichi2.anki.CollectionManager
-import com.ichi2.anki.CrashReportService
 import com.ichi2.anki.R
 import com.ichi2.anki.analytics.UsageAnalytics
 import com.ichi2.anki.launchCatchingTask
@@ -63,12 +65,12 @@
         }
         // Make it possible to test crash reporting
         requirePreference<Preference>(R.string.pref_trigger_crash_key).setOnPreferenceClickListener {
-            // If we don't delete the limiter data, our test crash may not go through,
-            // but we are triggering it very much on purpose, we want to see the crash in ACRA
-            this.context?.let { c -> CrashReportService.deleteACRALimiterData(c) }
+            val prefs = AnkiDroidApp.sharedPrefs()
+            prefs.edit {
+                putString(CollectionHelper.PREF_COLLECTION_PATH, "/storage/emulated/0/AnkiDroid")
+            }
 
-            Timber.w("Crash triggered on purpose from advanced preferences in debug mode")
-            throw RuntimeException("This is a test crash")
+            false
         }
         // Make it possible to test analytics
         requirePreference<Preference>(R.string.pref_analytics_debug_key).setOnPreferenceClickListener {

@mikehardy
Copy link
Member

...is that the right basis text for the diff? seems like it's removing what we want in the trigger crash dev preference and adding in something totally unrelated?

@david-allison
Copy link
Member Author

david-allison commented Nov 12, 2024

The Exception occurs when:

  • a user is on a new version of Android
  • with a play install
  • and the collection path is "/storage/emulated/0/AnkiDroid"

This is typically either after reinstalling, or after legacy permissions to the folder have been revoked by the Android system

The patch above quickly gets AnkiDroid into the same state and is what I used for testing

@mikehardy
Copy link
Member

Agreed - let's silence this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.19 Good First Issue! Help Wanted Requesting Pull Requests from volunteers Priority-High
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants