When screen rotates users can cheat Android - java

I am following Big Nerd Ranch guide Android in which I am building a basic application which displays a set of questions and you say true or false. There is a button 'Cheat' where in you can cheat. If you hit the button Cheat see the answer, come back and type the correct answer then there is a toast displayed 'Cheating is wrong'. This works fine in vertical screen but lets say I rotate the screen to horizontal, I view the answer and come back to horizontal, I can cheat. I dont want that to happen.
My Effort:
using onSavedInstanceState to override the existing function to share values between screens & keeping track of the value in onCreate
#Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
Log.i(TAG, "onSaveInstanceState");
savedInstanceState.putBoolean(EXTRA_ANSWER_SHOWN, mAnswerIsTrue) ;
}
In onCreate method,
if(savedInstanceState !=null)
{
mAnswerIsTrue = savedInstanceState.getBoolean(EXTRA_ANSWER_SHOWN);
setAnswerShownResult(mAnswerIsTrue);
}
Here is my code:
package com.android.geoquiz;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class CheatActivity extends Activity
{
//Extras
public static final String EXTRA_ANSWER_IS_TRUE = "com.android.geoquiz.answer_is_true";
public static final String EXTRA_ANSWER_SHOWN = "com.android.geoquiz.answer_shown";
private static final String TAG="CheatActivity";
private static final String KEY_INDEX = "cheat";
private boolean mAnswerIsTrue;
private TextView mAnswerTextView;
private Button mShowAnswer;
private void setAnswerShownResult(boolean isAnswerShown)
{
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);
setResult(RESULT_OK, data);
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);
mAnswerTextView = (TextView)findViewById(R.id.showAnswerButton);
setAnswerShownResult(false);
mShowAnswer = (Button)findViewById(R.id.showAnswerButton);
mShowAnswer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mAnswerIsTrue)
{
mAnswerTextView.setText(R.string.true_button);
}
else
{
mAnswerTextView.setText(R.string.false_button);
}
setAnswerShownResult(true);
}
});
if(savedInstanceState !=null)
{
mAnswerIsTrue = savedInstanceState.getBoolean(KEY_INDEX, false);
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
Log.i(TAG, "onSaveInstanceState");
savedInstanceState.putBoolean(KEY_INDEX, mAnswerIsTrue) ;
}
#Override
public void onStart()
{
super.onStart();
Log.d(TAG, "onStart() called");
}
#Override
public void onPause()
{
super.onPause();
Log.d(TAG, "onPause() called");
}
#Override
public void onResume()
{
super.onResume();
Log.d(TAG, "onResume() called");
}
#Override
public void onStop()
{
super.onStop();
Log.d(TAG, "onStop() called");
}
#Override
public void onDestroy()
{
super.onDestroy();
Log.d(TAG, "onDestroy() called");
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
}
}

This is happening because your onCreate is being called once the user rotates the screen there is simple solution to stop onCreate from being called onOrientationChanged
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden" />
now when you do this you have to overide a method in your activity class like you have onCreate , onPause you will need to add another method named onConfigChanged();
now whenever your screen is rotated this method is gonna be fired instead of activity being created again and again.
add this to your activity class
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
Hope this helps. if you need any help feel free to ask.
for more info read these posts.
Activity restart on rotation Android
How do I disable orientation change on Android?
http://developer.android.com/guide/topics/manifest/activity-element.html#config

In your manifest add this to your activity
android:configChanges="orientation|screenSize"
And in your Activity listen for config changes
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
System.out.println(newConfig.toString());
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Toast.makeTest(this,"portrait",Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeTest(this,"landscape",Toast.LENGTH_SHORT).show();
}
}

Related

Android onCreate of Activity class is not triggered

