Android应用程序强制关闭设备

时间:2011-05-14 16:04:01

标签: java android sqlite

在模拟器上,应用运行良好。在设备上,当我试图通过应用程序的数据库复制我的数据库并执行查询时,应用程序强制关闭。知道为什么会发生这种情况吗?我是否必须请求任何类型的权限或清单中的某些内容才能运行?

Database.Java

public class Database extends SQLiteOpenHelper{

//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/gr.BHC.www/databases/";

//Name of the Database to be created.
private static String DB_NAME = "BHCLibrary3.sqlite";

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 Database(Context context) {

    super(context, DB_NAME, null, 1);
    this.myContext = context;
}   


/**
 * Creates a empty database on the system and rewrites it with your own database.
 * */


public void createDataBase() throws IOException{

    //First we check if the database already exists, Method declared later
    boolean dbExist = checkDataBase(); 

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

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

        try {
            copyDataBase(); //Method declared later

        } 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;
    boolean checkdb = false;
    try{
        String myPath = DB_PATH + DB_NAME;
        File dbfile = new File(myPath);
        //checkdb = SQLiteDatabase.openDatabase(myPath,null,SQLiteDatabase.OPEN_READWRITE);
        checkdb = dbfile.exists();
    }
    catch(SQLiteException e){
        System.out.println("Database doesn't exist");
    }

    return checkdb;
}



/**
 * 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 transferring byte stream.
 * */


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();

}


//Opening the Database
public void openDataBase() throws SQLException{

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


}

//Finally overriding a few methods as required

@Override
public synchronized void close() {

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

        super.close();

}

@Override
public void onCreate(SQLiteDatabase db) {

    //First we check if the database already exists, Method declared later
    boolean dbExist = checkDataBase(); 

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

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

        try {
            copyDataBase(); //Method declared later

        } catch (IOException e) {
            throw new Error("Error copying database");
          }
    }
}

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

}

}

Results.java (我运行查询的活动)

public class SearchResults extends ListActivity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.searchresults);


    Database myDbHelper = new Database(null);
    myDbHelper = new Database(this);

  }



 // Get the intent, verify the action and get the query
    Intent intent = getIntent();
    String query = intent.getStringExtra(SearchManager.QUERY);


    SQLiteDatabase myDb = myDbHelper.getReadableDatabase();

 //Executing our query against the server using rawQuery and getting the cursor
    String select="SELECT DISTINCT b._ISBN as _id, b.BookTitle, b.Edition, b.Year, b.Pages, b.Rating, c.Category, p.Publisher, w.LastName" +
            "   FROM" +
            "   Books b" +
            "   JOIN Categories_Books cb ON cb._Books_ISBN = _id" +
            "   JOIN Categories c ON c._CategoryID = cb._Categories_CategoryID" +
            "   JOIN Publishers p ON p._PublisherID = b.PublisherID" +
            "   JOIN Writers_Books wb ON wb._Books_ISBN = _id" +
            "   JOIN Writers w ON w._WriterID = wb._Writers_WriterID" +
            "   WHERE b.BookTitle LIKE '%" + query +"%'" +
            "   OR c.Category LIKE '%" + query +"%'" +
            "   OR p.Publisher LIKE '%" + query +"%'" +
            "   OR w.LastName LIKE '%" + query +"%'" +
            "   OR _id LIKE '%" + query +"%'" +
            "   GROUP BY b.BookTitle";


    Cursor c = myDb.rawQuery(select, null);
    startManagingCursor(c);



 // the desired columns to be bound
    String[] columns = new String[] { "Books.BookTitle", "Publishers.Publisher" }; 
 // the XML defined views which the data will be bound to
    int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };

 //Getting results into our listview
    try
    {
        SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.listlayout, c, columns, to);
        this.setListAdapter(mAdapter);
    }
    catch( Exception e)
    {

    }
}

}

帮助将不胜感激。

编辑:我得到的错误是:java.lang.runtimeexception:无法启动活动Componentinfo(gr.BHC.www / gr.BHC.www.SearchResults},然后表示不存在表书等的各种异常。

