Android Open Source - FAST Search Activity






From Project

Back to project page FAST.

License

The source code is released under:

GNU General Public License

If you think the Android project FAST listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.ligi.fast.ui;
/*from   w  w w . j  ava 2  s .  c  o m*/
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

import org.ligi.axt.helpers.ViewHelper;
import org.ligi.axt.simplifications.SimpleTextWatcher;
import org.ligi.fast.App;
import org.ligi.fast.R;
import org.ligi.fast.background.BackgroundGatherAsyncTask;
import org.ligi.fast.model.AppInfo;
import org.ligi.fast.model.AppInfoList;
import org.ligi.fast.model.DynamicAppInfoList;
import org.ligi.fast.util.AppInfoListStore;
import org.ligi.tracedroid.sending.TraceDroidEmailSender;

import java.util.Locale;

/**
 * The main Activity for this App - most things come together here
 */
public class SearchActivity extends Activity implements App.PackageChangedListener {

    private DynamicAppInfoList appInfoList;
    private AppInfoAdapter adapter;
    private String oldSearch = "";
    private EditText searchQueryEditText;
    private GridView gridView;

    private AppInfoListStore appInfoListStore;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        App.applyTheme(this);

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

        setContentView(R.layout.activity_search);

        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.main_title);

        appInfoListStore = new AppInfoListStore(this);

        final AppInfoList loadedAppInfoList = appInfoListStore.load();
        appInfoList = new DynamicAppInfoList(loadedAppInfoList, App.getSettings());

        adapter = new AppInfoAdapter(this, appInfoList);

        configureAdapter();

        gridView = (GridView) findViewById(R.id.listView);

        searchQueryEditText = (EditText) findViewById(R.id.searchEditText);
        searchQueryEditText.setSingleLine();
        searchQueryEditText.setImeOptions(EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
        searchQueryEditText.setImeActionLabel("Launch", EditorInfo.IME_ACTION_DONE);

        searchQueryEditText.setOnEditorActionListener(new OnEditorActionListener() {

            @Override
            public boolean onEditorAction(TextView v, int actionId,
                                          KeyEvent event) {
                if (adapter.getCount() > 0) {
                    startItemAtPos(0);
                }
                return true;
            }

        });
        searchQueryEditText.setHint(R.string.query_hint);

        searchQueryEditText.addTextChangedListener(new SimpleTextWatcher() {

            @Override
            public void afterTextChanged(Editable s) {
                final String editString = s.toString();
                final boolean was_adding = oldSearch.length() < editString.length();
                oldSearch = editString.toLowerCase(Locale.ENGLISH);
                adapter.setActQuery(editString.toLowerCase(Locale.ENGLISH));
                startAppWhenItItIsTheOnlyOneInList(was_adding);
            }

        });

        gridView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
                                    long arg3) {
                try {
                    startItemAtPos(pos);
                } catch (ActivityNotFoundException e) {
                    // e.g. uninstalled while app running - TODO should refresh list
                }
            }

        });

        gridView.setLongClickable(true);

        gridView.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                                           int pos, long arg3) {
                new AppActionDialogBuilder(SearchActivity.this, adapter.getItem(pos)).show();
                return true;
            }

        });

        TraceDroidEmailSender.sendStackTraces("ligi@ligi.de", this);


        if (appInfoList.size() == 0) {
            startActivityForResult(new Intent(this, LoadingDialog.class), R.id.activityResultLoadingDialog);
        } else { // the second time - we use the old index to be fast but
            // regenerate in background to be recent

            // Use the pkgAppsListTemp in order to update data from the saved file with recent
            // call count information (seeing as we may not have saved it recently).
            new BackgroundGatherAsyncTask(this, appInfoList).execute();
        }

        gridView.setAdapter(adapter);
    }

    private void startAppWhenItItIsTheOnlyOneInList(boolean was_adding) {
        if ((adapter.getCount() == 1) && was_adding && App.getSettings().isLaunchSingleActivated()) {
            startItemAtPos(0);
        }
    }

    private void configureAdapter() {
        if (App.getSettings().getSortOrder().startsWith("alpha")) {
            adapter.setSortMode(DynamicAppInfoList.SortMode.ALPHABETICAL);
        } else if (App.getSettings().getSortOrder().equals("most_used")) {
            adapter.setSortMode(DynamicAppInfoList.SortMode.MOST_USED);
        }
    }

    public void startItemAtPos(int pos) {
        final AppInfo app = adapter.getItem(pos);
        app.incrementCallCount();
        final Intent intent = app.getIntent();
        intent.setAction(Intent.ACTION_MAIN);
        // set flag so that next start the search app comes up and not the last started App
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Log.d(App.LOG_TAG, "Starting " + app.getActivityName() + " (and incremented call count to " + app.getCallCount() + ")");

        try {
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(this,"cannot start: " + e,Toast.LENGTH_LONG).show();
        }

        if (Build.VERSION.SDK_INT > 18) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(searchQueryEditText.getWindowToken(), 0);
        }

        if (App.getSettings().isFinishOnLaunchEnabled()) {
            finish();
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case R.id.activityResultLoadingDialog:
                onPackageChange(appInfoListStore.load());
                break;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        App.packageChangedListener = this;

        searchQueryEditText.setText(""); // using the app showed that we want a new search here and the old stuff is not interesting anymore

        dealWithUserPreferencesRegardingSoftKeyboard();

        configureAdapter();

        final String iconSize = App.getSettings().getIconSize();
        gridView.setColumnWidth((int) getResources().getDimension(getWidthByIconSize(iconSize)));
    }

    private static int getWidthByIconSize(String iconSize) {
        switch (iconSize) {
            case "tiny":
                return R.dimen.cell_size_tiny;
            case "small":
                return R.dimen.cell_size_small;
            case "large":
                return R.dimen.cell_size_large;
            default:
                return R.dimen.cell_size;
        }
    }

    private void dealWithUserPreferencesRegardingSoftKeyboard() {
        if (App.getSettings().isShowKeyBoardOnStartActivated()) {
            showKeyboard();
        } else {
            hideKeyboard();
        }

    }

    private void hideKeyboard() {
        searchQueryEditText.clearFocus();
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }

    private void showKeyboard() {
        searchQueryEditText.requestFocus();

        searchQueryEditText.postDelayed(new Runnable() {

            @Override
            public void run() {
                new ViewHelper(searchQueryEditText).showKeyboard();
            }
        }, 200);
    }

    @SuppressWarnings("UnusedDeclaration") // the API is that way
    public void settingsClicked(View v) {
        startActivity(new Intent(this, FASTSettingsActivity.class));
        finish();
    }

    @SuppressWarnings("UnusedDeclaration") // the API is that way
    public void helpClicked(View v) {
        HelpDialog.show(this);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
                && keyCode == KeyEvent.KEYCODE_BACK
                && event.getRepeatCount() == 0) {
            // Take care of calling this method on earlier versions of
            // the platform where it doesn't exist.
            onBackPressed();
        }

        return super.onKeyDown(keyCode, event);
    }


    @Override
    public void onBackPressed() {
        finishIfWeAreNotTheDefaultLauncher();

    }

    private void finishIfWeAreNotTheDefaultLauncher() {
        // TODO check if we perhaps only want this when we have only one launcher
        if (!getPackageName().equals(getHomePackageName())) {
            finish();
        }
    }

    private String getHomePackageName() {
        final Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        final ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
        return resolveInfo.activityInfo.packageName;
    }

    @Override
    public void onPackageChange(final AppInfoList newAppInfoList) {
        // TODO we should also do a cleanup of cached icons here
        // we might not come from UI Thread

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                adapter.updateList(newAppInfoList);
            }
        });
    }

    @Override
    protected void onPause() {
        App.packageChangedListener = null;
        super.onPause();
    }

    @Override
    protected void onStop() {
        // Need to persist the call count values, or else the sort by "most used"
        // will not work next time we open this activity.
        appInfoListStore.save(appInfoList.getBackingAppInfoList());
        App.packageChangedListener = null;
        super.onStop();
    }

}




