无法在Android应用程序使用外部数据库 [英] Unable to use external database in Android app

查看:253
本文介绍了无法在Android应用程序使用外部数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用我的外部datbase在的MySQL 即可。我有一个存档数据库 databse.db.zip ,并在资产我的Andr​​oid的Java项目的夹复制它。最后,我创建了一个类打开数据库:

 进口android.content.Context;
进口android.database.Cursor;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteQueryBuilder;
进口com.readystatesoftware.sqliteasset.SQLiteAssetHelper;公共类databaseOpen扩展SQLiteAssetHelper {私有静态最后弦乐DATABASE_NAME =parole.db;
私有静态最终诠释DATABASE_VERSION = 1;公共databaseOpen(上下文的背景下){    超(背景下,DATABASE_NAME,空,DATABASE_VERSION);
}
公共字符串risposta(字符串parolain){
    SQLiteDatabase分贝= getReadableDatabase();
    SQLiteQueryBuilder QB =新SQLiteQueryBuilder();
    的String [] = selectionArgs两个{侨};
    光标C = db.query(表面,NULL,NULL,selectionArgs两个,NULL,NULL,NULL);
    c.moveToFirst();    返回c.getString(0);
}
}

我已经在开垦它在我的

 私人databaseOpen分贝;@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    DB =新databaseOpen(本);
    吐司面包= Toast.makeText(这一点,db.risposta(侨),Toast.LENGTH_LONG);
}

,但它不工作。下面是我得到的输出:

  09-26 15:20:23.761 1099至1099年/? I / SQLiteAssetHelper成功打开数据库parole.db
09-26 15:20:23.764一〇九九年至1099年/? E / SQLiteLog(1)没有这样的表:表面
09-26 15:20:23.783一〇九九年至1099年/? D / AndroidRuntime关闭VM
09-26 15:20:23.801一〇九九年至1099年/? E / AndroidRuntime致命异常:主要
    工艺:com.example.roby.jarvis,PID:1099
    了java.lang.RuntimeException:无法启动活动ComponentInfo {com.example.roby.jarvis / com.example.roby.jarvis.Home}:android.database.sqlite.SQLiteException:没有这样的表:表面(code 1 ),在编译:SELECT * FROM初步


解决方案

第一:您不能复制数据库从你的资产文件fil​​e到您的设备,这显然会导致成没有这样的表中找到

试试这个code,它为我工作。 (我也有评论不同部分的理解)

 进口android.content.ContentValues​​;
进口android.content.Context;
进口android.database.Cursor;
进口android.database.SQLException;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteException;
进口android.database.sqlite.SQLiteOpenHelper;
进口android.os.Build;
进口android.util.Log;进口java.io.FileOutputStream中;
进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.io.OutputStream中;/ **
*创建于HP-惠普23-07-2015。
* /
公共类DataBaseHelper扩展SQLiteOpenHelper {//你的应用程序数据库的Andr​​oid的默认系统路径。
私人静态字符串DB_PATH;私人静态字符串DB_NAME =profanityv2;私人SQLiteDatabase MYDATABASE;私人最终上下文myContext;/ **
 *构造
 *注意到并保持以访问该应用程序的资产和资源所传递的上下文的引用。
 * @参数方面
 * /
公共DataBaseHelper(上下文的背景下){    超级(上下文,DB_NAME,空,1);    如果(android.os.Build.VERSION.SDK_INT> = 4.2){
        DB_PATH = context.getApplicationInfo()DATADIR +/数据库/。
    }其他{
        DB_PATH =/数据/数据​​/+ context.getPackageName()+/数据库/;
    }    this.myContext =背景;
}/ **
 *在系统上创建一个空数据库,并与自己的数据库重写它。
 * * /
公共无效的CreateDatabase()抛出IOException    布尔dbExist = checkDataBase();    如果(dbExist){
        //什么也不做 - 已存在于数据库
    }其他{        //通过调用此方法与空的数据库将被创建到默认的系统路径
        //你的应用程序,所以我们要能够覆盖该数据库与我们的数据库。
        this.getReadableDatabase();        尝试{            copyDataBase();        }赶上(IOException异常五){            抛出新的错误(错误复制数据库);        }
    }}/ **
 *检查是否已存在于数据库,以避免重新复制每次打开应用程序时的文件。
 *如果存在返回:真的,假的,如果它不
 * /