I am trying to write a plugin for Capacitor. It should pass the accelerometer data to the JavaScript. The bridge works fine.
However, the heading class does not seem to be initialized. The onCreate function does not seem to be executed, so do all the other functions. Nothing is logged to the console.
In AndroidManifest.xml I have requested the following feature:
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
The file looks like this:
package de.example.capmap;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import com.getcapacitor.BridgeActivity;
import de.example.Compass;
public class MainActivity extends BridgeActivity {
private Heading heading;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerPlugin(Compass.class);
heading = new Heading();
}
}
class Heading extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor mAccelerometer;
private static final String TAG = "Heading";
#Override
public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "onCreate: Initializing");
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(Heading.this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onSensorChanged(SensorEvent event){
Log.i(TAG, "onSensorChanged: " + event.values[0]);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.i(TAG, "onAccuracyChanged:" + accuracy);
}
#Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
}
and the Compass Plugin, which gets executed:
import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginHandle;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.Bridge;
#CapacitorPlugin(name = "Compass")
public class Compass extends Plugin {
public static Bridge staticBridge = null;
#Override
public void load() {
staticBridge = this.bridge;
java.lang.System.out.println("Compass successfully started");
}
public static void onMagneticHeading(float magneticHeading){
Compass pushPlugin = Compass.getCompassInstance();
if (pushPlugin != null) {
pushPlugin.sendMagneticHeading(magneticHeading);
}
}
#PluginMethod()
public void getMagneticHeading(PluginCall call) {
String value = call.getString("value");
JSObject ret = new JSObject();
ret.put("magneticHeading", value);
call.resolve(ret);
}
public void sendMagneticHeading(float magneticHeading) {
JSObject data = new JSObject();
data.put("magneticHeading", magneticHeading);
notifyListeners("heading", data, true);
}
public static Compass getCompassInstance() {
if (staticBridge != null && staticBridge.getWebView() != null) {
PluginHandle handle = staticBridge.getPlugin("Compass");
if (handle == null) {
return null;
}
return (Compass) handle.getInstance();
}
return null;
}
}
How come you're extending an Activity instead of just using a plain class? If it's because you want access to a Context, just pass one in through the constructor (you have one when you create the Heading).
If it's because you want the onPause and onResume lifecycle callbacks, so you know when to register/unregister with the SensorManager, there's a couple of things you could do.
First you can just create some methods the activity can call during onPause/onResume:
class Heading(Context context) {
...
public void sleep() {
sensorManager.unregisterListener(this);
}
public void wake() {
sensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
}
class MainActivity extends BridgeActivity {
...
#Override
protected void onResume() {
super.onResume();
heading.wake();
}
#Override
protected void onPause() {
super.onPause();
heading.sleep();
}
}
The other approach is to make Heading implement DefaultLifecycleObserver, which basically lets you implement onResume and onPause etc like you're doing, and you make it observe the Activity's lifecycle, instead of the Activity having to manually call stuff to be like "hey onPause just happened". I'll just link the example page, but it basically covers what you're doing here (and the earlier, manual example too) as well as some more advanced stuff

Music doesn't play again after I press home or recents button

I have an app with a button to play or pause music. Pressing the back button while playing music pauses it and opening the app again resumes the music after pressing the play button. But that doesn't work with home or recents button. The music pauses but upon reopening the app and pressing the play button doesn't play the music until a force close. Here is the code:
package com.example.firozkaoo2222.myapplication;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import static com.example.firozkaoo2222.myapplication.R.raw.police;
public class MainActivity extends AppCompatActivity {
private MediaPlayer policeSound = MediaPlayer.create(this, police);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button policeSounds = this.findViewById(R.id.police);
policeSounds.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (policeSound == null) {
policeSound = MediaPlayer.create(getApplicationContext(), R.raw.police);
}
if (policeSound.isPlaying()) {
policeSound.pause();
} else {
policeSound.start();
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if (policeSound != null) {
policeSound = MediaPlayer.create(this, R.raw.police);
policeSound.start();
}
}
#Override
public void onPause() {
super.onPause();
if (policeSound.isPlaying())
policeSound.pause();
}
//Back button pressed.
#Override
public void onBackPressed() {
super.onBackPressed();
if (policeSound.isPlaying())
policeSound.pause();
}
#Override
protected void onDestroy() {
super.onDestroy();
policeSound.stop();
policeSound = null;
}
}
If you press home button the app go to the background and when you came from the background you should override the method onResume();
Code:
public class MainActivity extends AppCompatActivity {
//THIS IS YOUR LAST MISTAKE. IF YOU TRY TO CREATE THE OBJECT WITH THE CONTEXT AND THE RESOUERCES
//WHEN THE ACTIVITY IS NOT CREATED YET, YOUR APP CRASH
//private MediaPlayer policeSound = MediaPlayer.create(this, R.raw.police);
private MediaPlayer policeSound;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button policeSounds = this.findViewById(R.id.police);
policeSounds.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (policeSound == null) {
policeSound = MediaPlayer.create(getApplicationContext(), R.raw.police);
}
if (policeSound.isPlaying()) {
policeSound.pause();
} else {
policeSound.start();
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if (policeSound != null) {
policeSound = MediaPlayer.create(this, R.raw.police);
policeSound.start();
}
}
#Override
public void onPause() {
super.onPause();
if (policeSound.isPlaying())
policeSound.pause();
}
//Back button pressed.
#Override
public void onBackPressed() {
super.onBackPressed();
if (policeSound.isPlaying())
policeSound.pause();
}
#Override
protected void onDestroy() {
super.onDestroy();
policeSound.stop();
policeSound = null;
}
}
I hope this help you.

How can I make my Android WebView play music or audio in the background with an audio player in the status bar? Here is my MainActivity.java

package net.socialkit.socialkitandroidwebview;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import im.delight.android.webview.AdvancedWebView;
public class MainActivity extends AppCompatActivity implements AdvancedWebView.Listener
{
private AdvancedWebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (AdvancedWebView) findViewById(R.id.socialkitWebView);
mWebView.setListener(this, this);
mWebView.loadUrl(getString(R.string.url));
}
#SuppressLint("NewApi")
#Override
protected void onResume()
{
super.onResume();
mWebView.onResume();
}
#SuppressLint("NewApi")
#Override
protected void onPause()
{
mWebView.onPause();
super.onPause();
}
#Override
protected void onDestroy()
{
mWebView.onDestroy();
super.onDestroy();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
super.onActivityResult(requestCode, resultCode, intent);
mWebView.onActivityResult(requestCode, resultCode, intent);
}
#Override
public void onBackPressed()
{
if (!mWebView.onBackPressed()) { return; }
super.onBackPressed();
}
#Override
public void onPageStarted(String url, Bitmap favicon) { }
#Override
public void onPageFinished(String url) { }
#Override
public void onPageError(int errorCode, String description, String failingUrl) { }
#Override
public void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent) { }
#Override
public void onExternalPageRequest(String url) { }
}
How can I make my Android WebView play music or audio in the background with an audio player in the status bar? Here is my MainActivity.java
I need to solve this problem, to be able to play sound or audio in the background if I have to be with the application open, and if it can, with a music player in the status bar

