Форум программистов, компьютерный форум CyberForum.ru

Что я неправильно делаю при реализации поиска? - Android

Восстановить пароль Регистрация
 
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
21.10.2014, 14:51     Что я неправильно делаю при реализации поиска? #1
Мучаюсь уже второй день. Подскажите что не так. Задача сделать поиск в справочнике. Все делаю по гайду - прописываю в манифесте, что текущая активити -это searchable activity, далее в коде вызываю Intent, с которого получаю запрос. Далее в классе которые обрабатывает базу данных пишу запрос с LIKE что бы извлечь все подходящие запросы. Проблема как я понял в методе
Java
1
doMySearch(query);
. Куда и как правльно мне вывести результаты поиска? В приведенном ниже коде (который не работает), запрос выводится в ListView с помощью адаптера.
Подскажите как сделать правильно, сил уже нет...
p.s. В качестве searchable activity используется текущая MainActivity (правильно ли это?):

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.example.citycode;
 
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuInflater;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
 
public class MainActivity extends ActionBarActivity {
 
  private static final int CM_DELETE_ID = 1;
  ListView lvData;
  DBHelper db;
  SimpleCursorAdapter scAdapter;
  SimpleCursorAdapter records;
  Cursor cursor;
  Cursor cursor1;
 
  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    // открываем подключение к БД
    db = new DBHelper(this);
    db.open();
    
    // Get the intent, verify the action and get the query
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }
    
    // получаем курсор
    cursor = db.getAllData();
    startManagingCursor(cursor);
    
    // Формируем столбцы сопоставления
    String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
    int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };
 
    // создааем адаптер и настраиваем список
    scAdapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from, to);
    lvData = (ListView) findViewById(R.id.listdata);
    lvData.setAdapter(scAdapter);
  }
  
  public void doMySearch(String query) {
        //Ищем совпадения
        cursor1 = db.fetchRecordsByQuery(query);
        startManagingCursor(cursor1);
        String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
        int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };
 
        SimpleCursorAdapter records = new SimpleCursorAdapter(this,
                R.layout.item, cursor1, from, to);
        //Обновляем адаптер
        lvData.setAdapter(records);
      }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the options menu from XML
      MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.main, menu);
 
      // Get the SearchView and set the searchable configuration
      SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
      SearchView searchView = (SearchView) menu.findItem(R.id.action_settings).getActionView();
      // Assumes current activity is the searchable activity
      searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
      searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
 
      return true;
  }
 
  
  protected void onDestroy() {
    super.onDestroy();
    // закрываем подключение при выходе
    db.close();
  }
 
}
Из класса БД:
Java
1
2
3
4
5
6
      String sqlQuery1 = "SELECT * FROM city as t1, region as t2 WHERE t1.name LIKE" + "'%" + "?" + "%';";
      
         //Поиск запросом LIKE
      public Cursor fetchRecordsByQuery(String query) {
          return  myDataBase.rawQuery(sqlQuery1, new String[] {query});
      }
Вот такая ошибка выдается если я жму на поиск, вбиваю запрос и жму enter:

10-21 13:50:03.697: E/AndroidRuntime(12899): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.citycode/com.example.citycode.MainActivity}: java.lang.IllegalArgumentException: Cannot bind argument at index 1 because the index is out of range. The statement has 0 parameters.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Rube
910 / 558 / 87
Регистрация: 13.02.2014
Сообщений: 2,064
22.10.2014, 12:03     Что я неправильно делаю при реализации поиска? #2
Сколько cursor1.getCount()?
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
22.10.2014, 18:02  [ТС]     Что я неправильно делаю при реализации поиска? #3
Была ошибка в запросе, вы правы. Поменял на
Java
1
String sqlQuery1 = "SELECT * FROM city AS t1, region AS t2 WHERE t1.name LIKE '%' || ? || '%';";
и
Java
1
cursor1.getCount()
стал выдавать 42000.
Но все равно приложение не работает. Сейчас выдает ошибку:

10-22 12:10:00.905: E/AndroidRuntime(10353): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.citycode/com.example.citycode.MainActivity}: java.lang.NullPointerException

Что то не так видимо с реализацией Search... А что - без понятия... Очень нужна помощь.

Добавлено через 1 час 17 минут
Кстати, прописал логи после каждого действия, ошибка как я понял вылазит на этапе -
Java
1
2
        //Обновляем адаптер
        lvData.setAdapter(records);
в методе doMySearch(query);

Т.е. до обновления адаптера лог записывыыется, после уже нет... Может нельзя так обновлять адаптер? В чем тут дело может быть....

