选择建议后,Android搜索不会返回结果

时间:2013-06-24 18:49:11

标签: android android-searchmanager android-search

我有一个简单的应用程序,它只使用硬件搜索键通过我的内容提供商搜索我的数据库。从建议中获得结果并单击其中一个选项后,列表视图屏幕将显示为空白。我收到一个错误:

E/InputQueue-JNI(1137): channel '4150a5d0 PopupWindow:412ccf98 (client)' ~ Publisher closed input channel or an error occurred.  events=0x8

我是Android开发的新手,我做了一些研究,但无法弄清楚这甚至意味着什么。

这是完整的logcat:

06-24 14:54:03.154: I/TDAProvider(1137): query 
06-24 14:54:03.924: I/TDAProvider(1137): query return cursor 
06-24 14:54:04.014: I/TDAProvider(1137): query 
06-24 14:54:04.304: I/TDAProvider(1137): query return cursor 
06-24 14:54:04.754: D/dalvikvm(1137): GC_CONCURRENT freed 137K, 3% free 9374K/9607K, paused 23ms+28ms
06-24 14:54:07.154: E/InputQueue-JNI(1137): channel '4150a5d0 PopupWindow:412ccf98 (client)' ~ Publisher closed input channel or an error occurred.  events=0x8
06-24 14:54:07.464: I/TDAProvider(1137): query 
06-24 14:54:07.464: I/TDAProvider(1137): query return cursor 
06-24 14:54:07.694: I/dalvikvm(1137): threadid=3: reacting to signal 3
06-24 14:54:07.745: I/dalvikvm(1137): Wrote stack traces to '/data/anr/traces.txt'

有关如何解决此问题或对其进行调试的任何建议都将受到欢迎。

由于大部分处理都是由android类完成的,我不知道该怎么看。我正在使用来自我的内容提供商(TDAProvider.java)的2 uri的'SEARCH'和'CONTENT_URI_RULES'。我的猜测是内容提供商存在问题,但我不确定是什么。

这是我的清单文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ActivityMain"
     >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="64dp"
    android:layout_marginTop="22dp"
    android:text="Test Search - using hardware button. Search for 'check'"
    android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

这是我放入xml文件夹的我的searchable.xml。

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:searchSettingsDescription="@string/search_description"
android:searchSuggestAuthority="com.birdsall.tda.contentprovidertda"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://com.birdsall.tda.TDAProvider/rules" >

</searchable>

这里是用于促进搜索的ActivitySearch.java:

package com.birdsall.tda;

import android.app.ListActivity;
import android.app.LoaderManager;
import android.app.SearchManager;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.SimpleCursorAdapter;

public class ActivitySearch extends ListActivity implements
    LoaderManager.LoaderCallbacks<Cursor> {

private SimpleCursorAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create a new adapter and bind it to the List View
    adapter = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_1, null,
            new String[] { TDAdb.COL_RULETITLE },
            new int[] { android.R.id.text1 }, 0);
    setListAdapter(adapter);

    // Initiate the Cursor Loader
    getLoaderManager().initLoader(0, null, this);

    // Get the launch Intent
    parseIntent(getIntent());
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    parseIntent(getIntent());
}

private static String QUERY_EXTRA_KEY = "QUERY_EXTRA_KEY";

private void parseIntent(Intent intent) {
    // If the Activity was started to service a Search request,
    // extract the search query.
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String searchQuery = intent.getStringExtra(SearchManager.QUERY);

        // Perform the search, passing in the search query as an argument
        // to the Cursor Loader
        Bundle args = new Bundle();
        args.putString(QUERY_EXTRA_KEY, searchQuery);

        // Restart the Cursor Loader to execute the new query.
        getLoaderManager().restartLoader(0, args, this);
    }
}

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String query = "0";

    if (args != null) {
        // Extract the search query from the arguments.
        query = args.getString(QUERY_EXTRA_KEY);
    }

    // Construct the new query in the form of a Cursor Loader.
    String[] projection = { TDAdb.KEY_ROWID, TDAdb.COL_RULETITLE };
    String where = TDAdb.COL_RULETITLE + " LIKE \"%" + query + "%\"";
    String[] whereArgs = null;
    String sortOrder = TDAdb.COL_RULETITLE;

    // Create the new Cursor loader.
    return new CursorLoader(this, TDAProvider.CONTENT_URI_RULES,
            projection, where, whereArgs, sortOrder);
}

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    // Replace the result Cursor displayed by the Cursor Adapter with
    // the new result set.
    adapter.swapCursor(cursor);
}

