Android数据库错误(android.database.sqlite.SQLiteCantOpenDatabaseException : unable to open database file)

标签 android sqlite android-sqlite sqliteopenhelper

我正在尝试从预构建数据库中打开文件。该数据库大约为 40-50 MB。我已经编写了将数据库从 Assets 复制到外部文件的代码。但是无法加载数据库。

我的数据库类

package com.example.foodmed3;

import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.text.DecimalFormat;


@SuppressLint("SdCardPath")
public class DatabaseConnect extends Application
{

    private static final String DATABASE_NAME = "facts.db";
      private static final String DATABASE_PATH = "/data/data/FoodMed3/databases/";
      private static final int DATABASE_VERSION = 1;
      private static Context context;
      public static SQLiteDatabase db;

      public DatabaseConnect(Context paramContext)
      {
        context = paramContext;
      }

      public void copyDataBase()
        throws IOException
      {
        InputStream localInputStream = context.getAssets().open("facts.db");
        FileOutputStream localFileOutputStream = new FileOutputStream("/data/data/FoodMed3/databases/facts.db");
        byte[] arrayOfByte = new byte[1024];
        while (true)
        {
          int i = localInputStream.read(arrayOfByte);
          if (i <= 0)
          {
            localFileOutputStream.flush();
            localFileOutputStream.close();
            localInputStream.close();
            return;
          }
          localFileOutputStream.write(arrayOfByte, 0, i);
        }
      }

      private boolean dbExists()
      {
        try
        {
          SQLiteDatabase localSQLiteDatabase2 = SQLiteDatabase.openDatabase("/data/data/FoodMed3/databases/facts.db", null, 0);
          SQLiteDatabase localSQLiteDatabase1 = localSQLiteDatabase2;
          if (localSQLiteDatabase1 != null)
            localSQLiteDatabase1.close();
          boolean bool = false;
          if (localSQLiteDatabase1 != null)
            bool = true;
          return bool;
        }
        catch (SQLiteException localSQLiteException)
        {
            while (true)
            {
            SQLiteDatabase localSQLiteDatabase1 = null;
            }
        }
      }

      @SuppressLint("SdCardPath")
    public void openDB()
      {
        OpenHelper localOpenHelper = new OpenHelper(context);
        if (dbExists())
        {
        //  db =context.getAssets().open("facts.db");
            db = SQLiteDatabase.openDatabase("/data/data/FoodMed3/databases/facts.db", null, 0);
          return;
        }
        db = localOpenHelper.getWritableDatabase();
        try
        {
          copyDataBase();
          db = SQLiteDatabase.openDatabase("/data/data/FoodMed3/databases/facts.db", null, 0);
          return;
        }
        catch (IOException localIOException)
        {
        }
        throw new Error("Error copying database");
      }

      private static class OpenHelper extends SQLiteOpenHelper
      {
        OpenHelper(Context paramContext)
        {
          super(paramContext, "facts.db", null, 1);
        }

        public void onCreate(SQLiteDatabase paramSQLiteDatabase)
        {
        }

        public void onUpgrade(SQLiteDatabase paramSQLiteDatabase, int paramInt1, int paramInt2)
        {
        }
      }

