Android SearchView既没有启动可搜索的活动也没有onNewIntent()调用

时间:2017-01-07 17:46:05

标签: java android android-intent android-search

所以我正在尝试在我的应用中实现搜索功能。我已将SearchView添加到应用程序栏并配置我的清单以将意图指向正确的活动。但我有一个特殊的情况:我想在SearchView生成的意图中添加额外的信息以传递给我的SearchableActivity(在我的例子中是SearchEventsActivity类)。为此,我想让我的MainActivity类可以搜索,它用onNewIntent()来捕获意图,将额外的信息放在一个新的intent中并使用它来启动我的实际搜索活动。但出于某种原因,虽然我很确定我的清单是正确的,但是在MainActivity中永远不会调用onNewIntent()

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.joshuaindustries.FindFun">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:theme="@style/AppTheme.NoActionBar">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

            <meta-data
                android:name="android.app.default_searchable"
                android:value=".MainActivity"
                android:resource="@xml/searchable" />

        </activity>

        <activity
            android:name=".DetailsActivity"
            android:label="@string/title_activity_details"
            android:theme="@style/AppTheme.NoActionBar" ></activity>

        <activity
            android:name=".LoginActivity"
            android:label="LoginActivity"
            android:theme="@style/AppTheme.NoActionBar" ></activity>

        <activity
            android:name=".SearchEventsActivity" >
        </activity>
    </application>

    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

MainActivity.class

package com.joshuaindustries.FindFun;

import com.joshuaindustries.CustomFragments.ManageListFragment;
import com.joshuaindustries.CustomFragments.OverviewListFragment;
import com.joshuaindustries.netwerk.ManageEventsFetcher;
import com.joshuaindustries.netwerk.OverviewEventsFetcher;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.content.SharedPreferencesCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private final static String TAG = "MainActivity";

    private OverviewEventsFetcher overviewEventsFetcher;
    private ManageEventsFetcher manageEventsFetcher;
    private String userEmailAddress;
    private String userPassword;

    private OverviewListFragment overviewTabFragment;
    private ManageListFragment manageTabFragment;

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {
        super.onCreate ( savedInstanceState );
        setContentView ( R.layout.activity_main );
        Intent activityIntent = getIntent ( );
        Bundle passedData = getIntent ( ).getExtras ( );

        /* Make sure we are ( still ) logged in
         */
        SharedPreferences loginData = getSharedPreferences ( "com.joshuaindustries.FindFun.loginData", Context.MODE_PRIVATE );
        userEmailAddress = loginData.getString ( "userEmailAddress", null );
        userPassword = loginData.getString ( "userPassword", null );

        if ( ( userEmailAddress == null ) || ( userPassword == null ) ) {
            Bundle passedLoginData = passedData;

            if ( passedLoginData == null) {
                Intent loginIntent = new Intent ( this, LoginActivity.class );
                startActivity ( loginIntent );
            } else {
                userEmailAddress = passedLoginData.getString ( "userEmailAddress" );
                userPassword = passedLoginData.getString ( "userPassword" );

                if ( ( userEmailAddress == null ) || (userPassword == null ) ) {
                    Intent loginIntent = new Intent ( this, LoginActivity.class );
                    startActivity ( loginIntent );
                }
            }
        }

        /* Create our custom list fragment
         */
        overviewTabFragment = new OverviewListFragment( );
        manageTabFragment = new ManageListFragment ( );

        Toolbar toolbar = ( Toolbar ) findViewById ( R.id.toolbar );
        setSupportActionBar ( toolbar );
        getSupportActionBar ( ).setTitle ( "FindFun" );

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter ( getSupportFragmentManager ( ) );

        // Set up the ViewPager with the sections adapter.
        mViewPager = ( ViewPager ) findViewById ( R.id.container );
        mViewPager.setAdapter ( mSectionsPagerAdapter );

        TabLayout tabLayout = ( TabLayout ) findViewById ( R.id.tabs );
        tabLayout.setupWithViewPager ( mViewPager );

        FloatingActionButton fab = ( FloatingActionButton ) findViewById ( R.id.fab );
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        } );
    }

    @Override
    public void onStart ( ) {
        super.onStart ( );

        /* Get events data from server
         */
        overviewEventsFetcher = new OverviewEventsFetcher ( this, userEmailAddress, userPassword );
        overviewEventsFetcher.fetch ( );
        overviewTabFragment.setUserCredentials ( userEmailAddress, userPassword );
        overviewTabFragment.setEventsFetcher ( overviewEventsFetcher );
        manageEventsFetcher = new ManageEventsFetcher ( this, userEmailAddress, userPassword );
        manageEventsFetcher.fetch ( );
        manageTabFragment.setUserCredentials ( userEmailAddress, userPassword );
        manageTabFragment.setEventsFetcher ( manageEventsFetcher );
    }

    @Override
    public boolean onCreateOptionsMenu ( Menu menu ) {
        super.onCreateOptionsMenu ( menu );
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater ( ).inflate ( R.menu.menu_main, menu );
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected ( item );
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed ( ) {
        return;
    }

    @Override
    public void onNewIntent ( Intent newIntent ) {
        Log.d ( TAG, "onNewIntent started" );
        if ( Intent.ACTION_SEARCH.equals ( newIntent.getAction ( ) ) ) {
            //Intent searchIntent = new Intent ( Intent.ACTION_SEARCH, null, getApplicationContext ( ), SearchEventsActivity.class );

            Intent searchIntent = new Intent ( this,    SearchEventsActivity.class );
            searchIntent.putExtra ( "userEmailAddress", userEmailAddress );
            searchIntent.putExtra ( "userPassword", userPassword );
            searchIntent.putExtra ( SearchManager.QUERY, newIntent.getStringExtra ( SearchManager.QUERY ) );

            startActivity ( searchIntent );
        }
    }

    @Override
    public void onStop ( ) {
        super.onStop ( );

        overviewEventsFetcher.onActivityStop ( );
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";

        public PlaceholderFragment() {
        }

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle ( );
            args.putInt ( ARG_SECTION_NUMBER, sectionNumber );
            fragment.setArguments ( args );
            return fragment;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate ( R.layout.fragment_overview, container, false );
            TextView textView = ( TextView ) rootView.findViewById ( R.id.section_label );
            textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
            return rootView;
        }
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter ( FragmentManager fragmentManager ) {
            super ( fragmentManager );
        }

        @Override
        public Fragment getItem ( int position ) {
            if ( position == 0 ) {
                return ( overviewTabFragment );
            } else if ( position == 2 ) {
                return ( manageTabFragment );
            } else {
                return PlaceholderFragment.newInstance(position + 1);
            }
        }

        @Override
        public int getCount ( ) {
            /* We will have three tabs
             */
            return ( 3 );
        }

        @Override
        public CharSequence getPageTitle ( int position ) {
            /* We will have three tabs
                - Overview: showing an overview of events the user can participate in
                - Participations: allowing the user to manage his or her participations
                - Manage: allowing the user to manage the events he / she creates himself
             */
            switch ( position ) {
                case ( 0 ):
                    return ( "Overview" );
                case ( 1 ):
                    return ( "Participations" );
                case ( 2 ):
                    return ( "Manage" );
                default:
                    return ( null );
            }
        }
    }
}