CursorLoader does not refresh data

I'm creating application to add movie data via external web service to internal database and display list of movies as the main activity in ListFragment, another activity is responsible for search function.
ListFragment mentioned above fetches data from database using LoaderManager. Also this fragment is retained using setRetainInstance(true).
Problem that I encounter is that when I navigate to search, add something to database, and go back to ListFragment by pressing Back Button its not refreshed i.e. added movie is not displayed.
A few important things:
I'm not using ContentProvider so I manually retrieve Cursor from my data base in onCreateLoaderMethod.
I'm using support library - I hope that all imports are proper (if someone could check).
ListFragment uses custom CursorAdapter as its view.
Here is the code:
package com.mp.movieplanner;
import android.app.Activity;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import com.mp.movieplanner.data.DataManager;
public class MovieListFragment extends ListFragment
implements LoaderManager.LoaderCallbacks<Cursor> {
public static String TAG = MovieListFragment.class.getSimpleName();
private OnMovieSelectedListener mCallback;
private DataManager mDataManager;
private MovieCursorAdapter mAdapter;
public interface OnMovieSelectedListener {
public void onMovieSelected(int position);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.i(TAG, "onAttach(Activity)");
mDataManager = ((MoviePlannerApp)activity.getApplication()).getDataManager();
try {
mCallback = (OnMovieSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnMovieSelectedListener");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate(Bundle)");
final int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? android.R.layout.simple_list_item_activated_1
: android.R.layout.simple_list_item_1;
setRetainInstance(true);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.i(TAG, "onActivityCreated(Bundle)");
super.onActivityCreated(savedInstanceState);
mAdapter = new MovieCursorAdapter(getActivity(), null, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
#Override
public void onStart() {
super.onStart();
Log.i(TAG, "onStart()");
if (getFragmentManager().findFragmentById(R.id.movie_details_fragment) != null) {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
}
#Override
public void onResume() {
super.onResume();
Log.i(TAG, "onResume()");
}
#Override
public void onDetach() {
super.onDetach();
Log.i(TAG, "onDetach()");
mCallback = null;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Notify the parent activity of selected item
if (mCallback != null) {
mCallback.onMovieSelected(position);
// Set the item as checked to be highlighted when in two-pane layout
getListView().setItemChecked(position, true);
}
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity()) {
#Override
public Cursor loadInBackground() {
return mDataManager.getMovieCursor();
}
};
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> arg0) {
mAdapter.swapCursor(null);
}
#Override
public void onPause() {
Log.i(TAG, "onPause()");
super.onPause();
}
#Override
public void onStop() {
Log.i(TAG, "onStop()");
super.onStop();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
}
I would advise:
#Override
public void onResume() {
super.onResume();
Log.i(TAG, "onResume()");
getLoaderManager().restartLoader(0, null, this);
}
#Override
public void onResume() {
super.onResume();
Log.i(TAG, "onResume()");
getLoaderManager().initLoader(0, null, this);
}
try that

Android speech Recognition App Without Pop Up

I'm currently looking into getting a career with JAVA and have decided to start by building an app.
I have this code right here that I am using to trigger Speech Recognition.
public class MainActivity extends Activity implements OnClickListener{
private static final int VR_REQUEST = 999;
private ListView wordList;
private final String LOG_TAG = "SpeechRepeatActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button speechBtn = (Button) findViewById(R.id.speech_btn);
wordList = (ListView) findViewById (R.id.word_list);
PackageManager packManager= getPackageManager();
List<ResolveInfo> intActivities = packManager.queryIntentActivities
(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
if (intActivities.size() !=0){
speechBtn.setOnClickListener(this);
} else {
speechBtn.setEnabled(false);
Toast.makeText(this,"Oops - Speech Recognition Not Supported!",
Toast.LENGTH_LONG).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClick(View v){
if (v.getId() == R.id.speech_btn) {
listenToSpeech();
}
}
private void listenToSpeech() {
//start the speech recognition intent passing required data
Intent listenIntent =
new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
//indicate package
listenIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
getClass().getPackage().getName());
//message to display while listening
listenIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Say a word!");
//set speech model
listenIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
//specify number of results to retrieve
listenIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10);
//start listening
startActivityForResult(listenIntent, VR_REQUEST);
}
#Override
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
//check speech recognition result
if (requestCode == VR_REQUEST && resultCode == RESULT_OK) {
//store the returned word list as an ArrayList
ArrayList<String> suggestedWords = data.
getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
//set the retrieved list to display in the ListView
//using an ArrayAdapter
wordList.setAdapter(new ArrayAdapter<String>
(this, R.layout.word, suggestedWords));
}
//this detects which one the user clicks
wordList.setOnItemClickListener(new OnItemClickListener(){
//click listener for items within list
public void onItemClick(AdapterView<?> parent,
View view, int position, long id){
//cast the
TextView wordView = (TextView)
//retrive the chosen word
String wordChosen= (String) wordView.
//output for debugging
Log.v(LOG_TAG, "chosen:" +wordChosen);
}});
super.onActivityResult(requestCode, resultCode, data);
}
}
In this app the user presses a button and gets displayed with the Google Voice Input screen where you can click a button (it actually goes automatically) and you can speak, it will stop and it will display it. I don't want that window to pop up at all though. Instead just let the user click the button and be able to speak and let the app stop and display the text automatically (it already does that).
PLEASE! I understand that there are already answers on the form showing how to do this, in fact a user name JEEZ posted some code right here.
I don't know if I understood where to put this in my project file. I AM A NOOB! If anyone could help clarify this I would GREATLY appreciate your help.
Here is my code:
package com.example.speechrecognizertest;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.TextView;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
private static final int VR_REQUEST = 999;
public static final String TAG = null;
private ListView wordList;
private final String LOG_TAG = "SpeechRepeatActivity";
private SpeechRecognizer mSpeechRecognizer;
private Intent mSpeechRecognizerIntent;
private boolean mIslistening;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button speechBtn = (Button) findViewById(R.id.speech_btn);
wordList = (ListView) findViewById(R.id.word_list);
PackageManager packManager = getPackageManager();
List<ResolveInfo> intActivities = packManager.queryIntentActivities(
new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
if (!mIslistening)
{
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
} else {
speechBtn.setEnabled(false);
Toast.makeText(this, "Oops - Speech Recognition Not Supported!",
Toast.LENGTH_LONG).show();
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
protected class SpeechRecognitionListener implements RecognitionListener
{
#Override
public void onBeginningOfSpeech()
{
//Log.d(TAG, "onBeginingOfSpeech");
}
#Override
public void onBufferReceived(byte[] buffer)
{
}
#Override
public void onEndOfSpeech()
{
//Log.d(TAG, "onEndOfSpeech");
}
#Override
public void onError(int error)
{
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
//Log.d(TAG, "error = " + error);
}
#Override
public void onEvent(int eventType, Bundle params)
{
}
#Override
public void onPartialResults(Bundle partialResults)
{
}
#Override
public void onReadyForSpeech(Bundle params)
{
Log.d(TAG, "OnReadyForSpeech"); //$NON-NLS-1$
}
#Override
public void onResults(Bundle results)
{
//Log.d(TAG, "onResults"); //$NON-NLS-1$
ArrayList<String> suggestedWords = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
// matches are the return values of speech recognition engine
// Use these values for whatever you wish to do
wordList.setAdapter(new ArrayAdapter<String>(this, R.layout.word, suggestedWords));
}
#Override
public void onRmsChanged(float rmsdB)
{
}
}
AndroidManifest.xml
Add the following permission:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
class members
private SpeechRecognizer mSpeechRecognizer;
private Intent mSpeechRecognizerIntent;
private boolean mIslistening;
In onCreate
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
.........
.........
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
SpeechRecognitionListener listener = new SpeechRecognitionListener();
mSpeechRecognizer.setRecognitionListener(listener);
}
in your button listener just use this code
if (!mIsListening)
{
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}
In onDestroy
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
}
Inside your activity create the inner class
protected class SpeechRecognitionListener implements RecognitionListener
{
#Override
public void onBeginningOfSpeech()
{
//Log.d(TAG, "onBeginingOfSpeech");
}
#Override
public void onBufferReceived(byte[] buffer)
{
}
#Override
public void onEndOfSpeech()
{
//Log.d(TAG, "onEndOfSpeech");
}
#Override
public void onError(int error)
{
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
//Log.d(TAG, "error = " + error);
}
#Override
public void onEvent(int eventType, Bundle params)
{
}
#Override
public void onPartialResults(Bundle partialResults)
{
}
#Override
public void onReadyForSpeech(Bundle params)
{
Log.d(TAG, "onReadyForSpeech"); //$NON-NLS-1$
}
#Override
public void onResults(Bundle results)
{
//Log.d(TAG, "onResults"); //$NON-NLS-1$
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
// matches are the return values of speech recognition engine
// Use these values for whatever you wish to do
}
#Override
public void onRmsChanged(float rmsdB)
{
}
}
EDIT 2015-02-07: Incorporated code from the answers to this question by ZakiMak and Born To Win into the code in this answer to make this one more complete.
Don't Forget to add permission of following:-
<uses-permission android:name="android.permission.RECORD_AUDIO" />
It's been a long time since the post. Still for those who are looking, the above code provided by Hoan is almost complete, but there is an important line missing. Both in question and answer and I am not sure how it could work without that.
You need to create the SpeechRecognitionListener and set it as a listener for the SpeechRecognizer. Also it has to be done before we make a call to startListening() method of the SpeechRecognizer.
SpeechRecognitionListener listener = new SpeechRecognitionListener();
mSpeechRecognizer.setRecognitionListener(listener);
Then you also need to remove the listener from the onError event.
I ran into that issue as well. It seems like having startActivityForResult(...) will enable the pop-up mic, then you can handle the response in onActivityResult(). However, simply adding that startActivityForResult messed up my startListening(mSpeechRecognizerIntent), so you may need to do more adjustment.
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
startActivityForResult(recognizerIntent, 100);
// call back
onActivityResult(int requestCode, int resultCode, Intent data){...}

Categories