      public Cursor searchFoods(String paramString1)
      {
        Cursor localCursor = null;
        String str1 = paramString1.replace("'", "").replace("/", "").replace("\\", "").replace("%", "").replace(">", "").replace("<", "").replace(";", "").replace(":", "").replace("?", "");
        String str2 = "";
        String[] arrayOfString2 = null;
        int i1 = 0;
        int i3 = 0;
     //   label114:
     //   Cursor 
      //  localCursor;
        int i = 0;
        int j = 0;
        String[] arrayOfString1 = null;
        if (str1.contains(" "))
        {
          arrayOfString2 = str1.split(" ");
          i1 = 0;
          int i2 = arrayOfString2.length;
          i3 = 0;
          if (i3 >= i2)
          {
        //    if (paramString2.length() > 0)
        //      str2 = str2 + " AND FdGrp_Cd='" + paramString2 + "' ";
            localCursor = db.rawQuery("SELECT _id, FdGrp_Cd, Long_Desc, NDB_No FROM FOOD_DES WHERE " + str2 + " ORDER BY FdGrp_Cd='0900' DESC, FdGrp_Cd='1100' DESC, FdGrp_Cd='0500' DESC,  FdGrp_Cd='0100' DESC,  FdGrp_Cd='1500' DESC,  FdGrp_Cd='1300' DESC,  FdGrp_Cd='1700' DESC, Long_Desc ASC LIMIT 300;", null);
            i = 0;
            j = localCursor.getColumnIndex("Long_Desc");
            arrayOfString1 = new String[localCursor.getCount()];
            localCursor.moveToFirst();

          }


        }
        while (true)
        {

          if (localCursor.isAfterLast())
          {
            //return localCursor;
            String str4 = arrayOfString2[i3];
            if (str4.length() > 1)
            {
              String str5 = str4.substring(-1 + str4.length(), str4.length());
              if ((str5.toLowerCase().equals(str5)) && (str5.toLowerCase().equals("s")))
                str4 = str4.substring(0, -1 + str4.length());
            }
            if (i1 + 1 < arrayOfString2.length);
            for (str2 = str2 + " Long_Desc LIKE '%" + str4 + "%' AND "; ; str2 = str2 + " Long_Desc LIKE '%" + str4 + "%' ")
            {
              i1++;
              i3++;
              break;
            }

            if (str1.length() > 1)
            {
              int k = -1 + str1.length();
              int m = str1.length();
              String str3 = str1.substring(k, m);
              if ((str3.toLowerCase().equals(str3)) && (str3.toLowerCase().equals("s")))
              {
                int n = -1 + str1.length();
                str1 = str1.substring(0, n);
              }
            }
            str2 = " Long_Desc LIKE '%" + str1 + "%'";
      //      break label114;
            return localCursor;
          }
          arrayOfString1[i] = localCursor.getString(j);
          i++;
          localCursor.moveToNext();


          }
      }

      public String[][] getFood(String paramString1)
      {
        int i = 0;
        Cursor localCursor = db.rawQuery("SELECT FOOD_DES.Long_Desc, FOOD_DES.fav, nutr_defin.rdi, nutr_defin.units, nutr_defin.tagname, NUT_DATA.Nutr_Val, nutr_defin.friendly_des, nutr_defin.nutr_grp FROM NUT_DATA JOIN FOOD_DES ON FOOD_DES.NDB_No = NUT_DATA.NDB_No JOIN nutr_defin ON NUT_DATA.Nutr_No=nutr_defin.nutr_no WHERE FOOD_DES._id='" + paramString1 + "' AND nutr_defin.friendly_des!='' AND nutr_defin.nutr_grp!='' ORDER BY nutr_defin.sr_order ASC LIMIT 200;", null);
        String[][] arrayOfString = (String[][])Array.newInstance(String.class, new int[] { localCursor.getCount(), 8 });
        int j;
        int k;
        int m;
        int n;
        int i1;
        int i2;
        int i3;
        int i4;
        DecimalFormat localDecimalFormat1;
        DecimalFormat localDecimalFormat2;
        if (localCursor.getCount() > 0)
        {
          localCursor.moveToFirst();
          j = localCursor.getColumnIndex("Nutr_Val");
          k = localCursor.getColumnIndex("friendly_des");
          m = localCursor.getColumnIndex("units");
          n = localCursor.getColumnIndex("tagname");
          i1 = localCursor.getColumnIndex("nutr_grp");
          i2 = localCursor.getColumnIndex("Long_Desc");
          i3 = localCursor.getColumnIndex("rdi");
          i4 = localCursor.getColumnIndex("fav");
          localDecimalFormat1 = new DecimalFormat("#,##0.0");
          localDecimalFormat2 = new DecimalFormat("#,##0");
          if (!localCursor.isAfterLast());
        }
        else
        {
          localCursor.close();
          return arrayOfString;
        }
        double d = Double.parseDouble(localCursor.getString(j).trim());
        //* (Double.parseDouble(paramString2) / 100.0D);
        arrayOfString[i][0] = localCursor.getString(k).trim();
        if (localCursor.getString(m).trim().equals(new String("kcal")))
        {
          arrayOfString[i][1] = localDecimalFormat2.format(d);
          arrayOfString[i][2] = localCursor.getString(n).trim();
          arrayOfString[i][3] = localCursor.getString(i1).trim();
          arrayOfString[i][4] = Double.toString(d);
          arrayOfString[i][5] = localCursor.getString(i2).trim();
          if (localCursor.getInt(i3) <= 0)
          {
        //  break label510;
          Double localDouble = Double.valueOf(100.0D * (d / localCursor.getInt(i3)));
          arrayOfString[i][6] = (localDecimalFormat2.format(localDouble) + "%");
          }
        }
        while (true)
        {
          arrayOfString[i][7] = localCursor.getString(i4);
          i++;
          localCursor.moveToNext();
       //   break;
          arrayOfString[i][1] = (localDecimalFormat1.format(d) + localCursor.getString(m).trim());
       //   break label292;
          arrayOfString[i][6] = "~  ";
        }
      }


}

