我按照一些关于搜索对话框的教程(http://devmobapps.blogspot.com/2011/10/using-android-search-dialog-part-3.html)。在eclipse中没有红色错误,但是当我尝试运行应用程序时,它说不幸的是按钮停止了。
logcat的
11-12 23:31:26.499: D/AndroidRuntime(668): CheckJNI is ON
11-12 23:31:26.573: D/dalvikvm(668): Trying to load lib libjavacore.so 0x0
11-12 23:31:26.593: D/dalvikvm(668): Added shared lib libjavacore.so 0x0
11-12 23:31:26.663: D/dalvikvm(668): Trying to load lib libnativehelper.so 0x0
11-12 23:31:26.663: D/dalvikvm(668): Added shared lib libnativehelper.so 0x0
11-12 23:31:27.772: D/AndroidRuntime(668): Calling main entry com.android.commands.am.Am
11-12 23:31:27.823: I/ActivityManager(150): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.bogdanskoric.dictionary/.MainActivity u=0} from pid 668
11-12 23:31:27.833: W/WindowManager(150): Failure taking screenshot for (246x410) to layer 21005
11-12 23:31:27.913: D/dalvikvm(679): Not late-enabling CheckJNI (already on)
11-12 23:31:27.923: D/AndroidRuntime(668): Shutting down VM
11-12 23:31:27.933: D/dalvikvm(36): WAIT_FOR_CONCURRENT_GC blocked 0ms
11-12 23:31:27.942: I/ActivityManager(150): Start proc com.bogdanskoric.dictionary for activity com.bogdanskoric.dictionary/.MainActivity: pid=679 uid=10051 gids={1028}
11-12 23:31:27.993: I/AndroidRuntime(668): NOTE: attach of thread 'Binder_3' failed
11-12 23:31:27.993: D/dalvikvm(668): GC_CONCURRENT freed 102K, 77% free 489K/2048K, paused 1ms+1ms, total 16ms
11-12 23:31:28.013: D/jdwp(668): Got wake-up signal, bailing out of select
11-12 23:31:28.013: D/dalvikvm(668): Debugger has detached; object registry had 1 entries
11-12 23:31:28.114: D/dalvikvm(36): GC_EXPLICIT freed 38K, 4% free 7964K/8259K, paused 8ms+14ms, total 185ms
11-12 23:31:28.124: D/dalvikvm(36): WAIT_FOR_CONCURRENT_GC blocked 0ms
11-12 23:31:28.303: D/dalvikvm(36): GC_EXPLICIT freed <1K, 4% free 7964K/8259K, paused 27ms+48ms, total 181ms
11-12 23:31:28.333: D/dalvikvm(36): WAIT_FOR_CONCURRENT_GC blocked 0ms
11-12 23:31:28.453: D/dalvikvm(36): GC_EXPLICIT freed <1K, 4% free 7964K/8259K, paused 5ms+13ms, total 126ms
11-12 23:31:28.823: E/Trace(679): error opening trace file: No such file or directory (2)
11-12 23:31:29.182: I/ActivityThread(679): Pub com.bogdanskoric.dictionary.SuggestionProvider: com.bogdanskoric.dictionary.SuggestionProvider
11-12 23:31:29.413: D/AndroidRuntime(679): Shutting down VM
11-12 23:31:29.413: W/dalvikvm(679): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
11-12 23:31:29.453: E/AndroidRuntime(679): FATAL EXCEPTION: main
11-12 23:31:29.453: E/AndroidRuntime(679): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bogdanskoric.dictionary/com.bogdanskoric.dictionary.MainActivity}: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.os.Looper.loop(Looper.java:137)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.ActivityThread.main(ActivityThread.java:4745)
11-12 23:31:29.453: E/AndroidRuntime(679): at java.lang.reflect.Method.invokeNative(Native Method)
11-12 23:31:29.453: E/AndroidRuntime(679): at java.lang.reflect.Method.invoke(Method.java:511)
11-12 23:31:29.453: E/AndroidRuntime(679): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-12 23:31:29.453: E/AndroidRuntime(679): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-12 23:31:29.453: E/AndroidRuntime(679): at dalvik.system.NativeStart.main(Native Method)
11-12 23:31:29.453: E/AndroidRuntime(679): Caused by: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.ListActivity.onContentChanged(ListActivity.java:243)
11-12 23:31:29.453: E/AndroidRuntime(679): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:259)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.Activity.setContentView(Activity.java:1867)
11-12 23:31:29.453: E/AndroidRuntime(679): at com.bogdanskoric.dictionary.MainActivity.onCreate(MainActivity.java:26)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.Activity.performCreate(Activity.java:5008)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-12 23:31:29.453: E/AndroidRuntime(679): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-12 23:31:29.453: E/AndroidRuntime(679): ... 11 more
11-12 23:31:29.482: W/ActivityManager(150): Force finishing activity com.bogdanskoric.dictionary/.MainActivity
11-12 23:31:29.523: W/WindowManager(150): Failure taking screenshot for (246x410) to layer 21010
11-12 23:31:30.033: W/ActivityManager(150): Activity pause timeout for ActivityRecord{413b0b80 com.bogdanskoric.dictionary/.MainActivity}
11-12 23:31:30.363: I/Choreographer(272): Skipped 60 frames! The application may be doing too much work on its main thread.
11-12 23:31:32.302: I/Process(679): Sending signal. PID: 679 SIG: 9
11-12 23:31:32.493: W/InputMethodManagerService(150): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@41394dc8 attribute=null
11-12 23:31:32.698: I/ActivityManager(150): Process com.bogdanskoric.dictionary (pid 679) has died.
11-12 23:31:41.195: W/ActivityManager(150): Activity destroy timeout for ActivityRecord{413b0b80 com.bogdanskoric.dictionary/.MainActivity}
11-12 23:33:21.643: D/dalvikvm(255): GC_CONCURRENT freed 383K, 7% free 8537K/9159K, paused 30ms+6ms, total 77ms
11-12 23:40:21.313: E/ThrottleService(150): problem during onPollAlarm: java.lang.IllegalStateException: problem parsing stats: java.io.FileNotFoundException: /proc/net/xt_qtaguid/iface_stat_all: open failed: ENOENT (No such file or directory)
11-12 23:40:50.673: D/dalvikvm(255): GC_CONCURRENT freed 384K, 7% free 8537K/9159K, paused 24ms+6ms, total 73ms
11-12 23:48:25.913: D/dalvikvm(255): GC_CONCURRENT freed 384K, 7% free 8537K/9159K, paused 28ms+6ms, total 71ms
11-12 23:50:00.373: D/dalvikvm(150): GC_CONCURRENT freed 582K, 7% free 11556K/12359K, paused 38ms+52ms, total 327ms
11-12 23:50:21.313: E/ThrottleService(150): problem during onPollAlarm: java.lang.IllegalStateException: problem parsing stats: java.io.FileNotFoundException: /proc/net/xt_qtaguid/iface_stat_all: open failed: ENOENT (No such file or directory)
MainActivity.java
package com.bogdanskoric.dictionary;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
public class MainActivity extends ListActivity {
private EditText text;
private Button add;
private RecordsDbHelper mDbHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDbHelper = new RecordsDbHelper(this);
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
showResults(query);
} else if (Intent.ACTION_VIEW.equals(intent.getAction())){
Intent recordIntent = new Intent(this, RecordActivity.class);
recordIntent.setData(intent.getData());
startActivity(recordIntent);
finish();
}
add = (Button) findViewById(R.id.add);
text = (EditText) findViewById(R.id.text);
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String data = text.getText().toString();
if (!data.equals("")) {
saveTask(data);
text.setText("");
}
}
});
}
private void saveTask(String data) {
mDbHelper.createRecord(data);
}
private void showResults(String query) {
Cursor cursor = managedQuery(SuggestionProvider.CONTENT_URI, null, null,
new String[] {query}, null);
if (cursor == null) {
Toast.makeText(this, "There are no results", Toast.LENGTH_SHORT).show();
} else {
String[] from = new String[] { RecordsDbHelper.KEY_DATA };
int[] to = new int[] { R.id.text1 };
SimpleCursorAdapter records = new SimpleCursorAdapter(this, R.layout.record, cursor, from, to);
getListView().setAdapter(records);
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
RecordsHelper.java
import java.util.HashMap;
import android.app.SearchManager;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.provider.BaseColumns;
import android.util.Log;
public class RecordsDbHelper {
public static final String KEY_DATA = SearchManager.SUGGEST_COLUMN_TEXT_1;
private static final String TAG = "RecordsDbHelper";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static final String DATABASE_NAME = "datas";
private static final String DATABASE_TABLE = "records";
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE =
"CREATE VIRTUAL TABLE " + DATABASE_TABLE +
" USING fts3 (" + KEY_DATA + ");";
private static final HashMap<String,String> mColumnMap = buildColumnMap();
public Cursor getRecord(String rowId, String[] columns) {
String selection = "rowid = ?";
String[] selectionArgs = new String[] {rowId};
return query(selection, selectionArgs, columns);
}
public Cursor getRecordMatches(String query, String[] columns) {
String selection = KEY_DATA + " MATCH ?";
String[] selectionArgs = new String[] {query+"*"};
return query(selection, selectionArgs, columns);
}
private static HashMap<String,String> buildColumnMap() {
HashMap<String,String> map = new HashMap<String,String>();
map.put(KEY_DATA, KEY_DATA);
map.put(BaseColumns._ID, "rowid AS " +
BaseColumns._ID);
map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " +
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
return map;
}
private Cursor query(String selection, String[] selectionArgs, String[] columns) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(DATABASE_TABLE);
builder.setProjectionMap(mColumnMap);
Cursor cursor = builder.query(mDbHelper.getReadableDatabase(),
columns, selection, selectionArgs, null, null, null);
if (cursor == null) {
return null;
} else if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
return cursor;
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS records");
onCreate(db);
}
}
public RecordsDbHelper(Context context) {
mDbHelper = new DatabaseHelper(context);
}
public long createRecord(String data) {
mDb = mDbHelper.getWritableDatabase();
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_DATA, data);
return mDb.insert(DATABASE_TABLE, null, initialValues);
}
}
SugestionProvider.java
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
public class SuggestionProvider extends ContentProvider{
private RecordsDbHelper mDbHelper;
public static String AUTHORITY = "com.example.search.SuggestionProvider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/records");
public static final String RECORDS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +
"/vnd.example.search";
public static final String RECORD_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE +
"/vnd.example.search";
private static final int SEARCH_RECORDS = 0;
private static final int GET_RECORD = 1;
private static final int SEARCH_SUGGEST = 2;
private static final UriMatcher sURIMatcher = makeUriMatcher();
@Override
public boolean onCreate() {
mDbHelper = new RecordsDbHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
switch (sURIMatcher.match(uri)) {
case SEARCH_SUGGEST:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return getSuggestions(selectionArgs[0]);
case SEARCH_RECORDS:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return search(selectionArgs[0]);
case GET_RECORD:
return getRecord(uri);
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
private Cursor getSuggestions(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
RecordsDbHelper.KEY_DATA,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return mDbHelper.getRecordMatches(query, columns);
}
private Cursor search(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
RecordsDbHelper.KEY_DATA};
return mDbHelper.getRecordMatches(query, columns);
}
private Cursor getRecord(Uri uri) {
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
RecordsDbHelper.KEY_DATA};
return mDbHelper.getRecord(rowId, columns);
}
private static UriMatcher makeUriMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(AUTHORITY, "records", SEARCH_RECORDS);
matcher.addURI(AUTHORITY, "records/#", GET_RECORD);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
return matcher;
}
@Override
public String getType(Uri uri) {
switch (sURIMatcher.match(uri)) {
case SEARCH_RECORDS:
return RECORDS_MIME_TYPE;
case SEARCH_SUGGEST:
return SearchManager.SUGGEST_MIME_TYPE;
case GET_RECORD:
return RECORD_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
throw new UnsupportedOperationException();
}
@Override
public Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException();
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
}
RecordActivity.java
package com.bogdanskoric.dictionary;
import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.widget.TextView;
public class RecordActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.record_activity);
Uri uri = getIntent().getData();
Cursor cursor = managedQuery(uri, null, null, null, null);
if (cursor == null) {
finish();
} else {
cursor.moveToFirst();
TextView record = (TextView) findViewById(R.id.record_header);
int rIndex = cursor.getColumnIndexOrThrow(RecordsDbHelper.KEY_DATA);
record.setText(cursor.getString(rIndex));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
}
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:orientation="horizontal" >
<EditText
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dp"
android:layout_weight="10"
android:ems="10"
android:text="@string/text" >
<requestFocus />
</EditText>
<Button
android:id="@+id/add"
android:layout_width="70dp"
android:layout_height="50dp"
android:layout_above="@+id/empty"
android:layout_toRightOf="@+id/text"
android:ems="5"
android:text="@string/add"
android:textSize="15dp" />
<TextView
android:id="@+id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/text"
android:layout_toLeftOf="@+id/add"
android:text="@string/no_records" />
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/empty"
android:layout_below="@+id/empty"
android:layout_marginTop="16dp" >
</ListView>
</RelativeLayout>
record_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp">
<TextView
android:id="@+id/record_header"
android:textSize="25dp"
android:textColor="?android:textColorPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
record.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id ="@+id/text1"
xmlns:android ="http://schemas.android.com/apk/res/android"
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
/>
string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Dictionary</string>
<string name="add">Add</string>
<string name="text">Enter text</string>
<string name="no_records">There are no records in the table</string>
<string name="search_hint">Add</string>
<string name="search">Search</string>
<string name="action_settings">Settings</string>
</resources>
XML / searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint"
android:searchMode="queryRewriteFromText"
android:includeInGlobalSearch="true"
android:searchSuggestAuthority="com.example.search.SuggestionProvider"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://com.example.search.SuggestionProvider/records"
android:searchSuggestThreshold="1"
android:searchSuggestSelection=" ?">
</searchable>
答案 0 :(得分:0)
将此用作列表的XML
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/empty"
android:layout_below="@+id/empty"
android:layout_marginTop="16dp" >
</ListView>
由于您使用的是ListActivity,因此XML文件必须在提及ID时指定关键字android
。