Java Source Code List

org.ligi.axt.helpers.ActivityHelper.java
org.ligi.axt.helpers.ContextHelper.java
org.ligi.axt.helpers.FileHelper.java
org.ligi.axt.helpers.ResolveInfoHelper.java
org.ligi.axt.helpers.ViewHelper.java
org.ligi.axt.simplifications.SimpleTextWatcher.java
org.ligi.fast.App.java
org.ligi.fast.TargetStore.java
org.ligi.fast.TargetStore.java
org.ligi.fast.TargetStore.java
org.ligi.fast.background.AppInstallOrRemoveReceiver.java
org.ligi.fast.background.BackgroundGatherAsyncTask.java
org.ligi.fast.background.BaseAppGatherAsyncTask.java
org.ligi.fast.model.AppIconCache.java
org.ligi.fast.model.AppInfoList.java
org.ligi.fast.model.AppInfoSortByLabelComparator.java
org.ligi.fast.model.AppInfoSortByMostUsedComparator.java
org.ligi.fast.model.AppInfo.java
org.ligi.fast.model.DynamicAppInfoList.java
org.ligi.fast.settings.AndroidFASTSettings.java
org.ligi.fast.settings.FASTSettings.java
org.ligi.fast.testing.AppInfoTestBase.java
org.ligi.fast.testing.MutableFastSettings.java
org.ligi.fast.testing.TheAppIconCache.java
org.ligi.fast.testing.TheAppInfoStore.java
org.ligi.fast.testing.TheAppInfo.java
org.ligi.fast.testing.TheSearchActivity.java
org.ligi.fast.ui.AppActionDialogBuilder.java
org.ligi.fast.ui.AppInfoAdapter.java
org.ligi.fast.ui.FASTSettingsActivity.java
org.ligi.fast.ui.HelpDialog.java
org.ligi.fast.ui.HelpDialog.java
org.ligi.fast.ui.IconDimensions.java
org.ligi.fast.ui.LoadingDialog.java
org.ligi.fast.ui.SearchActivity.java
org.ligi.fast.util.AppInfoListStore.java
org.ligi.fast.util.PackageListSerializer.java
org.ligi.fast.util.StringUtils.java
org.ligi.fast.util.UmlautConverter.java