调用数据库类的Activity类

![package com.example.foodmed3;

import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.database.SQLException;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class FoodSearch extends Activity {

    private EditText searchinput;
    private ListView searchview;
    private Button searchbutton;
    private DatabaseConnect data;
    private String usersearchinput = "";
    private ListAdapter ladapter;

      @SuppressWarnings("deprecation")
    private SimpleCursorAdapter performSearch(String paramString1)
      {
        FoodSearch.this.data = new DatabaseConnect(this);
        FoodSearch.this.data.openDB();
        Cursor localCursor = this.data.searchFoods(paramString1);
        startManagingCursor(localCursor);
        return new SimpleCursorAdapter(this, R.layout.activity_food_search,
                localCursor, new String\[\] { "Long_Desc" }, new int\[\] {R.id.foodsearchview});    

      }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_food_search);

        usersearchinput="";
        searchinput = (EditText) findViewById(R.id.foodsearchinput);
        searchview = (ListView) findViewById(R.id.foodsearchview);
        searchbutton = (Button) findViewById (R.id.foodsearchbutton);

        FoodSearch.this.searchinput.setText("");
        FoodSearch.this.searchbutton.setOnClickListener(new View.OnClickListener()
        {
          public void onClick(View paramAnonymousView)
          {
              FoodSearch.this.usersearchinput = FoodSearch.this.searchinput.getText().toString();
              FoodSearch.this.ladapter=performSearch(FoodSearch.this.usersearchinput);
            ((InputMethodManager)FoodSearch.this.getSystemService("input_method")).hideSoftInputFromWindow(FoodSearch.this.searchinput.getWindowToken(), 0);
            FoodSearch.this.searchview.setAdapter(FoodSearch.this.ladapter);
          }
        });
        FoodSearch.this.searchinput.addTextChangedListener(new TextWatcher()
        {
          public void afterTextChanged(Editable paramAnonymousEditable)
          {
          }

          public void beforeTextChanged(CharSequence paramAnonymousCharSequence, int paramAnonymousInt1, int paramAnonymousInt2, int paramAnonymousInt3)
          {
          }

          public void onTextChanged(CharSequence paramAnonymousCharSequence, int paramAnonymousInt1, int paramAnonymousInt2, int paramAnonymousInt3)
          {
              FoodSearch.this.usersearchinput = FoodSearch.this.searchinput.getText().toString();
            if (FoodSearch.this.usersearchinput.length() > 1)
                FoodSearch.this.ladapter=performSearch(FoodSearch.this.usersearchinput);
            FoodSearch.this.searchview.setAdapter(FoodSearch.this.ladapter);
          }
        });
    }][1]

logcat 输出

    01-13 23:43:05.136: D/libEGL(1426): loaded /system/lib/egl/libGLES_android.so
