How to read version number from a database file in Android which is placed in asset folder(如何从放在资产文件夹中的Android数据库文件中读取版本号)
问题描述
在我手动放置的包数据库下的ASSET文件夹中有一个SQLite文件(如下所示:SRC->Main->ASSET->数据库->Q-db(Q-db是我的SQLite文件)。 现在我想读取它的版本号,如果这个版本放在我自己的应用程序中,我想要匹配,如果不是,那么这个需要复制到我的数据库中,否则将跳过。当然,第一次它会从文件中复制,下一次打开应用程序时,它会检查版本号。我谷歌了很多次,但无法获得文件的版本号,我得到的是我的SQLite版本号,在我的情况下,我不想要它。我们将非常感谢您的支持。
参考:如下所示:
https://www.concretepage.com/android/android-ship-sqlite-database-with-apk-copy-sqlite-database-from-assets-folder-to-data-example
推荐答案
没有单个版本号,而是可以是多个值。
您大概是在谈论Android SDK SQLiteOpenHelper使用的User_Version。
还有应用程序ID,它与USER_VERSION一样可以用作用户变量。
您已经遇到SQLite_Version,所以可以打折。
还有Data_Version,这不太可能是版本号,因为它用于指示数据库文件是否已被实时修改。
还有SCHEMA_VERSION,您可能不希望将其用作警告:误用此杂注可能会导致数据库损坏。
User_Version
如前所述,您可能正在谈论User_Version。首先要注意的是,它是一个用户控制的变量/字段,可供自定义使用。SQlite不使用或更改USER_VERSION,但允许更改和使用它。
此外,SQLite管理器(如DB浏览器、Navicat等)不会自动更改版本号。因此,在将数据库文件复制到Assets文件夹之前,您必须故意更改USER_VERSION以使其可用(请注意,如果这样做并且您使用的是SQLiteOpenHelper
的子类,则可能会调用onUpgrade
和onDowngrade
方法)。
如果没有特别更改USER_VERSION,并且数据库仅由SQLite管理器工具访问,则其USER_VERSION将为0。如果数据库文件是通过从使用SQLiteOpenHelper的子类的Android应用程序复制数据库文件来打开的,则它的USER_VERSION将为1或更大(取决于用作SQLiteOpenHelper的构造器的第四个参数的最后一个值)。当然,如果以编程方式更改了USER_VERSION,则如果将文件复制到SQlite管理器工具中,也会反映这样的更改。
在复制文件之前,通常会在SQlite管理器工具中将USER_VERSION更改为适当的值。
您可以使用SQLPRAGMA user_version = 5;
更改User_Version
您可以使用PRAGMA user_version
或SELECT * FROM pragma_user_version;
检索USER_VERSION
示例
以下是一个工作示例(请注意,我很少使用Kotlin,这是使用as Studio从Java转换而来的)。
这使用了一个类,即SQLAssetVersionCheck,它从文件中提取版本号,而不是将文件作为SQLiteDatabase打开。
SQLAssetVersionCheck.kt:-
class SQLAssetVersionCheck
/**
* Full SQLAssetVersionCheck Constructor - sub directories can be specified
* @param context Assets are part of package so use the context to get the asset file
* @param dbName The database name (i.e. the file name)
* @param subDirectories The sub-directories as per the heirarchial order
* @param dbVersion The database version to check against
*/
(context: Context, val databaseName: String, subDirectories: Array<String>?, dbVersion: Int) {
val assetPath: String
var databaseVersion: Int = 0
private set
var result: Int = 0
private set
init {
assetPath = applySubDirectories(databaseName, subDirectories)
Log.d("SQLAVC", "Looking for Asset $assetPath")
var stage = 0
try {
val `is` = context.assets.open(assetPath)
stage++
// Get the first 64 bytes of the header
val v = ByteArray(64)
`is`.read(v, 0, 64)
// only interested in the 4 bytes from offset 60 so get them
val v2 = ByteArray(4)
for (i in 60..63) {
v2[i - 60] = v[i]
}
stage++
// Done with the InputStream so close it
`is`.close()
// Extarct the stored DBVersion
databaseVersion = ByteBuffer.wrap(v2).int
if (databaseVersion < dbVersion) {
result = ASSETVERSIONLOW
}
if (databaseVersion > dbVersion) {
result = ASSETVERSIONHIGH
}
if (databaseVersion == dbVersion) {
result = ASSETVERSIONMATCH
}
} catch (e: IOException) {
e.printStackTrace()
when (stage) {
0 -> result = ASSETNOTFOUND
1 -> result = ASSETIOERROR
}
}
}
constructor(context: Context, dbName: String, dbVersion: Int) : this(context, dbName, null, dbVersion) {}
private fun applySubDirectories(dbname: String, subDirectories: Array<String>?): String {
val base = StringBuffer("")
var firstdirectory = true
if (subDirectories != null) {
for (d in subDirectories) {
if (!firstdirectory) {
base.append(File.separatorChar)
}
firstdirectory = false
base.append(d)
}
}
if (base.length > 0) {
base.append(File.separatorChar)
}
base.append(dbname)
return base.toString()
}
companion object {
val ASSETNOTFOUND = -2
val ASSETIOERROR = -3
val ASSETVERSIONMATCH = 0
val ASSETVERSIONHIGH = 1
val ASSETVERSIONLOW = -1
}
}
下面是一个活动,它两次使用上面的类来尝试检查testdb文件中的版本。
第一次使用时找不到数据库文件testdb,因为它在Assets文件夹(不是数据库子目录)中查找。
第二次用法是在指定子目录数据库(完整构造函数的第三个参数)时找到testdb文件,在sets/Databages/文件夹中找到:-
MainActivity.kt:-
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val db_version_to_check_against = 100
var mAVC1 = SQLAssetVersionCheck(this, "testdb", 100)
var result = ""
when (mAVC1.result) {
SQLAssetVersionCheck.ASSETIOERROR -> result = "IO ERROR detected - check the Log"
SQLAssetVersionCheck.ASSETNOTFOUND -> result = "The Asset, for Database " + mAVC1.databaseName + " was not located at " + mAVC1.assetPath
SQLAssetVersionCheck.ASSETVERSIONHIGH -> result = "The Asset was located and the version number being " +
mAVC1.databaseVersion.toString() +
" was higher than the version to be checked which was " +
db_version_to_check_against.toString()
SQLAssetVersionCheck.ASSETVERSIONLOW -> result = "The Asset was located and the version number being " +
mAVC1.databaseVersion.toString() +
" was lower than the version to be checked which was " +
db_version_to_check_against.toString()
SQLAssetVersionCheck.ASSETVERSIONMATCH -> result = "The Asset version and the version to be check ed are the same."
}
Log.d("ASSETVERSIONCHECK", "The result of the version check was - $result")
var mAVC2 = SQLAssetVersionCheck(this, "testdb", arrayOf("databases"), db_version_to_check_against)
result = ""
when (mAVC2.result) {
SQLAssetVersionCheck.ASSETIOERROR -> result = "IO ERROR detected - check the Log"
SQLAssetVersionCheck.ASSETNOTFOUND -> result = "The Asset, for Database " + mAVC2.databaseName + " was not located at " + mAVC2.assetPath
SQLAssetVersionCheck.ASSETVERSIONHIGH -> result = "The Asset was located and the version number being " +
mAVC2.databaseVersion.toString() +
" was higher than the version to be checked which was " +
db_version_to_check_against.toString()
SQLAssetVersionCheck.ASSETVERSIONLOW -> result = "The Asset was located and the version number being " +
mAVC2.databaseVersion.toString() +
" was lower than the version to be checked which was " +
db_version_to_check_against.toString()
SQLAssetVersionCheck.ASSETVERSIONMATCH -> result = "The Asset version and the version to be check ed are the same."
}
Log.d("ASSETVERSIONCHECK", "The result of the version check was - $result")
}
}
结果(日志):-
2019-02-19 13:11:34.473 19058-19058/com.example.so54741423assetdbversioning D/SQLAVC: Looking for Asset testdb
2019-02-19 13:11:34.473 19058-19058/com.example.so54741423assetdbversioning W/System.err: java.io.FileNotFoundException: testdb
2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.content.res.AssetManager.nativeOpenAsset(Native Method)
2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.content.res.AssetManager.open(AssetManager.java:744)
2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.content.res.AssetManager.open(AssetManager.java:721)
2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err: at com.example.so54741423assetdbversioning.SQLAssetVersionCheck.<init>(SQLAssetVersionCheck.kt:31)
2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err: at com.example.so54741423assetdbversioning.SQLAssetVersionCheck.<init>(SQLAssetVersionCheck.kt:67)
2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err: at com.example.so54741423assetdbversioning.MainActivity.onCreate(MainActivity.kt:17)
2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.Activity.performCreate(Activity.java:7136)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.Activity.performCreate(Activity.java:7127)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.os.Looper.loop(Looper.java:193)
2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6669)
2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning W/System.err: at java.lang.reflect.Method.invoke(Native Method)
2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning D/ASSETVERSIONCHECK: The result of the version check was - The Asset, for Database testdb was not located at testdb
2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning D/SQLAVC: Looking for Asset databases/testdb
2019-02-19 13:11:34.477 19058-19058/com.example.so54741423assetdbversioning D/ASSETVERSIONCHECK: The result of the version check was - The Asset was located and the version number being 5 was lower than the version to be checked which was 100
第一次尝试找不到该文件(显示捕获的异常),并显示要显示的行版本检查的结果是-数据库Testdb的资产未位于Testdb
第二次尝试有效并导致版本检查的结果是-资产已找到,版本号为5的版本低于要检查的版本100
添加空行间隙是为了将第二次尝试与第一次尝试分开。
其他
使用SQLite管理器工具(Navicat)并使用:-
PRAGMA user_version = 101;
然后将文件(在Navicat中关闭连接后)复制到Assets文件夹(因此我有两个testdb文件),结果是:-
2019-02-19 13:50:09.874 19253-19253/com.example.so54741423assetdbversioning D/SQLAVC: Looking for Asset testdb
2019-02-19 13:50:09.874 19253-19253/com.example.so54741423assetdbversioning D/ASSETVERSIONCHECK: The result of the version check was - The Asset was located and the version number being 101 was higher than the version to be checked which was 100
2019-02-19 13:50:09.874 19253-19253/com.example.so54741423assetdbversioning D/SQLAVC: Looking for Asset databases/testdb
2019-02-19 13:50:09.874 19253-19253/com.example.so54741423assetdbversioning D/ASSETVERSIONCHECK: The result of the version check was - The Asset was located and the version number being 5 was lower than the version to be checked which was 100
- 即,新文件的USER_VERSION为101,因此第一个查找该文件,第二个查找文件(USER_VERSION 5),与以前一样。
这篇关于如何从放在资产文件夹中的Android数据库文件中读取版本号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何从放在资产文件夹中的Android数据库文件中读取版本号
- Android - 拆分 Drawable 2022-01-01
- Android viewpager检测滑动超出范围 2022-01-01
- 用 Swift 实现 UITextFieldDelegate 2022-01-01
- Android - 我如何找出用户有多少未读电子邮件? 2022-01-01
- 使用自定义动画时在 iOS9 上忽略 edgesForExtendedLayout 2022-01-01
- MalformedJsonException:在第1行第1列路径中使用JsonReader.setLenient(True)接受格式错误的JSON 2022-01-01
- android 4中的android RadioButton问题 2022-01-01
- 在测试浓缩咖啡时,Android设备不会在屏幕上启动活动 2022-01-01
- 如何检查发送到 Android 应用程序的 Firebase 消息的传递状态? 2022-01-01
- 想使用ViewPager,无法识别android.support.*? 2022-01-01