mirror of
https://github.com/YTVanced/VancedMicroG
synced 2024-11-13 06:25:06 +00:00
EN: Add database export feature. Only exports the advertisements table.
This commit is contained in:
parent
879b4c1396
commit
4158e71999
7 changed files with 81 additions and 0 deletions
|
@ -24,6 +24,7 @@ class ExposureNotificationsRpisFragment : PreferenceFragmentCompat() {
|
|||
private lateinit var histogramCategory: PreferenceCategory
|
||||
private lateinit var histogram: BarChartPreference
|
||||
private lateinit var deleteAll: Preference
|
||||
private lateinit var exportDb: Preference
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.preferences_exposure_notifications_rpis)
|
||||
|
@ -33,6 +34,7 @@ class ExposureNotificationsRpisFragment : PreferenceFragmentCompat() {
|
|||
histogramCategory = preferenceScreen.findPreference("prefcat_exposure_rpi_histogram") ?: histogramCategory
|
||||
histogram = preferenceScreen.findPreference("pref_exposure_rpi_histogram") ?: histogram
|
||||
deleteAll = preferenceScreen.findPreference("pref_exposure_rpi_delete_all") ?: deleteAll
|
||||
exportDb = preferenceScreen.findPreference("pref_exposure_export_database") ?: exportDb
|
||||
deleteAll.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.pref_exposure_rpi_delete_all_title)
|
||||
|
@ -48,6 +50,10 @@ class ExposureNotificationsRpisFragment : PreferenceFragmentCompat() {
|
|||
.show()
|
||||
true
|
||||
}
|
||||
exportDb.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
ExposureDatabase.export(requireContext())
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
<string name="pref_exposure_rpi_delete_all_title">Alle gesammelten IDs löschen</string>
|
||||
<string name="pref_exposure_rpi_delete_all_warning">Nach dem Löschen der gesammelten IDs kannst du nicht mehr informiert werden, falls einer deiner Kontakte der letzten 14 Tage positiv getested wurde.</string>
|
||||
<string name="pref_exposure_rpi_delete_all_warning_confirm_button">Trotzdem löschen</string>
|
||||
<string name="pref_exposure_rpi_export_title">Datenbank Export</string>
|
||||
<string name="pref_exposure_rpi_export_summary">Exportiere die aktuelle Datenbank um sie mit einer anderen App zu analysieren.</string>
|
||||
<string name="pref_exposure_info_summary">"Die Exposure Notifications API ermöglicht es Apps, dich zu warnen, falls du Kontakt zu einer positiv getesteten Person hattest.
|
||||
|
||||
Das Datum, die Zeitdauer und die Signalstärke, die dem Kontakt zugeordnet sind, werden mit der zugehörigen App geteilt."</string>
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
<string name="pref_exposure_rpi_delete_all_title">Delete all collected IDs</string>
|
||||
<string name="pref_exposure_rpi_delete_all_warning">Deleting collected IDs will make it impossible to notify you in case any of your contacts of the last 14 days is diagnosed.</string>
|
||||
<string name="pref_exposure_rpi_delete_all_warning_confirm_button">Delete anyways</string>
|
||||
<string name="pref_exposure_rpi_export_title">Export Database</string>
|
||||
<string name="pref_exposure_rpi_export_summary">Export the current database for analysis with another app.</string>
|
||||
<string name="pref_exposure_info_summary">"Exposure Notifications API allows apps to notify you if you were exposed to someone who reported to be diagnosed positive.
|
||||
|
||||
The date, duration, and signal strength associated with an exposure will be shared with the corresponding app."</string>
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
android:key="pref_exposure_rpi_delete_all"
|
||||
android:title="@string/pref_exposure_rpi_delete_all_title" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:layout="@layout/preference_category_no_label">
|
||||
<Preference
|
||||
android:key="pref_exposure_export_database"
|
||||
android:title="@string/pref_exposure_rpi_export_title"
|
||||
android:summary="@string/pref_exposure_rpi_export_summary" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:layout="@layout/preference_category_no_label">
|
||||
<org.microg.gms.ui.TextPreference
|
||||
android:icon="@drawable/ic_info_outline"
|
||||
|
|
|
@ -42,5 +42,15 @@
|
|||
<action android:name="android.intent.action.PACKAGE_RESTARTED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="org.microg.gms.nearby.exposurenotification.export"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/preferences_exposure_notifications_exportedfiles" />
|
||||
</provider>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -8,13 +8,17 @@ package org.microg.gms.nearby.exposurenotification
|
|||
import android.annotation.TargetApi
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.database.sqlite.SQLiteCursor
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteDatabase.CONFLICT_IGNORE
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import android.util.Log
|
||||
import androidx.core.content.FileProvider
|
||||
import com.google.android.gms.nearby.exposurenotification.CalibrationConfidence
|
||||
import com.google.android.gms.nearby.exposurenotification.DiagnosisKeysDataMapping
|
||||
import com.google.android.gms.nearby.exposurenotification.ExposureConfiguration
|
||||
import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
|
||||
|
@ -964,6 +968,53 @@ class ExposureDatabase private constructor(private val context: Context) : SQLit
|
|||
}
|
||||
}
|
||||
|
||||
fun export(context: Context) {
|
||||
// FileProvider cannot directly access /databases, so we have to copy the database first
|
||||
// In addition, we filter out only the Advertisements table to not export sensitive TEKs
|
||||
|
||||
// Create a new database which will store only the Advertisements table
|
||||
val exportDir = File(context.getCacheDir(), "exposureDatabase")
|
||||
exportDir.mkdir()
|
||||
val exportFile = File(exportDir, "database.db")
|
||||
if (exportFile.delete()) {
|
||||
Log.d("EN-DB-Exporter", "Deleted old export database.")
|
||||
}
|
||||
val db = SQLiteDatabase.openOrCreateDatabase(exportFile, null)
|
||||
|
||||
// Attach the full database to the new empty db
|
||||
val databaseFile = context.getDatabasePath(DB_NAME);
|
||||
db.execSQL("ATTACH '$databaseFile' AS fulldb;")
|
||||
|
||||
// copy TABLE_ADVERTISEMENTS over
|
||||
db.execSQL("CREATE TABLE $TABLE_ADVERTISEMENTS AS SELECT * FROM fulldb.$TABLE_ADVERTISEMENTS;")
|
||||
|
||||
// Detach original db, close new db
|
||||
db.execSQL("DETACH DATABASE fulldb;")
|
||||
db.close()
|
||||
|
||||
// Use the FileProvider to get a content URI for the new DB
|
||||
val fileUri: Uri? = try {
|
||||
FileProvider.getUriForFile(context,"org.microg.gms.nearby.exposurenotification.export", exportFile)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Log.e("EN-DB-Exporter", "The database file can't be shared: $exportFile $e")
|
||||
null
|
||||
}
|
||||
|
||||
// Open a sharesheet
|
||||
if (fileUri != null) {
|
||||
// Grant temporary read permission to the content URI
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
putExtra(Intent.EXTRA_STREAM, fileUri)
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
type = "application/vnd.sqlite3"
|
||||
}
|
||||
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
context.startActivity(shareIntent)
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated(message = "Sync database access is slow", replaceWith = ReplaceWith("with(context, call)"))
|
||||
fun <T> withSync(context: Context, call: (ExposureDatabase) -> T): T {
|
||||
val it = runBlocking { ref(context) }
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<cache-path name="exposureDatabase" path="exposureDatabase" />
|
||||
</paths>
|
Loading…
Reference in a new issue