01-13 23:43:05.147: D/libEGL(1426): loaded /system/lib/egl/libEGL_emulation.so
01-13 23:43:05.156: D/(1426): HostConnection::get() New Host Connection established 0x9365918, tid 1426
01-13 23:43:05.246: D/libEGL(1426): loaded /system/lib/egl/libGLESv1_CM_emulation.so
01-13 23:43:05.246: D/libEGL(1426): loaded /system/lib/egl/libGLESv2_emulation.so
01-13 23:43:05.297: W/EGL_emulation(1426): eglSurfaceAttrib not implemented
01-13 23:43:05.336: D/OpenGLRenderer(1426): Enabling debug mode 0
01-13 23:43:05.606: I/dalvikvm(1426): threadid=3: reacting to signal 3
01-13 23:43:05.606: I/dalvikvm(1426): Wrote stack traces to '/data/anr/traces.txt'
01-13 23:43:37.237: D/Food(1426): Food Tab switched
01-13 23:43:37.877: D/Food(1426): Food Search clicked
01-13 23:43:37.967: W/EGL_emulation(1426): eglSurfaceAttrib not implemented
01-13 23:43:38.047: D/OpenGLRenderer(1426): Flushing caches (mode 0)
01-13 23:43:38.857: I/SqliteDatabaseCpp(1426): sqlite returned: error code = 14, msg = cannot open file at line 27701 of [8609a15dfa], db=/data/data/FoodMed3/databases/facts.db
01-13 23:43:38.857: I/SqliteDatabaseCpp(1426): sqlite returned: error code = 14, msg = os_unix.c: open() at line 27701 - "" errno=2 path=/data/data/FoodMed3/databases/facts.db, db=/data/data/FoodMed3/databases/facts.db
01-13 23:43:38.857: E/SqliteDatabaseCpp(1426): sqlite3_open_v2("/data/data/FoodMed3/databases/facts.db", &handle, 2, NULL) failed
01-13 23:43:38.857: E/SQLiteDatabase(1426): Failed to open the database. closing it.
01-13 23:43:38.857: E/SQLiteDatabase(1426): android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1013)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:962)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at com.example.foodmed3.DatabaseConnect.dbExists(DatabaseConnect.java:58)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at com.example.foodmed3.DatabaseConnect.openDB(DatabaseConnect.java:80)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at com.example.foodmed3.FoodSearch.performSearch(FoodSearch.java:31)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at com.example.foodmed3.FoodSearch.access$3(FoodSearch.java:28)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at com.example.foodmed3.FoodSearch$1.onClick(FoodSearch.java:55)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at android.view.View.performClick(View.java:3511)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at android.view.View$PerformClick.run(View.java:14105)
01-13 23:43:38.857: E/SQLiteDatabase(1426):     at android.os.Handler.handleCallback(Handler.java:605)

我的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.foodmed3"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.foodmed3.TabLayout"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

来自 SQLLite 数据库浏览器的我的数据库内容

enter image description here

我们将不胜感激。

谢谢。

最佳答案

我认为您的 DATABASE_PATH 不正确。文件系统上的路径将基于您的包名称,因此它应该是 /data/data/com.example.foodmed3/databases/

关于Android数据库错误(android.database.sqlite.SQLiteCantOpenDatabaseException : unable to open database file),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21103816/

相关文章:

android - 如何在单击按钮时删除动态创建的 View

android - 在 React Native AirBnb 的 MapView [Android] 上关注用户位置

android - onListItemClick + android

sqlite - SQLite 是否具有 C API 可以读/写的机器可移植文件格式?

android - SQLite 与远程数据库?

sqlite - SQLite3 Pragma同步不持久

flutter - 使用moor_flutter包获取sqlite db表中具有相同列值的所有记录

java - 使用带有 BLOB 数据的游标加载器

android - 如何在 Android 中保存(下载)包含所有图像、CSS 等的 HTML 页面?

android - 如何查询 SQLite 数据库