public void onLoaderReset(Loader<Cursor> loader) {
    // Remove the existing result Cursor from the List Adapter.
    adapter.swapCursor(null);
}

}

这是内容提供程序(TDAProvider.java),我确实使用了一些原始查询,但不是这个例子:

package com.birdsall.tda;

import java.util.HashMap;

import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class TDAProvider extends ContentProvider {

private TDAdbHelper dbHelper;
private static final String TAG = "TDAProvider";

private static final int ALL_CHAPTERS = 1;
private static final int SINGLE_CHAPTER = 2;
private static final int ALL_RULES = 3;
private static final int SINGLE_RULE = 4;
private static final int ALL_RAW_QUERY = 5;
private static final int SINGLE_RAW_QUERY = 6;
private static final int SEARCH = 7;
// authority is the symbolic name of your provider
// To avoid conflicts with other providers, you should use
// Internet domain ownership (in reverse) as the basis of your provider
// authority.
private static final String AUTHORITY = "com.birdsall.tda.contentprovidertda";

// create content URIs from the authority by appending path to database
// table
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
        + "/chapters");

public static final Uri CONTENT_URI_RULES = Uri.parse("content://"
        + AUTHORITY + "/rules");

public static final Uri CONTENT_URI_RAWQUERY = Uri.parse("content://"
        + AUTHORITY + "/rawquery");

// a content URI pattern matches content URIs using wildcard characters:
// *: Matches a string of any valid characters of any length.
// #: Matches a string of numeric characters of any length.
private static final UriMatcher uriMatcher;
static {
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(AUTHORITY, "chapters", ALL_CHAPTERS);
    uriMatcher.addURI(AUTHORITY, "chapters/#", SINGLE_CHAPTER);
    uriMatcher.addURI(AUTHORITY, "rules", ALL_RULES);
    uriMatcher.addURI(AUTHORITY, "rules/#", SINGLE_RULE);
    uriMatcher.addURI(AUTHORITY, "rawquery", ALL_RAW_QUERY);
    uriMatcher.addURI(AUTHORITY, "rawquery/#", SINGLE_RAW_QUERY);
    uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY,
            SEARCH);
    uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY
            + "/*", SEARCH);
    uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT,
            SEARCH);
    uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT
            + "/*", SEARCH);
}

// system calls onCreate() when it starts up the provider.
@Override
public boolean onCreate() {
    // get access to the database helper
    Log.i(TAG, "onCreate ");
    dbHelper = new TDAdbHelper(getContext());
    return false;
}