私人布尔checkDataBase(){    SQLiteDatabase CHECKDB = NULL;    尝试{
        字符串mypath中= DB_PATH + DB_NAME;
        CHECKDB = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READONLY);    }赶上(SQLiteException E){        //数据库开不存在。
        尝试{
            myContext.deleteDatabase(亵渎);
        }赶上(例外E1){
            e1.printStackTrace();
        }
    }    如果(CHECKDB!= NULL){        checkDB.close();    }    返回CHECKDB!= NULL;
}/ **
 *副本数据库从本地资产文件夹在刚才创建的空数据库
 *系统文件夹,从那里可以访问和处理。
 *这是通过转流的字节流进行。
 * * /
私人无效copyDataBase()抛出IOException    //打开本地数据库的输入流
    InputStream的myInput = myContext.getAssets()开(DB_NAME)。    //路径刚刚创建的空分贝
    字符串outFileName = DB_PATH + DB_NAME;    //打开空分贝的输出流
    的OutputStream myOutput =新的FileOutputStream(outFileName);    //传递从inputfile中字节到OUTPUTFILE
    字节[]缓冲区=新的字节[1024];
    INT长;
    而((长度= myInput.read(缓冲液))大于0){
        myOutput.write(缓冲液,0,长度);
    }    //关闭流
    myOutput.flush();
    myOutput.close();
    myInput.close();}公共无效的openDatabase()抛出的SQLException {    //打开数据库
    字符串mypath中= DB_PATH + DB_NAME;
    MYDATABASE = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.CREATE_IF_NECESSARY);}@覆盖
公共同步无效的close(){    如果(MYDATABASE!= NULL)
        myDataBase.close();    super.close();}公共光标的getData(){
    光标C = NULL;
    尝试{
        C = myDataBase.rawQuery(SELECT * FROM profanity_table,NULL);
    }赶上(例外五){
        e.printStackTrace();
    }
    //注:法师是在外部分贝一个表。在这里,我们试图从外部访问数据库表中的记录。
    返回℃;
}
@覆盖
公共无效的onCreate(SQLiteDatabase DB){}@覆盖
公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){}//添加您的公开辅助方法访问并从数据库中获取的内容。
//你可以做返回游标返回myDataBase.query(....),因此这将会是很容易
//你创建你的意见适配器。}

用法:

  DataBaseHelper dataBaseHelper =新DataBaseHelper(本);    尝试{
        dataBaseHelper.createDataBase();
    }赶上(IOException异常五){
        // TODO自动生成catch块
        e.printStackTrace();
    }    尝试{        dataBaseHelper.openDataBase();    }赶上(的SQLException SQLE){        扔SQLE;    }    光标C = dataBaseHelper.getData();    如果(C!= NULL){
        / *光标code * /
        c.close();
    }
    dataBaseHelper.close();

*注:有些设备可能无法能够将数据库复制到设备(已知设备:OnePlus)。

不要忘了添加此权限

<使用许可权的android:NAME =android.permission.WRITE_EXTERNAL_STORAG​​E/>

在您的清单中。

编辑1: OnePlus是能够复制数据库 /data/data/<package-name>/databases/<filename>.db ,但不允许访问数据和我有关于这毫无头绪。

I want to use my external datbase in MySQL. I have an archived database databse.db.zip and have copied it in the assets folder of my Android Java project. Finally I have created a class for opening the database:

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;

public class databaseOpen extends SQLiteAssetHelper {

private static final String DATABASE_NAME = "parole.db";
private static final int DATABASE_VERSION = 1;

public databaseOpen(Context context) {

    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public String risposta(String parolain ){
    SQLiteDatabase db = getReadableDatabase();
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    String[] selectionArgs = {"ciao"};
    Cursor c =db.query("prima", null, null,selectionArgs, null, null,   null);
    c.moveToFirst();

    return c.getString(0);
}
}

And i have reclaimed it in my main:

private databaseOpen db;

@Override
protected void onCreate(Bundle savedInstanceState) {
    db = new databaseOpen(this);
    Toast toast=Toast.makeText(this, db.risposta("ciao"), Toast.LENGTH_LONG);
}

but it doesn't work. Here is the output I'm getting:

09-26 15:20:23.761    1099-1099/? I/SQLiteAssetHelper successfully opened database parole.db
09-26 15:20:23.764    1099-1099/? E/SQLiteLog (1) no such table: prima
09-26 15:20:23.783    1099-1099/? D/AndroidRuntime Shutting down VM
09-26 15:20:23.801    1099-1099/? E/AndroidRuntime FATAL EXCEPTION: main
    Process: com.example.roby.jarvis, PID: 1099
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.roby.jarvis/com.example.roby.jarvis.Home}: android.database.sqlite.SQLiteException: no such table: prima (code 1): , while compiling: SELECT * FROM prima