Добавлено через 3 часа 32 минуты
Продолжаю общаться сам с собой))) От помощи все еще не откажусь Получилось запустить код, но поиск работает на правильно, т.е. не выдает то что нужно, а весь список. Хотя в лог из Cursor записывается что нужно, т.е. запрос работает. Вот код:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package com.example.citycode;
 
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
 
public class MainActivity extends ActionBarActivity {
 
  ListView lvData,lvData1;
  DBHelper db;
  SimpleCursorAdapter scAdapter;
  Cursor cursor;
  Cursor cursor1;
  
  final String LOG_TAG = "myLogs";
  final String LOG_TAG1 = "myLogs1";
 
  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    // открываем подключение к БД
    db = new DBHelper(this);
    db.open();
    
    // Get the intent, verify the action and get the query
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }
    
    // получаем курсор
    cursor = db.getAllData();
    startManagingCursor(cursor);
    
    // Формируем столбцы сопоставления
    String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
    int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };
 
    // создааем адаптер и настраиваем список
    scAdapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from, to);
    lvData = (ListView) findViewById(R.id.listdata);
    lvData.setAdapter(scAdapter);
  }
  
  public void doMySearch(String query) {
        //Ищем совпадения
        Log.d(LOG_TAG, "Before get the C");
        cursor1 = db.fetchRecordsByQuery(query);
        Log.d(LOG_TAG, "After get the C");
        String t = Integer.toString(cursor1.getCount());
        Log.d(LOG_TAG, t);
        startManagingCursor(cursor1);
        String[] from = new String[] { DBHelper.COLUMN_r_name, DBHelper.COLUMN_region, DBHelper.COLUMN_code};
        int[] to = new int[] { R.id.city_name, R.id.region_name, R.id.city_code };
 
        scAdapter = new SimpleCursorAdapter(this,
                R.layout.item, cursor1, from, to);
        Log.d(LOG_TAG, "Setting the adapter");
        //Обновляем адаптер
        logCursor(cursor1);
        lvData = (ListView) findViewById(R.id.listdata);
        lvData.setAdapter(scAdapter);
        Log.d(LOG_TAG, "Adapter was set");
      }
  
//вывод в лог данных из курсора
 void logCursor(Cursor c) {
   if (c != null) {
     if (c.moveToFirst()) {
       String str;
       do {
         str = "";
         for (String cn : c.getColumnNames()) {
           str = str.concat(cn + " = " + c.getString(c.getColumnIndex(cn)) + "; ");
         }
         Log.d(LOG_TAG1, str);
       } while (c.moveToNext());
     }
   } else
     Log.d(LOG_TAG1, "Cursor is null");
 }
  
 
  
     @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.options_main, menu);
        
        // Get the SearchView and set the searchable configuration
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.action_settings).getActionView();
        // Assumes current activity is the searchable activity
        //searchView.setSubmitButtonEnabled(true);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
        
        return true;
    }
 
  
  protected void onDestroy() {
    super.onDestroy();
    // закрываем подключение при выходе
    db.close();
  }
 
}
Сам поиск стал работать, но выдавать полный список, после того как я в метоже doMySearch определил заново - lvData = (ListView) findViewById(R.id.listdata);
Но как я говорил, поиск все равно работает неправильно, хотя с помощью метода logCursor в лог идут как раз правильные данные.
Rube
910 / 558 / 87
Регистрация: 13.02.2014
Сообщений: 2,064
23.10.2014, 09:22     Что я неправильно делаю при реализации поиска? #4
Попробуйте использовать changeCursor(cursor) или notifyDataSetChanged().
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
23.10.2014, 12:34  [ТС]     Что я неправильно делаю при реализации поиска? #5
Эти методы не работают в это проекте...
CoolMind
411 / 394 / 65
Регистрация: 06.10.2012
Сообщений: 1,701
23.10.2014, 12:56     Что я неправильно делаю при реализации поиска? #6
yourfanat, тоже недавно мучался с поиском, в итоге забил и на SimpleCursorAdapter (вроде, он устарел, а люди продолжают его использовать), и на SearchActivity. Пока что, к сожалению, научился только при каждом поиске заново заполнять ListView.
Вместо этого использую другой код.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                Log.i("********", "Search submit " + s);
                ваши действия по поиску
                return false;
            }
 
            @Override
            public boolean onQueryTextChange(String s) {
                Log.i("********", "Search change " + s);
                return false;
            }
        });
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
23.10.2014, 13:17  [ТС]     Что я неправильно делаю при реализации поиска? #7
А как его применить к моему проекту?))) Я пока только по гайдам могу кодить, с небольшим вкладом от себя)))