// Return the MIME type corresponding to a content URI
@Override
public String getType(Uri uri) {
    Log.i(TAG, "getType ");
    switch (uriMatcher.match(uri)) {
    case ALL_CHAPTERS:
        return "vnd.android.cursor.dir/vnd.com.birdsall.peter.contentprovidertda.chapters";
    case SINGLE_CHAPTER:
        return "vnd.android.cursor.item/vnd.com.birdsall.peter.contentprovidertda.chapters";
    case ALL_RULES:
        return "vnd.android.cursor.dir/vnd.com.birdsall.peter.contentprovidertda.rules";
    case SINGLE_RULE:
        return "vnd.android.cursor.item/vnd.com.birdsall.peter.contentprovidertda.rules";
    case ALL_RAW_QUERY:
        return "vnd.android.cursor.dir/vnd.com.birdsall.peter.contentprovidertda.rulesdescribed";
    case SINGLE_RAW_QUERY:
        return "vnd.android.cursor.item/vnd.com.birdsall.peter.contentprovidertda.rulesdescribed";
    case SEARCH:
        return SearchManager.SUGGEST_MIME_TYPE;
    default:
        throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
}

private static final HashMap<String, String> SEARCH_PROJECTION_MAP;
static {
    SEARCH_PROJECTION_MAP = new HashMap<String, String>();
    SEARCH_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
            TDAdb.COL_RULETITLE + " AS "
                    + SearchManager.SUGGEST_COLUMN_TEXT_1);
    SEARCH_PROJECTION_MAP.put("_id", TDAdb.KEY_ROWID + " AS " + "_id");
}

// The insert() method adds a new row to the appropriate table, using the
// values
// in the ContentValues argument. If a column name is not in the
// ContentValues argument,
// you may want to provide a default value for it either in your provider
// code or in
// your database schema.
@Override
public Uri insert(Uri uri, ContentValues values) {

    Log.i(TAG, "insert ");
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    switch (uriMatcher.match(uri)) {
    case ALL_CHAPTERS:
        // do nothing
        break;
    default:
        throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
    long id = db.insert(TDAdb.CHAPTER_TABLE, null, values);
    getContext().getContentResolver().notifyChange(uri, null);
    return Uri.parse(CONTENT_URI + "/" + id);
}

// The query() method must return a Cursor object, or if it fails,
// throw an Exception. If you are using an SQLite database as your data
// storage,
// you can simply return the Cursor returned by one of the query() methods
// of the
// SQLiteDatabase class. If the query does not match any rows, you should
// return a
// Cursor instance whose getCount() method returns 0. You should return null
// only
// if an internal error occurred during the query process.
// public Cursor query (Uri uri, String[] projection, String selection,
// String[] selectionArgs,
// String having, String groupby, String sortOrder, String limit,
// CancellationSignal cancellationSignal) {
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {

    String id;
    Log.i(TAG, "query ");

    SQLiteDatabase db = dbHelper.getWritableDatabase();
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    // queryBuilder.setTables(TDAdb.CHAPTER_TABLE);

    switch (uriMatcher.match(uri)) {
    case ALL_CHAPTERS:
        // do nothing
        queryBuilder.setTables(TDAdb.CHAPTER_TABLE);
        break;
    case SINGLE_CHAPTER:
        queryBuilder.setTables(TDAdb.CHAPTER_TABLE);
        id = uri.getPathSegments().get(1);
        queryBuilder.appendWhere(TDAdb.KEY_ROWID + "=" + id);
        break;
    case ALL_RULES:
        // do nothing
        queryBuilder.setTables(TDAdb.RULE_TABLE);
        break;
    case SINGLE_RULE:
        queryBuilder.setTables(TDAdb.RULE_TABLE);
        id = uri.getPathSegments().get(1);
        queryBuilder.appendWhere(TDAdb.KEY_ROWID + "=" + id);
        break;
    case ALL_RAW_QUERY:
        db = dbHelper.getReadableDatabase();
        return db.rawQuery(selection, selectionArgs);
    case SINGLE_RAW_QUERY:
        db = dbHelper.getReadableDatabase();
        return db.rawQuery(selection, selectionArgs);
    case SEARCH:
        queryBuilder.setTables(TDAdb.RULE_TABLE);
        queryBuilder.appendWhere(TDAdb.COL_RULETITLE + " LIKE \"%"
                + uri.getPathSegments().get(1) + "%\"");
        queryBuilder.setProjectionMap(SEARCH_PROJECTION_MAP);
        break;
    default:
        throw new IllegalArgumentException("Unsupported URI: " + uri);
    }

    Cursor cursor = queryBuilder.query(db, projection, selection,
            selectionArgs, null, null, sortOrder);
    Log.i(TAG, "query return cursor ");
    // Register the contexts ContentResolver to be notified if
    // the cursor result set changes.
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    return cursor;

}

// The delete() method deletes rows based on the seletion or if an id is
// provided then it deleted a single row. The methods returns the numbers
// of records delete from the database. If you choose not to delete the data
// physically then just update a flag here.
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {

    Log.i(TAG, "delete ");
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    switch (uriMatcher.match(uri)) {
    case ALL_CHAPTERS:
        // do nothing
        break;
    case SINGLE_CHAPTER:
        String id = uri.getPathSegments().get(1);
        selection = TDAdb.KEY_ROWID
                + "="
                + id
                + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                        + ')' : "");
        break;
    default:
        throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
    int deleteCount = db.delete(TDAdb.CHAPTER_TABLE, selection,
            selectionArgs);
    getContext().getContentResolver().notifyChange(uri, null);
    return deleteCount;
}

// The update method() is same as delete() which updates multiple rows
// based on the selection or a single row if the row id is provided. The
// update method returns the number of updated rows.
@Override
public int update(Uri uri, ContentValues values, String selection,
        String[] selectionArgs) {
    Log.i(TAG, "update ");
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    switch (uriMatcher.match(uri)) {
    case ALL_CHAPTERS:
        // do nothing
        break;
    case SINGLE_CHAPTER:
        String id = uri.getPathSegments().get(1);
        selection = TDAdb.KEY_ROWID
                + "="
                + id
                + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                        + ')' : "");
        break;
    default:
        throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
    int updateCount = db.update(TDAdb.CHAPTER_TABLE, values, selection,
            selectionArgs);
    getContext().getContentResolver().notifyChange(uri, null);
    Log.i(TAG, "update return updateCount ");
    return updateCount;
}

}

