Java tutorial
/* * Copyright (C) 2010 Jamie McDonald * * This file is part of MusicBrainz for Android. * * MusicBrainz for Android is free software: you can redistribute * it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * MusicBrainz for Android is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MusicBrainz for Android. If not, see * <http://www.gnu.org/licenses/>. */ package org.musicbrainz.mobile.activity; import java.util.LinkedList; import org.musicbrainz.android.api.data.ReleaseStub; import org.musicbrainz.mobile.R; import org.musicbrainz.mobile.adapter.list.ReleaseStubAdapter; import org.musicbrainz.mobile.dialog.BarcodeConfirmDialog; import org.musicbrainz.mobile.intent.IntentFactory.Extra; import org.musicbrainz.mobile.loader.SearchReleaseLoader; import org.musicbrainz.mobile.loader.SubmitBarcodeLoader; import org.musicbrainz.mobile.loader.result.AsyncResult; import com.actionbarsherlock.view.Window; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.Loader; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; /** * Activity to submit a barcode to a selected release in MusicBrainz. */ public class BarcodeSearchActivity extends MusicBrainzActivity implements View.OnClickListener, ListView.OnItemClickListener, ListView.OnItemLongClickListener, OnEditorActionListener { private static final String INSTANCE_SELECTED = "selected_position"; private static final int SEARCH_RELEASE_LOADER = 0; private static final int SUBMIT_BARCODE_LOADER = 1; private static final int DIALOG_CONNECTION_FAILURE = 0; private static final int DIALOG_SUBMIT_BARCODE = 1; private TextView barcodeText; private EditText searchBox; private ImageButton searchButton; private TextView instructions; private TextView noResults; private ListView matches; private LinearLayout loading; private String barcode; private String searchTerm; private LinkedList<ReleaseStub> results; private int selection = 0; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.activity_barcode); setSupportProgressBarIndeterminateVisibility(false); findViews(); barcode = getIntent().getStringExtra(Extra.BARCODE); barcodeText.setText(barcodeText.getText() + " " + barcode); if (getSupportLoaderManager().getLoader(SEARCH_RELEASE_LOADER) != null) { getSupportLoaderManager().initLoader(SEARCH_RELEASE_LOADER, null, searchCallbacks); } } private void findViews() { searchBox = (EditText) findViewById(R.id.barcode_search); barcodeText = (TextView) findViewById(R.id.barcode_text); searchButton = (ImageButton) findViewById(R.id.barcode_search_btn); matches = (ListView) findViewById(R.id.barcode_list); instructions = (TextView) findViewById(R.id.barcode_instructions); noResults = (TextView) findViewById(R.id.noresults); loading = (LinearLayout) findViewById(R.id.loading); searchBox.setOnEditorActionListener(this); searchButton.setOnClickListener(this); } public void onClick(View v) { doSearch(); } public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (v.getId() == R.id.barcode_search && actionId == EditorInfo.IME_NULL) { doSearch(); } return false; } private void doSearch() { String term = searchBox.getText().toString(); if (term.length() != 0) { hideKeyboard(); prepareSearch(); searchTerm = term; getSupportLoaderManager().destroyLoader(SEARCH_RELEASE_LOADER); getSupportLoaderManager().initLoader(SEARCH_RELEASE_LOADER, null, searchCallbacks); } else { Toast.makeText(this, R.string.toast_search_err, Toast.LENGTH_SHORT).show(); } } private void prepareSearch() { searchButton.setEnabled(false); instructions.setVisibility(View.INVISIBLE); loading.setVisibility(View.VISIBLE); } private void hideKeyboard() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(searchBox.getWindowToken(), 0); } public void submitBarcode(String releaseMbid) { setSupportProgressBarIndeterminateVisibility(true); getSupportLoaderManager().initLoader(SUBMIT_BARCODE_LOADER, null, submissionCallbacks); } public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selection = position; showDialog(DIALOG_SUBMIT_BARCODE); } public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { Intent releaseIntent = new Intent(this, ReleaseActivity.class); releaseIntent.putExtra(Extra.RELEASE_MBID, results.get(position).getReleaseMbid()); startActivity(releaseIntent); return true; } protected Dialog createConnectionErrorDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(BarcodeSearchActivity.this); builder.setMessage(getString(R.string.err_text)); builder.setCancelable(false); builder.setPositiveButton(getString(R.string.err_pos), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { getSupportLoaderManager().restartLoader(SEARCH_RELEASE_LOADER, null, searchCallbacks); dialog.cancel(); loading.setVisibility(View.VISIBLE); } }); builder.setNegativeButton(getString(R.string.err_neg), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { BarcodeSearchActivity.this.finish(); } }); return builder.create(); } @Override protected Dialog onCreateDialog(int id) { switch (id) { case DIALOG_SUBMIT_BARCODE: return new BarcodeConfirmDialog(this, results.get(selection)); case DIALOG_CONNECTION_FAILURE: return createConnectionErrorDialog(); } return null; } @Override public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putInt(INSTANCE_SELECTED, selection); super.onSaveInstanceState(savedInstanceState); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); selection = savedInstanceState.getInt(INSTANCE_SELECTED); } private LoaderCallbacks<AsyncResult<LinkedList<ReleaseStub>>> searchCallbacks = new LoaderCallbacks<AsyncResult<LinkedList<ReleaseStub>>>() { @Override public Loader<AsyncResult<LinkedList<ReleaseStub>>> onCreateLoader(int id, Bundle args) { return new SearchReleaseLoader(getApplicationContext(), searchTerm); } @Override public void onLoadFinished(Loader<AsyncResult<LinkedList<ReleaseStub>>> loader, AsyncResult<LinkedList<ReleaseStub>> data) { instructions.setVisibility(View.INVISIBLE); loading.setVisibility(View.INVISIBLE); switch (data.getStatus()) { case SUCCESS: handleSearchResults(data); break; case EXCEPTION: showDialog(DIALOG_CONNECTION_FAILURE); } } @Override public void onLoaderReset(Loader<AsyncResult<LinkedList<ReleaseStub>>> loader) { loader.reset(); } }; private void handleSearchResults(AsyncResult<LinkedList<ReleaseStub>> result) { results = result.getData(); matches.setAdapter(new ReleaseStubAdapter(this, R.layout.list_release, results)); matches.setOnItemClickListener(this); matches.setOnItemLongClickListener(this); if (results.isEmpty()) { noResults.setVisibility(View.VISIBLE); matches.setVisibility(View.INVISIBLE); } else { matches.setVisibility(View.VISIBLE); noResults.setVisibility(View.INVISIBLE); } searchButton.setEnabled(true); } private LoaderCallbacks<AsyncResult<Void>> submissionCallbacks = new LoaderCallbacks<AsyncResult<Void>>() { @Override public Loader<AsyncResult<Void>> onCreateLoader(int id, Bundle args) { return new SubmitBarcodeLoader(getApplicationContext(), getSelectedReleaseMbid(), barcode); } @Override public void onLoadFinished(Loader<AsyncResult<Void>> loader, AsyncResult<Void> data) { getSupportLoaderManager().destroyLoader(SUBMIT_BARCODE_LOADER); setSupportProgressBarIndeterminateVisibility(false); switch (data.getStatus()) { case EXCEPTION: Toast.makeText(BarcodeSearchActivity.this, R.string.toast_barcode_fail, Toast.LENGTH_LONG).show(); break; case SUCCESS: Toast.makeText(BarcodeSearchActivity.this, R.string.toast_barcode, Toast.LENGTH_LONG).show(); BarcodeSearchActivity.this.finish(); } } @Override public void onLoaderReset(Loader<AsyncResult<Void>> loader) { loader.reset(); } }; private String getSelectedReleaseMbid() { return results.get(selection).getReleaseMbid(); } }