解决方案

First : You are not copying the Database file from your assets file to your device, which will obviously result into no such table found.

Try this code, its working for me. (Also i have commented different sections for your understanding)

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.util.Log;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
* Created by HP-HP on 23-07-2015.
*/
public class DataBaseHelper extends SQLiteOpenHelper {

//The Android's default system path of your application database.
private static String DB_PATH ;

private static String DB_NAME = "profanityv2";

private SQLiteDatabase myDataBase;

private final Context myContext;

/**
 * Constructor
 * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
 * @param context
 */
public DataBaseHelper(Context context) {

    super(context, DB_NAME, null, 1);

    if(android.os.Build.VERSION.SDK_INT >= 4.2){
        DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
    } else {
        DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    }

    this.myContext = context;
}

/**
 * Creates a empty database on the system and rewrites it with your own database.
 * */
public void createDataBase() throws IOException {

    boolean dbExist = checkDataBase();

    if(dbExist){
        //do nothing - database already exist
    }else{

        //By calling this method and empty database will be created into the default system path
        //of your application so we are gonna be able to overwrite that database with our database.
        this.getReadableDatabase();

        try {

            copyDataBase();

        } catch (IOException e) {

            throw new Error("Error copying database");

        }
    }

}

/**
 * Check if the database already exist to avoid re-copying the file each time you open the application.
 * @return true if it exists, false if it doesn't
 */
private boolean checkDataBase(){

    SQLiteDatabase checkDB = null;

    try{
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

    }catch(SQLiteException e){

        //database does't exist yet.
        try {
            myContext.deleteDatabase("profanity");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    if(checkDB != null){

        checkDB.close();

    }

    return checkDB != null;
}

/**
 * Copies your database from your local assets-folder to the just created empty database in the
 * system folder, from where it can be accessed and handled.
 * This is done by transfering bytestream.
 * */
private void copyDataBase() throws IOException{

    //Open your local db as the input stream
    InputStream myInput = myContext.getAssets().open(DB_NAME);

    // Path to the just created empty db
    String outFileName = DB_PATH + DB_NAME;

    //Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    //transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer))>0){
        myOutput.write(buffer, 0, length);
    }

    //Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();

}

public void openDataBase() throws SQLException {

    //Open the database
    String myPath = DB_PATH + DB_NAME;
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS|SQLiteDatabase.CREATE_IF_NECESSARY );

}

@Override
public synchronized void close() {

    if(myDataBase != null)
        myDataBase.close();

    super.close();

}

public Cursor getData() {
    Cursor c = null;
    try {
        c = myDataBase.rawQuery("SELECT * FROM profanity_table", null);
    } catch (Exception e) {
        e.printStackTrace();
    }
    // Note: Master is the one table in External db. Here we trying to access the records of table from external db.
    return c;
}


@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.

}

usage :

DataBaseHelper dataBaseHelper = new DataBaseHelper(this);

    try {
        dataBaseHelper.createDataBase();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {

        dataBaseHelper.openDataBase();

    }catch(SQLException sqle){

        throw sqle;

    }

    Cursor c = dataBaseHelper.getData();

    if(c!=null) {
        /* your cursor code */
        c.close();
    }


    dataBaseHelper.close();

*Note : Some Devices may not be able to able to copy the database to the device.(Known Devices : OnePlus)

Don't forget to add this permission

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

in your manifest.

Edit 1: OnePlus is able to copy the database to /data/data/<package-name>/databases/<filename>.db but it doesn't allow to access that data and i have no clue regarding that.

这篇关于无法在Android应用程序使用外部数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