SearchEventsActivity.java

package com.joshuaindustries.FindFun;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.joshuaindustries.netwerk.OverviewEventsFetcher;
import com.joshuaindustries.netwerk.SearchResultsEventsFetcher;

/**
 * Created by Joshua on 7/01/2017.
 */

public class SearchEventsActivity extends AppCompatActivity implements ListView.OnItemClickListener {
    private static final String TAG = "SearchEventsActivityt";

    private static int nextSearchQueryID = 0;

    private String userEmailAddress;
    private String userPassword;
    private String searchQuery;
    private int searchQueryID;

    private View viewRoot;
    private ListView searchResultsList;
    SearchResultsEventsFetcher eventsFetcher;

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {
        super.onCreate ( savedInstanceState );
        Log.d ( TAG, "search activity started" );
        setContentView ( R.layout.activity_search_events );

        Intent searchIntent = getIntent ( );
        Bundle passedData = searchIntent.getExtras ( );

        userEmailAddress = passedData.getString ( "userEmailAddress" );
        userPassword = passedData.getString ( "userPassword" );
        searchQuery = passedData.getString ( SearchManager.QUERY );
        searchQueryID = SearchEventsActivity.nextSearchQueryID;
        ++SearchEventsActivity.nextSearchQueryID;

        eventsFetcher = new SearchResultsEventsFetcher ( this, userEmailAddress, userPassword, searchQuery, searchQueryID );
    }

    @Override
    public View onCreateView ( String name, Context context, AttributeSet attributeSet ) {
        viewRoot = super.onCreateView ( name, context, attributeSet );
        searchResultsList = ( ListView ) viewRoot.findViewById ( R.id.list_search_results );
        searchResultsList.setOnItemClickListener ( this );
        searchResultsList.setAdapter ( this.eventsFetcher.getEventListAdapter ( ) );

        Button loadMoreResultsButton = new Button ( this );
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams ( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT );
        layoutParams.addRule ( RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE );
        loadMoreResultsButton.setLayoutParams ( new AbsListView.LayoutParams ( layoutParams ) );
        loadMoreResultsButton.setText ( "Load more results ..." );
        loadMoreResultsButton.setOnClickListener (
                new View.OnClickListener ( ) {
                    SearchResultsEventsFetcher eventsFetcher;

                    public View.OnClickListener passEventsFetcher ( SearchResultsEventsFetcher eventsFetcher ) {
                        this.eventsFetcher = eventsFetcher;

                        return ( this );
                    }

                    @Override
                    public void onClick ( View view ) {
                        eventsFetcher.fetch( );
                    }
                }.passEventsFetcher ( eventsFetcher )
        );
        searchResultsList.addFooterView ( loadMoreResultsButton );

        return ( viewRoot );
    }

    @Override
    public void onItemClick ( AdapterView listView, View view, int viewPosition, long rowID ) {
        Intent detailsIntent = new Intent ( this, DetailsActivity.class );
        detailsIntent.putExtra ( "userEmailAddress", userEmailAddress );
        detailsIntent.putExtra ( "userPassword", userPassword );
        eventsFetcher.putEventInIntent ( detailsIntent, rowID );

        startActivity ( detailsIntent );
    }
}

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" >
</searchable>

我尝试过提出的解决方案herehere无济于事......

非常感谢任何帮助和/或建议!

谢谢, 约书亚

1 个答案:

答案 0 :(得分:1)

我认为我的问题是SDK没有将我的可搜索配置链接到我的活动中实例化的SearchView。我不知道为什么会这样,但我有一个解决方法,即在MainActivity.java的onCreateOptionsMenu(菜单菜单)方法中以编程方式进行此耦合,如下所示:

SearchView searchView = ( SearchView ) menu.findItem ( R.id.action_search ).item.getActionView ( );
SearchManager searchManager = ( SearchManager ) getSystemService ( Context.SEARCH_SERVICE );
searchView.setSearchableInfo ( searchManager.getSearchableInfo ( getComponentName ( ) ) );

我希望将来可以帮助某人:)