不幸的是按钮已停止 - 搜索对话框?

时间:2014-11-12 22:48:29

标签: android eclipse search

我按照一些关于搜索对话框的教程(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>

1 个答案:

答案 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