Мне все таки интересно, почему в своем коде я могу вывести правльный результат поиска в лог, с помощью метода logCursor. А вот если данные теже начинаю назначать адаптеру, и применять его к ListView - выводится весь полный список.. Ну вот где то же зарыта собака
Rube
910 / 558 / 87
Регистрация: 13.02.2014
Сообщений: 2,064
23.10.2014, 13:45     Что я неправильно делаю при реализации поиска? #8
Цитата Сообщение от yourfanat Посмотреть сообщение
Эти методы не работают в это проекте...
Как т.е не работают? Это методы SimpleCursorAdapter, который у вас scAdapter.
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
23.10.2014, 14:02  [ТС]     Что я неправильно делаю при реализации поиска? #9
Добавляю после назначения курсора - cursor1 = db.fetchRecordsByQuery(query);
метод changeCursor(cursor1);
Пишет что: the method is undefined for the type MainActivity....
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
23.10.2014, 14:13  [ТС]     Что я неправильно делаю при реализации поиска? #10
Добавляю весь проект. Посмотрите пожалуйста, может я где то что то упустил... Ваш метод закоментил, что б проект запускался....
Вложения
Тип файла: zip citycode.zip (2.88 Мб, 3 просмотров)
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
23.10.2014, 19:17  [ТС]     Что я неправильно делаю при реализации поиска? #11
Попробовал добавить в проект над главным Listview - другой Listview - так вот туда выводяться результаты. За ним идет общий список. Может быть есть метод как выводить результаты в главный Listview?

Добавлено через 11 минут
Я так понял к моему Listview прикрпепился адаптер) От него нужно как то избавится, что бы можно было назначить другой Вопрос как это сделать ?

Добавлено через 1 час 14 минут
>Попробуйте использовать changeCursor(cursor) или notifyDataSetChanged().
Пробовал - не получилось
Rube
910 / 558 / 87
Регистрация: 13.02.2014
Сообщений: 2,064
24.10.2014, 07:56     Что я неправильно делаю при реализации поиска? #12
Цитата Сообщение от yourfanat Посмотреть сообщение
Добавляю после назначения курсора - cursor1 = db.fetchRecordsByQuery(query);
метод changeCursor(cursor1);
Пишет что: the method is undefined for the type MainActivity....
Вы рано добавляете, я писал, что
Цитата Сообщение от Rube Посмотреть сообщение
Это методы SimpleCursorAdapter, который у вас scAdapter.
scAdapter/records инициализируется у вас после назначения курсора, сл-но надо писать после 64 строки.
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
24.10.2014, 15:59  [ТС]     Что я неправильно делаю при реализации поиска? #13
Решил проблему добавлением return; в метод Oncreate сразу после вызова doMySearch метода. Более детально опишу на блоге, и дам ссылку, может будет интересно кому то)
chizz
 Аватар для chizz
979 / 493 / 54
Регистрация: 19.03.2013
Сообщений: 3,059
Записей в блоге: 18
Завершенные тесты: 1
24.10.2014, 16:16     Что я неправильно делаю при реализации поиска? #14
yourfanat, да, интересно. У меня не получилось Searchable прикрутить, велосипед делал
yourfanat
5 / 5 / 0
Регистрация: 30.10.2013
Сообщений: 177
30.10.2014, 16:10  [ТС]     Что я неправильно делаю при реализации поиска? #15
Как и обещал выкладываю подробный пост по реализации поиска в Android. Если будут какие то замечания, просьба написать тут или лучше в коментах. Ссылка: http://yourfanat.com/android/spravoc...zaciya-poiska/
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.10.2014, 16:22     Что я неправильно делаю при реализации поиска?
Еще ссылки по теме:

Android Что использовать для реализации клиент-серверного приложения?
С чего начать написание приложения? И что понадобится для его реализации Android
Делаю удаленную базу Android-Php-MySql Android
Android WebView и реализации tel:
Что за магия при смене языка? Android

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
CoolMind
411 / 394 / 65
Регистрация: 06.10.2012
Сообщений: 1,701
31.10.2014, 16:22     Что я неправильно делаю при реализации поиска? #16
yourfanat, молодец, что добил задачу.
Недавно у меня стояла такая же задача, но требовалось:
1) делать поиск во фрагментах,
2) на одних экранах показывать поиск, на других - нет,
3) по-другому оформить поисковую строку.
В куче тьюториалов об этом не сказано. Пришлось долго копаться. SearchActivity в итоге я не использовал за ненадобностью. Кроме того, выяснилось, что без ActionBarActivity задачу реализовать сложно, поэтому так и оставил public class MainActivity extends ActionBarActivity.
Yandex
Объявления
31.10.2014, 16:22     Что я неправильно делаю при реализации поиска?
Ответ Создать тему
Опции темы

Текущее время: 14:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru