SearchView после реализации голоса генерирует исключение NullPointerException - PullRequest
0 голосов
/ 13 марта 2019

Я попытался реализовать голосовой поиск, выполнив следующие действия; Кнопка ActionBar Mic (голосовой поиск) в SearchView

Все в порядке, я добавил всю необходимую информацию в мой AndroidManifest и searcabhle.xml, чтобы я мог видеть значок микрофона и панель поиска, проблема в том, что когда я пытаюсь выполнить голосовой поиск после того, как что-то сказать, ничего не находит и приложение вылетает, похоже, что-то не так с SetQuery и вот полная ошибка;

2019-03-13 04:55:55.723 1533-1533/com.demotxt.myapp.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.demotxt.myapp.myapplication, PID: 1533
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.SearchView.setQuery(java.lang.CharSequence, boolean)' on a null object reference
    at com.demotxt.myapp.myapplication.activities.MainActivity.onNewIntent(MainActivity.java:153)
    at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1231)
    at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1243)
    at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:3064)
    at android.app.ActivityThread.performNewIntents(ActivityThread.java:3076)
    at android.app.ActivityThread.handleNewIntent(ActivityThread.java:3085)
    at android.app.ActivityThread.-wrap17(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1710)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6682)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

И это мой Main3Activity;

 private static final String TAG = "Main3Activity";
private final String JSON_URL = "https://MYURLXXX" ;
private JsonArrayRequest request ;
private RequestQueue requestQueue ;
private List<Anime> lstAnime ;
private RecyclerView recyclerView ;
private RecyclerViewLiveAdapter adapter;
RecyclerView.LayoutManager layoutManager;


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

        lstAnime = new ArrayList<>() ;
        recyclerView = findViewById(R.id.recyclerviewid);
        jsonrequest();



    }

    private void jsonrequest() {

        request = new JsonArrayRequest(JSON_URL, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {

                JSONObject jsonObject  = null ;

                for (int i = 0 ; i < response.length(); i++ ) {


                    try {
                        jsonObject = response.getJSONObject(i) ;
                        Anime anime = new Anime() ;
                        anime.setName(jsonObject.getString("name"));
                        anime.setDescription(jsonObject.getString("description"));
                        anime.setRating(jsonObject.getString("Rating"));
                        anime.setCategorie(jsonObject.getString("categorie"));
                        anime.setStudio(jsonObject.getString("studio"));
                        anime.setImage_url(jsonObject.getString("img"));
                        anime.setLink(jsonObject.getString("link"));
                        anime.setDrm_scheme(jsonObject.getString("drm_scheme"));
                        anime.setDrm_license_url(jsonObject.getString("drm_license_url"));
                        anime.setDrm(jsonObject.getString("drm"));
                        anime.setSubtitle(jsonObject.getString("subtitle"));
                        anime.setSubtitle1(jsonObject.getString("subtitle1"));
                        anime.setSubtitle2(jsonObject.getString("subtitle2"));
                        lstAnime.add(anime);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    setuprecyclerview(lstAnime);


                }


            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });


        requestQueue = Volley.newRequestQueue(Main3Activity.this);
        requestQueue.add(request) ;


    }

    private void setuprecyclerview(List<Anime> lstAnime) {


        adapter = new RecyclerViewLiveAdapter(this,lstAnime) ;
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_item,menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) searchItem.getActionView();
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
        {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                if (adapter != null){
                adapter.getFilter().filter(newText);}
                return false;
            }
        });
        return true;

    }

   protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);

            searchView.setQuery(query, false);
        }
    }
}

Я выполняю фильтрацию в моем адаптере, но, поскольку здесь происходит ошибка, я думаю, что нет необходимости помещать здесь код моего адаптера, а также потому, что фильтрация с текстом работает отлично, единственная проблема - голосовой поиск.

Ответы [ 5 ]

0 голосов
/ 13 марта 2019

Это потому, что вы обращаетесь к нулевому объекту searchView в onNewIntent (). Создайте глобальную ссылочную переменную для searchView в своем классе и создайте экземпляр в onCreateOptionsMenu (). Как ниже:

SearchView searchView;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_item,menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        searchView = (SearchView) searchItem.getActionView();
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
        {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                if (adapter != null){
                adapter.getFilter().filter(newText);}
                return false;
            }
        });
        return true;
}
0 голосов
/ 13 марта 2019

Ребята, извините, что добавляю ответ за помощь, но это съедает меня живьем, на самом деле нужна помощь: /

Это последний код, который я добавил для целей задержки, но, к счастью, снова все равно null searchView;

if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        final String query = intent.getStringExtra(SearchManager.QUERY);
        searchView.post(new Runnable() {

            @Override
            public void run() {
                // Important! Make sure searchView has been initialized
                // and referenced to the correct (current) SearchView.
                // Config changes (e.g. screen rotation) may make the
                // variable value null.
                searchView.setQuery(query, false);
            }
        });
0 голосов
/ 13 марта 2019

Самое последнее, что я попробовал, это:

удалил метод onNewIntent и добавил этот код в onCreateOptionsMenu без ошибок, но также снова не выполняет поиск с голосом, даже не помещая ничего на панель поиска

Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        searchView.setQuery(query,false);
    }

Мне действительно нужна рука.

0 голосов
/ 13 марта 2019

Наконец, вернулись к первому коду и заменили метод onNewIntent с очень небольшими изменениями, все те же

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
            searchView.onActionViewExpanded();
            searchView.setQuery(query,false);
    }
}
0 голосов
/ 13 марта 2019

То, что я попробовал сейчас, из этой части;

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        searchView.setQuery(query, false);
    }
}

Я взял searchView.setQuery(query, false); и заменил его на adapter.getFilter().filter(query);}

, теперь он выполняет поиск, но не показываеттекст в строке поиска и нет кнопки «назад». Также я думаю, что есть огромная ошибка, потому что я пытался установить setQuery вручную, но он не работал, как это возможно?

Короче говоря, все, что я хочукогда я нажимаю на кнопку микрофона, он фиксирует мои слова и помещает их в строку поиска.

...