这是数据库活动(TDAdb.java):

package com.birdsall.tda;

import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class TDAdb {

public static final String LOG_TAG = "TDAdb";

// tables
public static final String CHAPTER_TABLE = "chapters";
public static final String RULE_TABLE = "rules";
public static final String INDEXHEADER_TABLE = "indexheader";
public static final String KEYDESCRIPTORS_TABLE = "keydescriptors";
public static String SQLITE_TABLE = "chapters";

// Chapter Table Columns
public static final String KEY_ROWID = "_id";
public static final String COL_CHAPTER = "chapter";
public static final String COL_CHAPTERTITLE = "chaptertitle";

// Rule Table Columns
public static final String COL_RULE = "rule";
// public static final String COL_CHAPTER = "chapter";
public static final String COL_KEYDESCRIPTOR = "keydescriptor";
public static final String COL_RULETITLE = "ruletitle";
public static final String COL_DESCR = "descr";
public static final String COL_DESCRIPTION = "description"; // LongText
public static final String COL_LABEL = "label";
public static final String COL_USERLABEL = "userlabel";
public static final String COL_LABELID = "labelid"; // Integer
public static final String COL_USERLABELID = "userlabelid"; // Integer
public static final String COL_TDTIP = "tdtip";
public static final String COL_DEFUNCT = "defunct";
public static final String COL_USCFREVISION = "uscfrevision";
public static final String COL_HIGHLIGHT = "highlight"; // LongText
public static final String COL_PAGENO = "pageno";
public static final String COL_CHANGEDATE = "changedate"; // Integer
public static final String COL_REFINC = "refinc";
public static final String COL_RULEINC = "ruleinc";

// keydescriptors table columns
public static final String COL_KEYDESC = "keydesc";
public static final String COL_IMAGEREFERENCE = "imagereference";

// indexheader table columns
public static final String COL_INDEX_HEADER = "index_header";
public static final String COL_INDEXID = "indexid";
public static final String COL_INDEXLEXICON = "indexlexicon";

// columns defined in RAW Queries via AS
public static final String COLRAW_XREFRULE = "xrefrule";
public static final String COL_PROJ_THECOUNT = "count(*) as thecound";
public static final String COLTHECOUNT = "thecound";

public static final String[] PROJECTION_CHAPTER = { KEY_ROWID, COL_CHAPTER,
        COL_CHAPTERTITLE, };

public static final String[] PROJECTION_RULES = { KEY_ROWID, COL_CHAPTER,
        COL_RULE, COL_RULETITLE, COL_KEYDESCRIPTOR, };

/* ************** MAKE SURE THERE'S and _id *********************** */
public static final String RAWQUERY_RULESDESCRIBED = "select rules._id, rule, chapter, ruletitle, rules.keydescriptor, keydesc FROM rules LEFT OUTER JOIN keydescriptors ON rules.keydescriptor = keydescriptors.keydescriptor WHERE chapter = ? group by 1, 2, 3, 4, 5 order by 1, 4";
public static final String RAWQUERY_RULESCROSSREF = "SELECT rules._id, rules.rule, rules.ruletitle,  rulereferences.rule AS xrefrule FROM rulereferences INNER JOIN rules ON rulereferences.rulereference = rules.rule WHERE (((rules.keydescriptor)='2') AND ((rulereferences.rule)= ? )) ORDER BY rules.rule";
public static final String RAWQUERY_RULESCROSSREFDETAIL = "SELECT rules._id, rules.rule, rules.ruletitle, keydescriptors.keydesc FROM rules INNER JOIN keydescriptors ON rules.keydescriptor = keydescriptors.keydescriptor WHERE (((rules.rule)= ? )) GROUP BY rules.rule, rules.ruletitle, keydescriptors.keydesc ORDER BY rules.rule, Min(rules.keydescriptor)";
public static final String RAWQUERY_INDEX = "SELECT DISTINCT _id, indexlexicon FROM indexheader GROUP BY 2 ORDER BY 2";
public static final String RAWQUERY_INDEXCHILD = "SELECT indexheader._id, indexheader.index_header, indexer.rule, indexheader.indexid, rules.pageno, rules.uscfrevision, rules.defunct FROM (indexheader LEFT JOIN indexer ON indexheader.indexid = indexer.indexid) LEFT JOIN rules ON indexer.rule = rules.rule WHERE (((indexheader.indexlexicon)= ? )) GROUP BY indexheader._id, indexheader.index_header, indexer.rule, indexheader.indexid, rules.pageno, rules.uscfrevision, rules.defunct HAVING (((rules.pageno) Is Not Null)) ORDER BY indexheader.index_header, indexheader.indexid";
public static final String RAWQUERY_RULEDETAIL = "SELECT rules.rule, rules.ruletitle, rules.descr, rules.description, rules.keydescriptor, rules.tdtip, rules.uscfrevision, rules.defunct, rules.highlight, rules.label, rules.userlabel, rules.changedate FROM rules GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 HAVING (((rules.rule)= ? )) ORDER BY 1, 5";
public static final String RAWQUERY_LABEL = "select distinct _id, label, count(*) as thecount from rules group by 2 order by label";
public static final String RAWQUERY_LABELDETAIL = "SELECT rules._id, rules.rule, rules.ruletitle, keydescriptors.keydesc FROM rules INNER JOIN keydescriptors ON rules.keydescriptor = keydescriptors.keydescriptor WHERE (((rules.label)= ? )) GROUP BY rules.rule, rules.ruletitle, keydescriptors.keydesc ORDER BY rules.rule, Min(rules.keydescriptor)";

public static void onCreate(SQLiteDatabase db) {

    Log.i(LOG_TAG, "onCreate");
}

public static void onUpgrade(SQLiteDatabase db, int oldVersion,
        int newVersion) {
    Log.w(LOG_TAG, "Upgrading database from version " + oldVersion + " to "
            + newVersion + ", which will destroy all old data");

    onCreate(db);
}
}

这是数据库助手(TDAdbHelper.java):

package com.birdsall.tda;

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

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class TDAdbHelper extends SQLiteOpenHelper {

public static String DATABASE_PATH;
public static final String DATABASE_NAME = "tda.db";
private static final int DATABASE_VERSION = 1;
private Context context;
private SQLiteDatabase db;

public TDAdbHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.context = context;
    String packageName = context.getPackageName();
    DATABASE_PATH = String.format("//data//data//%s//databases//",
            packageName);
    Log.i(this.getClass().toString(), "... before calling openDatabase ");
    openDataBase();
    Log.i(this.getClass().toString(), "... after return openDatabase ");
}

@Override
public void onCreate(SQLiteDatabase db) {
    Log.i(this.getClass().toString(), "... Starting TDAdb.onCreate ");
    TDAdb.onCreate(db);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    TDAdb.onUpgrade(db, oldVersion, newVersion);
}

// Performing a database existence check
private boolean checkDataBase() {
    Log.i(this.getClass().toString(), "... Starting checkDatabase ");
    SQLiteDatabase checkDb = null;
    try {
        String path = DATABASE_PATH + DATABASE_NAME;
        checkDb = SQLiteDatabase.openDatabase(path, null,
                SQLiteDatabase.OPEN_READONLY);
    } catch (SQLException e) {
        Log.e(this.getClass().toString(), "Error while checking db");
    }
    // Android doesn’t like resource leaks, everything should
    // be closed
    if (checkDb != null) {
        checkDb.close();
    }
    return checkDb != null;
}

// Method for copying the database
private void copyDataBase() throws IOException {
    // Open a stream for reading from our ready-made database
    // The stream source is located in the assets
    Log.i(this.getClass().toString(), "... in copyDataBase ");
    InputStream externalDbStream = context.getAssets().open(DATABASE_NAME);

    // Path to the created empty database on your Android device
    String outFileName = DATABASE_PATH + DATABASE_NAME;

    // Now create a stream for writing the database byte by byte
    OutputStream localDbStream = new FileOutputStream(outFileName);

    // Copying the database
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = externalDbStream.read(buffer)) > 0) {
        localDbStream.write(buffer, 0, bytesRead);
    }
    // Don’t forget to close the streams
    localDbStream.close();
    externalDbStream.close();
}

// This piece of code will create a database if it’s not yet created
public void createDataBase() {
    Log.i(this.getClass().toString(), "... in createDataBase ");
    boolean dbExist = checkDataBase();
    if (!dbExist) {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            Log.e(this.getClass().toString(), "Copying error");
            throw new Error("Error copying database!");
        }
    } else {
        Log.i(this.getClass().toString(), "Database already exists");
    }
}

public SQLiteDatabase openDataBase() throws SQLException {
    String path = DATABASE_PATH + DATABASE_NAME;
    Log.i(this.getClass().toString(), "Starting openDatabase " + path);
    if (db == null) {
        createDataBase();
        db = SQLiteDatabase.openDatabase(path, null,
                SQLiteDatabase.OPEN_READWRITE);
    }

    return db;
}

}

为了完整性,有一个主要的活动(ActivityMain.java),就像一个简单的Hello World:

package com.birdsall.tda;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class ActivityMain extends Activity {

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


}

主要活动(activity_main.xml)的简单布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ActivityMain"
     >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="64dp"
    android:layout_marginTop="22dp"
    android:text="Test Search - using hardware button. Search for 'check'"
    android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

因此,如果您对如何修复或调试此问题有任何想法,我将不胜感激。请记住,我是Android开发人员的新手,所以关于原因的几句话也会有所帮助。

度过美好的一天。

1 个答案:

答案 0 :(得分:0)

我在考虑一件事而不是另一件事。建议显示,单击其中一个OF COURSE将不会显示任何内容,没有实现的方法来处理SearchAdapter中的onClick(或其他任何调用)。当您点击键盘上的“开始”按钮时,结果将发布到列表视图中。显然,我太接近问题,我。