EDIT2:我看到异常通常与内容提供商有关,但我仍然无法弄清楚为什么我会这样做。

2 个答案:

答案 0 :(得分:1)

我想我解决了这个问题。我对您的代码进行了一些更改,现在它正在运行。以下是代码:

SearchResults.java

public class SearchResults extends ListActivity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//      setContentView(R.layout.searchresults);

        DbManager myDbHelper = new DbManager(null);
        myDbHelper = new DbManager(this);

        // Get the intent, verify the action and get the query

        myDbHelper.createNewDatabase();


        try {
            myDbHelper.open();
            Log.d("Search Results", "database opened");
        } catch (SQLException sqle) {
            throw sqle;
        }

        Intent intent = getIntent();
        String query = intent.getStringExtra(SearchManager.QUERY);

        // Executing our query against the server using rawQuery and getting the
        // cursor
        String select = "SELECT DISTINCT b._ISBN as _id, b.BookTitle, b.Edition, b.Year, b.Pages, b.Rating, c.Category, p.Publisher, w.LastName"
                + "   FROM"
                + "   Books b"
                + "   JOIN Categories_Books cb ON cb._Books_ISBN = _id"
                + "   JOIN Categories c ON c._CategoryID = cb._Categories_CategoryID"
                + "   JOIN Publishers p ON p._PublisherID = b.PublisherID"
                + "   JOIN Writers_Books wb ON wb._Books_ISBN = _id"
                + "   JOIN Writers w ON w._WriterID = wb._Writers_WriterID"
                + "   WHERE b.BookTitle LIKE '%"
                + query
                + "%'"
                + "   OR c.Category LIKE '%"
                + query
                + "%'"
                + "   OR p.Publisher LIKE '%"
                + query
                + "%'"
                + "   OR w.LastName LIKE '%"
                + query
                + "%'"
                + "   OR _id LIKE '%"
                + query
                + "%'"
                + "   GROUP BY b.BookTitle";

        Cursor c = myDbHelper.rawQ(select);
        startManagingCursor(c);

        // the desired columns to be bound
        String[] columns = new String[] { "Books.BookTitle",
                "Publishers.Publisher" };
        // the XML defined views which the data will be bound to
        int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };

        // Getting results into our listview
        try {
            SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
                    R.layout.listlayout, c, columns, to);
            this.setListAdapter(mAdapter);
        } catch (Exception e) {

        }
    }
}

你的新数据库助手DbManager:

DbManager.java

public class DbManager extends SQLiteOpenHelper {

    private static final String DB_NAME = "BHCLibrary3.sqlite";
    private static final String DB_PATH = "/data/data/gr.BHC.www/databases/";
    private static final Integer DB_VERSION = 1;
    private static final String TAG = "DbManager";
    private final Context context;
    private SQLiteDatabase db;
    private DbManager dbManager;

    public DbManager(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        this.context = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE 'notes' (_id integer primary key autoincrement, title text not null);");
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    }

    public DbManager open() {
        dbManager = new DbManager(context);
        db = dbManager.getWritableDatabase();
        return this;
    }

    public void createNewDatabase() {
        InputStream assetsDB = null;
        try {
            assetsDB = context.getAssets().open(DB_NAME);
            OutputStream dbOut = new FileOutputStream(DB_PATH + DB_NAME);

            byte[] buffer = new byte[1024];
            int length;
            while ((length = assetsDB.read(buffer)) > 0) {
                dbOut.write(buffer, 0, length);
            }

            dbOut.flush();
            dbOut.close();
            assetsDB.close();
            Log.i(TAG, "New database created...");
        } catch (IOException e) {
            Log.e(TAG, "Could not create new database...");
            e.printStackTrace();
        }
    }

    public Cursor rawQ(String select) {
        return db.rawQuery(select, null);
    }
}

答案 1 :(得分:0)

看起来您的数据库大小超过一MB。在这种情况下,您需要将其作为.jpg存储在assets文件夹中,然后将其复制。这是因为Android对文本资产的大小设置了限制。