I am trying to route my TTS output to an external bluetooth SCO device (works fine with local speaker and mic) but it doesn't play out.
I am setting the route for AudioManager as follows -
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
The utterances are played out with this method -
private void say(String text, String utteranceId) {
Log.d(TAG, "Saying: " + text);
final Bundle ttsParams = new Bundle();
ttsParams.putInt(TextToSpeech.Engine.KEY_PARAM_STREAM, AudioManager.STREAM_VOICE_CALL);
mTextToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, ttsParams, utteranceId);
}
There's no audio from the speaker. If I don't setBluetoothScoOn to true it works fine with the in-built speaker.
Use this class:
public abstract class BluetoothHeadsetUtils {
private AudioManager mAudioManager;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothHeadset mBluetoothHeadset;
private BluetoothDevice mConnectedHeadset;
private Context mContext;
private CountDownTimer mCountDown;
private BroadcastReceiver mHeadsetBroadcastReceiver;
private BluetoothProfile.ServiceListener mHeadsetProfileListener;
private boolean mIsCountDownOn;
private boolean mIsOnHeadsetSco;
private boolean mIsStarted;
private boolean receiverRegistered;
public BluetoothHeadsetUtils(final Context context) {
mHeadsetBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
final int intExtra = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset
.STATE_DISCONNECTED);
if (intExtra == BluetoothHeadset.STATE_CONNECTED) {
BluetoothHeadsetUtils.this.mConnectedHeadset = intent.getParcelableExtra(BluetoothDevice
.EXTRA_DEVICE);
BluetoothHeadsetUtils.this.mIsCountDownOn = true;
BluetoothHeadsetUtils.this.mCountDown.start();
BluetoothHeadsetUtils.this.onHeadsetConnected();
} else if (intExtra == BluetoothHeadset.STATE_DISCONNECTED) {
if (BluetoothHeadsetUtils.this.mIsCountDownOn) {
BluetoothHeadsetUtils.this.mIsCountDownOn = false;
BluetoothHeadsetUtils.this.mCountDown.cancel();
}
BluetoothHeadsetUtils.this.mConnectedHeadset = null;
BluetoothHeadsetUtils.this.onHeadsetDisconnected();
}
} else {
final int intExtra2 = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset
.STATE_AUDIO_DISCONNECTED);
if (intExtra2 == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
BluetoothHeadsetUtils.this.mIsOnHeadsetSco = true;
if (BluetoothHeadsetUtils.this.mIsCountDownOn) {
BluetoothHeadsetUtils.this.mIsCountDownOn = false;
BluetoothHeadsetUtils.this.mCountDown.cancel();
}
BluetoothHeadsetUtils.this.onScoAudioConnected();
return;
}
if (intExtra2 == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
BluetoothHeadsetUtils.this.mIsOnHeadsetSco = false;
BluetoothHeadsetUtils.this.mBluetoothHeadset.stopVoiceRecognition(BluetoothHeadsetUtils.this
.mConnectedHeadset);
BluetoothHeadsetUtils.this.onScoAudioDisconnected();
}
}
}
};
mHeadsetProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(final int n, final BluetoothProfile bluetoothProfile) {
BluetoothHeadsetUtils.this.mBluetoothHeadset = (BluetoothHeadset) bluetoothProfile;
final List<BluetoothDevice> connectedDevices = BluetoothHeadsetUtils.this.mBluetoothHeadset
.getConnectedDevices();
if (connectedDevices.size() > 0) {
BluetoothHeadsetUtils.this.mConnectedHeadset = connectedDevices.get(0);
BluetoothHeadsetUtils.this.onHeadsetConnected();
BluetoothHeadsetUtils.this.mIsCountDownOn = true;
BluetoothHeadsetUtils.this.mCountDown.start();
} else {
BluetoothHeadsetUtils.this.noHeadsetConnected();
}
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
BluetoothHeadsetUtils.this.mContext.registerReceiver(BluetoothHeadsetUtils.this
.mHeadsetBroadcastReceiver, filter);
receiverRegistered = true;
}
public void onServiceDisconnected(final int n) {
BluetoothHeadsetUtils.this.stop();
}
};
mCountDown = new CountDownTimer(10000L, 1000L) {
public void onFinish() {
BluetoothHeadsetUtils.this.mIsCountDownOn = false;
onTimeout();
}
public void onTick(final long n) {
BluetoothHeadsetUtils.this.mBluetoothHeadset.startVoiceRecognition(BluetoothHeadsetUtils.this
.mConnectedHeadset);
}
};
mContext = context;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mAudioManager = (AudioManager) this.mContext.getSystemService(Context.AUDIO_SERVICE);
}
private boolean startBluetooth() {
return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mAudioManager
.isBluetoothScoAvailableOffCall() &&
mBluetoothAdapter.getProfileProxy(mContext, mHeadsetProfileListener, BluetoothProfile.HEADSET);
}
public boolean isOnHeadsetSco() {
return mIsOnHeadsetSco;
}
protected void onTimeout() {
}
protected void noHeadsetConnected() {
}
protected void onHeadsetConnected() {
}
protected void onHeadsetDisconnected() {
}
protected void onScoAudioConnected() {
}
protected void onScoAudioDisconnected() {
}
#UiThread
public boolean start() {
if (!mIsStarted) {
mIsStarted = true;
mIsStarted = startBluetooth();
}
return mIsStarted;
}
#UiThread
public void stop() {
if (mIsStarted) {
mIsStarted = false;
stopBluetooth();
}
}
private void stopBluetooth() {
if (mIsCountDownOn) {
mIsCountDownOn = false;
mCountDown.cancel();
}
try {
if (receiverRegistered) {
mContext.unregisterReceiver(mHeadsetBroadcastReceiver);
}
} catch (IllegalArgumentException ignored) {
} finally {
receiverRegistered = false;
}
if (mBluetoothHeadset != null) {
mBluetoothHeadset.stopVoiceRecognition(mConnectedHeadset);
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
mBluetoothHeadset = null;
}
mIsOnHeadsetSco = false;
}
}
Use your say method in the onScoAudioConnected callback.
Related
Actually I want to do speech to text continuously in the background so actually I am using the solution which is given in the below link but i m not getting how can i implement it.
link
I have done this so far but still my service is not running and i am not getting any output
So I think that i have done something wrong in its implementation.Please help me and correct my code in order to run service and get my output
This is my mainactivity.java
public class MainActivity extends AppCompatActivity {
private int mBindFlag ;
private Messenger mServiceMessenger ;
private Button btStartService;
private TextView tvText;
#Override
protected void onStart() {
super.onStart();
Log.d("check", "onStart: ");
bindService(new Intent(getApplicationContext(), MyService.class), mServiceConnection, mBindFlag);
}
#Override
protected void onStop() {
super.onStop();
if (mServiceMessenger != null) {
unbindService(mServiceConnection);
mServiceMessenger = null;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent service = new Intent(this, MyService.class);
this.startService(service);
mBindFlag = Context.BIND_ABOVE_CLIENT;
Log.d("check", "onCreate: "+mBindFlag);
btStartService = (Button) findViewById(R.id.btStartService);
tvText = (TextView) findViewById(R.id.tvText);
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
Manifest.permission.RECORD_AUDIO
};
if (!hasPermissions(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
}
public static boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
private final ServiceConnection mServiceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName name, IBinder service)
{
if (DEBUG) {
Log.d("check", "onServiceConnected");} //$NON-NLS-1$
mServiceMessenger = new Messenger(service);
Message msg = new Message();
msg.what = MyService.MSG_RECOGNIZER_START_LISTENING;
try
{
mServiceMessenger.send(msg);
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
#Override
public void onServiceDisconnected(ComponentName name)
{
if (DEBUG) {Log.d("check", "onServiceDisconnected");} //$NON-NLS-1$
mServiceMessenger = null;
}
};
}
This is the code for my background service
public class MyService extends Service
{
protected AudioManager mAudioManager;
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));
protected boolean mIsListening;
protected volatile boolean mIsCountDownOn;
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
#Override
public void onCreate()
{
super.onCreate();
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());
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());
Log.d("check", "onCreate: "+"service");
}
protected static class IncomingHandler extends Handler
{
private WeakReference<MyService> mtarget;
IncomingHandler(MyService target)
{
mtarget = new WeakReference<MyService>(target);
}
#Override
public void handleMessage(Message msg)
{
final MyService target = mtarget.get();
switch (msg.what)
{
case MSG_RECOGNIZER_START_LISTENING:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
// turn off beep sound
target.mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
}
if (!target.mIsListening)
{
target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
target.mIsListening = true;
Log.d("check", "message start listening"); //$NON-NLS-1$
}
break;
case MSG_RECOGNIZER_CANCEL:
target.mSpeechRecognizer.cancel();
target.mIsListening = false;
Log.d("check", "message canceled recognizer"); //$NON-NLS-1$
break;
}
}
}
// Count down timer for Jelly Bean work around
protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000)
{
#Override
public void onTick(long millisUntilFinished)
{
// TODO Auto-generated method stub
}
#Override
public void onFinish()
{
mIsCountDownOn = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_CANCEL);
try
{
mServerMessenger.send(message);
message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
}
};
#Override
public void onDestroy()
{
super.onDestroy();
if (mIsCountDownOn)
{
mNoSpeechCountDown.cancel();
}
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
}
}
protected class SpeechRecognitionListener implements RecognitionListener
{
private static final String TAG = "check";
#Override
public void onBeginningOfSpeech()
{
// speech input will be processed, so there is no need for count down anymore
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
//Log.d(TAG, "onBeginingOfSpeech"); //$NON-NLS-1$
}
#Override
public void onBufferReceived(byte[] buffer)
{
}
#Override
public void onEndOfSpeech()
{
//Log.d(TAG, "onEndOfSpeech"); //$NON-NLS-1$
}
#Override
public void onError(int error)
{
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
mIsListening = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
try
{
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
//Log.d(TAG, "error = " + error); //$NON-NLS-1$
}
#Override
public void onEvent(int eventType, Bundle params)
{
}
#Override
public void onPartialResults(Bundle partialResults)
{
}
#Override
public void onReadyForSpeech(Bundle params)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
mIsCountDownOn = true;
mNoSpeechCountDown.start();
mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
}
Log.d("check", "onReadyForSpeech");
}
#Override
public void onResults(Bundle results)
{
Toast.makeText(getApplicationContext(),results.toString(),Toast.LENGTH_LONG).show();
}
#Override
public void onRmsChanged(float rmsdB)
{
}
}
#Override
public IBinder onBind(Intent arg0) {
return mServerMessenger.getBinder();
}
}
I got my answer I have not enabled the service from the manifest
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
Error I'm getting null point exception in Bluetooth when I'm starting a service.
LiveFragment.class
public class LiveFragment extends Fragment {
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
private static final int REQUEST_ENABLE_BT = 3;
private BluetoothAdapter mBluetoothAdapter =null;
public BluetoothChatService mChatService = null;
private PowerManager.WakeLock wakeLock = null;
private PowerManager powerManager = null;
private String mConnectedDeviceName = null;
private boolean isServiceBound;
private boolean preRequisites = true;
private SharedPreferences prefs;
private BroadcastReceiver broadcastReceiver;
private Context c;
private AbstractGatewayService ab;
protected ImageView blue_onoffBut, gps_Button, obd_inidca, ss_button, bluetooth_indicator, gps_indicator,obd_connectButt;
protected TextView ss_Status,btStatusTextView,obdStatusTextView,gpsStatusTextView;
private LinearLayout vv;
protected BluetoothSocket sock = null;
public LiveFragment() {
// Required empty public constructor
}
private final Runnable mQueueCommands = new Runnable() {
public void run() {
Log.d(TAG, "Runnable mQueueCommands ()");
if (ab != null && ab.isRunning() && ab.queueEmpty()) {
queueCommands();
}
// run again in period defined in preferences
new Handler().postDelayed(mQueueCommands, 4000);
}
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_live, container, false);
blue_onoffBut = (ImageView) view.findViewById(R.id.blutooth_butoon);
gps_Button = (ImageView) view.findViewById(R.id.gps_button);
obd_inidca = (ImageView) view.findViewById(R.id.obd_Indicator);
ss_button = (ImageView) view.findViewById(ssButton);
gps_indicator = (ImageView) view.findViewById(R.id.gps_indicator);
bluetooth_indicator = (ImageView) view.findViewById(R.id.bluetooth_indicator);
obd_connectButt = (ImageView) view.findViewById(R.id.Obd_Connect_Button);
ss_Status = (TextView) view.findViewById(R.id.statusTx);
btStatusTextView = (TextView) view.findViewById(R.id.blue);
obdStatusTextView = (TextView) view.findViewById(R.id.obd);
gpsStatusTextView = (TextView) view.findViewById(R.id.gps);
vv = (LinearLayout) view.findViewById(R.id.fragment_live_layout);
ss_Status.setTextColor(getResources().getColor(R.color.colorGreen));
if (mBluetoothAdapter.isEnabled()) {
bluetooth_indicator.setImageResource(R.drawable.green_circle);
} else {
bluetooth_indicator.setImageResource(R.drawable.red_circle);
}
gps_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final LocationManager manager = (LocationManager) getActivity().getSystemService( Context.LOCATION_SERVICE );
if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
buildAlertMessageNoGps();
}
else {
showToast("Already GPS is ON");
}
}
});
blue_onoffBut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
showToast("Bluetooth Turned ON"+"\n"+"Connect Your OBD now");
bluetooth_indicator.setImageResource(R.drawable.green_circle);
mChatService = new BluetoothChatService(getActivity(), mHandler);
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
} else if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
mBluetoothAdapter.cancelDiscovery();
obd_inidca.setImageResource(R.drawable.red_circle);
showToast("Bluetooth Turned OFF");
bluetooth_indicator.setImageResource(R.drawable.red_circle);
}
}
});
ss_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBluetoothAdapter.isEnabled() && mChatService.getState() == BluetoothChatService.STATE_CONNECTED) {
startLiveData();
} else if (!mBluetoothAdapter.isEnabled()) {
showToast("Turn ON Bluetooth to Continue");
}
else if (!(mChatService.getState() == BluetoothChatService.STATE_CONNECTED)){
showToast("Select your OBD to Start ");
}
}
});
obd_connectButt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mBluetoothAdapter.isEnabled()) {
Intent serverIntent = new Intent(getActivity(), DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
}
else if (!mBluetoothAdapter.isEnabled()){
showToast("Turn ON Bluetooth to Connect OBD");
}
}
});
return view;
}
private ServiceConnection serviceConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder binder) {
Log.d(TAG, className.toString() + " service is bound");
isServiceBound = true;
ab = ((AbstractGatewayService.AbstractGatewayServiceBinder) binder).getService();
ab.setContext(getActivity());
Log.d(TAG, "Starting live data");
try {
ab.startService();
if (preRequisites)
btStatusTextView.setText("Connected");
} catch (IOException ioe) {
Log.e(TAG, "Failure Starting live data");
btStatusTextView.setText("Connection failed");
doUnbindService();
}
}
#Override
protected Object clone() throws CloneNotSupportedException {
Log.d(TAG, "CloneNotSupportedException ");
return super.clone();
}
#Override
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, className.toString() + " service is unbound");
isServiceBound = false;
}
};
public static String LookUpCommand(String txt) {
Log.d(TAG, "LookUpCommand() ");
for (AvailableCommandNames item : AvailableCommandNames.values()) {
if (item.getValue().equals(txt)) return item.name();
}
return txt;
}
public void updateTextView(final TextView view, final String txt) {
Log.d(TAG, "updateTextView() ");
new Handler().post(new Runnable() {
public void run() {
view.setText(txt);
}
});
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void stateUpdate(ObdCommandJob job) {
final String cmdName = job.getCommand().getName();
String cmdResult = "";
final String cmdID = LookUpCommand(cmdName);
Log.d(TAG, "stateUpdate() ");
if (job.getState().equals(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR)) {
cmdResult = job.getCommand().getResult();
if (cmdResult != null && isServiceBound) {
obdStatusTextView.setText(cmdResult.toLowerCase());
}
} else if (job.getState().equals(ObdCommandJob.ObdCommandJobState.BROKEN_PIPE)) {
if (isServiceBound)
stopLiveData();
} else if (job.getState().equals(ObdCommandJob.ObdCommandJobState.NOT_SUPPORTED)) {
cmdResult = "NA";
} else {
cmdResult = job.getCommand().getFormattedResult();
if (isServiceBound)
obdStatusTextView.setText("Receiving data...");
}
cmdResult.replace("NODATA", "0");
if (vv.findViewWithTag(cmdID) != null) {
TextView existingTV = (TextView) vv.findViewWithTag(cmdID);
existingTV.setText(cmdResult);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
FragmentActivity activity = getActivity();
Toast.makeText(activity, "No Bluetooth Feature in Device", Toast.LENGTH_LONG).show();
activity.finish();
}
}
#Override
public void onStart() {
super.onStart();
final LocationManager manager = (LocationManager) getActivity().getSystemService( Context.LOCATION_SERVICE );
if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
gps_indicator.setImageResource(R.drawable.red_circle);
}
if(mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.disable();
bluetooth_indicator.setImageResource(R.drawable.red_circle);
}
}
#Override
public void onResume() {
super.onResume();
powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "ObdReader");
final LocationManager manager = (LocationManager) getActivity().getSystemService( Context.LOCATION_SERVICE );
if ( manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
gps_indicator.setImageResource(R.drawable.green_circle);
} else {
gps_indicator.setImageResource(R.drawable.red_circle);
}
EventBus.getDefault().register(this);
if(mBluetoothAdapter.isEnabled()) {
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
}
}
#Override
public void onPause() {
super.onPause();
Log.d(TAG, "Pausing..");
releaseWakeLockIfHeld();
EventBus.getDefault().unregister(this);
}
private void showToast(String message) {
final Toast toast = Toast.makeText(getContext(), message, Toast.LENGTH_SHORT);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 500);
}
#Override
public void onDestroy() {
/* unregisterReceiver(mReceiver);*/
super.onDestroy();
releaseWakeLockIfHeld();
if (mChatService != null) {
mChatService.stop();
}
if (isServiceBound) {
doUnbindService();
}
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
}
showToast("Take Care!");
}
private void startLiveData() {
if (mChatService.getState() == BluetoothChatService.STATE_CONNECTED) {
Log.d(TAG, "Starting live data..");
ss_Status.setText("Stop");
ss_Status.setTextColor(getResources().getColor(R.color.colorRed));
wakeLock.acquire();
ss_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ss_Status.setText("Go Live");
ss_Status.setTextColor(getResources().getColor(R.color.colorGreen));
stopLiveData();
}
});
doBindService();
LocalBroadcastManager.getInstance(getActivity()).registerReceiver((broadcastReceiver), new IntentFilter(OBD_GATEWAY_SERVICE));
new Handler().post(mQueueCommands);
}
}
private void stopLiveData() {
Log.d(TAG, "Stopping live data..");
releaseWakeLockIfHeld();
new Handler().removeCallbacks(mQueueCommands);
ss_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ss_Status.setText("Go Live");
ss_Status.setTextColor(getResources().getColor(R.color.colorGreen));
startLiveData();
}
});
doUnbindService();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(broadcastReceiver);
}
private void queueCommands() {
Log.d(TAG, "LiveFragment queueCommands() ");
if (isServiceBound) {
for (ObdCommand Command : ObdConfig.getCommands()) {
if (prefs.getBoolean(Command.getName(), true))
ab.queueJob(new ObdCommandJob(Command));
}
}
}
private void doBindService() {
if (!isServiceBound) {
Log.d(TAG, "Binding OBD service..");
if (preRequisites) {
btStatusTextView.setText("Connecting.....");
Intent serviceIntent = new Intent(getActivity(),ObdGatewayService.class);
getActivity().bindService(serviceIntent, serviceConn, Context.BIND_AUTO_CREATE);
}
}
}
private void doUnbindService() {
if (isServiceBound) {
if (ab.isRunning()) {
ab.stopService();
if (preRequisites)
btStatusTextView.setText("Ready...");
}
Log.d(TAG, "Unbinding OBD service..");
getActivity().unbindService(serviceConn);
isServiceBound = false;
obdStatusTextView.setText("Disconnected");
}
}
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
FragmentActivity activity = getActivity();
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
obd_inidca.setImageResource(R.drawable.green_circle);
break;
case BluetoothChatService.STATE_CONNECTING:
obd_inidca.setImageResource(R.drawable.orange_circle);
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
obd_inidca.setImageResource(R.drawable.red_circle);
break;
}
break;
case Constants.MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME);
if (null != activity) {
Toast.makeText(activity, "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
obd_inidca.setImageResource(R.drawable.green_circle);
}
break;
case Constants.MESSAGE_TOAST:
if (null != activity) {
Toast.makeText(activity, msg.getData().getString(Constants.TOAST),
Toast.LENGTH_SHORT).show();
}
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
try {
connectDevice(data, true);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void connectDevice(Intent data, boolean secure) throws IOException {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice object
BluetoothDevice dev = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(dev, secure);
}.
This is ObdGateway service class:
public class ObdGatewayService extends AbstractGatewayService {
private static final String TAG = ObdGatewayService.class.getName();
#Inject
SharedPreferences prefs;
private BluetoothDevice dev = null;
private BluetoothSocket sock = null;
private BluetoothChatService mChatservice = null;
private BluetoothAdapter bluetoothAdapter =null;
public final static String JOB_NAME_STAMP = "Name";
public final static String JOB_STATE_STAMP = "State";
public final static String JOB_RESULT_STAMP = "Result";
public final static String JOB_FORMATED_RESULT_STAMP = "Formated REsult";
public final static String OBD_GATEWAY_SERVICE = "com.samplersoft.saz.Obd.ObdGatewayService";
public void startService() throws IOException {
Log.d(TAG, "Starting service..");
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// get the remote Bluetooth device
if(mChatservice.getState() != BluetoothChatService.STATE_CONNECTED){
Toast.makeText(ctx, "No Bluetooth device selected", Toast.LENGTH_LONG).show();
// log error
Log.e(TAG, "No Bluetooth device has been selected.");
stopService();
throw new IOException();
}
else
{
Log.d(TAG, "Stopping Bluetooth discovery.");
bluetoothAdapter.cancelDiscovery();
try {
startObdConnection();
} catch (Exception e) {
Log.e(
TAG,
"There was an error while establishing connection. -> "
+ e.getMessage()
);
// in case of failure, stop this service.
stopService();
throw new IOException();
}
}
}
private void startObdConnection() throws IOException {
Log.d(TAG, "Starting OBD connection..");
isRunning = true;
if(mChatservice.getState() == BluetoothChatService.STATE_CONNECTED){
// Let's configure the connection.
Log.d(TAG, "Queueing jobs for connection configuration..");
queueJob(new ObdCommandJob(new ObdResetCommand()));
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
queueJob(new ObdCommandJob(new EchoOffCommand()));
queueJob(new ObdCommandJob(new EchoOffCommand()));
queueJob(new ObdCommandJob(new LineFeedOffCommand()));
queueJob(new ObdCommandJob(new TimeoutCommand(62)));
// Get protocol from preferences
queueJob(new ObdCommandJob(new SelectProtocolCommand(ObdProtocols.valueOf("AUTO"))));
// Job for returning dummy data
queueJob(new ObdCommandJob(new AmbientAirTemperatureCommand()));
queueCounter = 0L;
Log.d(TAG, "Initialization jobs queued.");
}
else {
stopService();
throw new IOException();
}
}
#Override
public void queueJob(ObdCommandJob job) {
// This is a good place to enforce the imperial units option
//job.getCommand().useImperialUnits(prefs.getBoolean(ConfigActivity.IMPERIAL_UNITS_KEY, false));
// Now we can pass it along
super.queueJob(job);
}
protected void executeQueue() throws InterruptedException {
Log.d(TAG, "Executing queue..");
while (!Thread.currentThread().isInterrupted()) {
ObdCommandJob job = null;
try {
job = jobsQueue.take();
// log job
Log.d(TAG, "Taking job[" + job.getId() + "] from queue..");
if (job.getState().equals(ObdCommandJob.ObdCommandJobState.NEW)) {
Log.d(TAG, "Job state is NEW. Run it..");
job.setState(ObdCommandJob.ObdCommandJobState.RUNNING);
if (sock.isConnected()) {
job.getCommand().run(sock.getInputStream(), sock.getOutputStream());
} else {
job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
Log.e(TAG, "Can't run command on a closed socket.");
}
} else
// log not new job
Log.e(TAG,
"Job state was not new, so it shouldn't be in queue. BUG ALERT!");
} catch (InterruptedException i) {
Thread.currentThread().interrupt();
} catch (UnsupportedCommandException u) {
if (job != null) {
job.setState(ObdCommandJob.ObdCommandJobState.NOT_SUPPORTED);
}
Log.d(TAG, "Command not supported. -> " + u.getMessage());
} catch (IOException io) {
if (job != null) {
if(io.getMessage().contains("Broken pipe"))
job.setState(ObdCommandJob.ObdCommandJobState.BROKEN_PIPE);
else
job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
}
Log.e(TAG, "IO error. -> " + io.getMessage());
} catch (Exception e) {
if (job != null) {
job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
}
Log.e(TAG, "Failed to run command. -> " + e.getMessage());
}
ObdCommandJob job2 = job;
if(job2 !=null)
EventBus.getDefault().post(job2);
}
}
public void stopService() {
Log.d(TAG, "Stopping service..");
jobsQueue.clear();
isRunning = false;
if (sock != null)
// close socket
try {
sock.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
// kill service
stopSelf();
}
public boolean isRunning() {
return isRunning;
}
}.
This is Abstract Class where service method gets called from from Livefragment Class from serivceConnection().
public abstract class AbstractGatewayService extends RoboService {
private static final String TAG = AbstractGatewayService.class.getName();
private final IBinder binder = new AbstractGatewayServiceBinder();
protected Context ctx;
protected boolean isRunning = false;
protected Long queueCounter = 0L;
protected BlockingQueue<ObdCommandJob> jobsQueue = new LinkedBlockingQueue<>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
executeQueue();
} catch (InterruptedException e) {
t.interrupt();
}
}
});
protected LocalBroadcastManager broadcastManager;
#Override
public IBinder onBind(Intent intent) {
return binder;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "Creating service..");
final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
t.start();
Log.d(TAG, "Service created.");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "Destroying service...");
t.interrupt();
broadcastManager = LocalBroadcastManager.getInstance(this);
Log.d(TAG, "Service destroyed.");
}
public boolean isRunning() {
return isRunning;
}
public boolean queueEmpty() {
return jobsQueue.isEmpty();
}
public void queueJob(ObdCommandJob job) {
queueCounter++;
Log.d(TAG, "Adding job[" + queueCounter + "] to queue..");
job.setId(queueCounter);
try {
jobsQueue.put(job);
Log.d(TAG, "Job queued successfully.");
} catch (InterruptedException e) {
job.setState(ObdCommandJob.ObdCommandJobState.QUEUE_ERROR);
Log.e(TAG, "Failed to queue job.");
}
}
public void setContext(Context c) {
ctx = c;
}
abstract protected void executeQueue() throws InterruptedException;
abstract public void startService() throws IOException;
abstract public void stopService();
public class AbstractGatewayServiceBinder extends Binder {
public AbstractGatewayService getService() {
return AbstractGatewayService.this;
}
}
}.
You are getting the exception because in class ObdGatewayService your class member mChatservice is not the same as mChatservice in class LiveFragment
They are just different member variables
mChatservice gets assigned like this in your Fragment
mChatService = new BluetoothChatService(getActivity(), mHandler);
You need to pass this reference to ObdGatewayService 's startService() like this where ever you are instantiating/invoking it:-
ObdGatewayService ogs;
....
ogs.startservice(mChatservice); // This is fragment's member reference
And in ObdGatewayService you have to assign it accordingly:-
public void startService(BluetoothChatService _mChatservice) throws IOException {
Log.d(TAG, "Starting service..");
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mChatservice = _mChatservice //Assignment YOU ARE MISSING THIS
.......
.......
}
I'm writinng Android app that receiving data via bluetooth from another device. Those data as in fact streaming non-stop. After getting about 50 or 70 of them, app slows down and stop showing me received data. App cache is full, but clearing it (deleting context.getCacheDir()) doesn't help. After restarting whole app, I can again get next part of data. WHat can I do for avoiding this "lag"?
my MainActivity:
public class MainActivity extends Activity {
private BluetoothAdapter bluetoothAdapter;
private boolean pendingRequestEnableBt = false;
private final String SAVED_PENDING_REQUEST_ENABLE_BT = "PENDING_REQUEST_ENABLE_BT";
private BluetoothResponseHandler mHandler;
private static MainActivity instance;
private DeviceConnector connector;
private TextView console;
private String deviceName;
private final int REQUEST_CONNECT_DEVICE = 1;
private final int REQUEST_ENABLE_BT = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
instance = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
console = (TextView) findViewById(R.id.main_text_console);
if (savedInstanceState != null) {
pendingRequestEnableBt = savedInstanceState.getBoolean(SAVED_PENDING_REQUEST_ENABLE_BT);
}
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this, "No bluetooth available", Toast.LENGTH_LONG).show();
}
if (mHandler == null) {
mHandler = new BluetoothResponseHandler(this);
} else {
mHandler.setTarget(this);
}
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
getActionBar().setSubtitle(deviceName);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVED_PENDING_REQUEST_ENABLE_BT, pendingRequestEnableBt);
outState.putString("device_name", deviceName);
if (console != null) {
final String log = console.getText().toString();
outState.putString("AC", log);
}
}
public boolean isAdapterReady() {
return (bluetoothAdapter != null) && (bluetoothAdapter.isEnabled());
}
private static class BluetoothResponseHandler extends Handler {
private WeakReference<MainActivity> mActivity;
public BluetoothResponseHandler(MainActivity activity) {
mActivity = new WeakReference<MainActivity>(activity);
}
public void setTarget(MainActivity target) {
mActivity.clear();
mActivity = new WeakReference<MainActivity>(target);
}
#Override
public void handleMessage(Message msg) {
MainActivity activity = mActivity.get();
if (activity != null) {
if (msg.what==MessageType.MESSAGE_STATE_CHANGE.getValue()) {
final ActionBar bar = activity.getActionBar();
switch (msg.arg1) {
case DeviceConnector.STATE_CONNECTED:
bar.setSubtitle("Połączono.");
break;
case DeviceConnector.STATE_CONNECTING:
bar.setSubtitle("Łączenie");
break;
case DeviceConnector.STATE_NONE:
bar.setSubtitle("Rozłączono.");
break;
}
} else if (msg.what==MessageType.MESSAGE_READ.getValue()) {
if (msg.obj != null) {
activity.appendLog((String)msg.obj);
}
} else if (msg.what==MessageType.MESSAGE_DEVICE_NAME.getValue()) {
activity.setDeviceName((String) msg.obj);
}
}
}
}
private void startDeviceListActivity() {
stopConnection();
startActivityForResult(new Intent(this, DeviceListActivity.class), REQUEST_CONNECT_DEVICE);
}
private void stopConnection() {
if (connector != null) {
connector.stop();
connector = null;
}
}
#Override
public boolean onSearchRequested() {
if (isAdapterReady()) {
startDeviceListActivity();
}
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.device_control_activity, menu);
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
if (resultCode == Activity.RESULT_OK) {
String address = data.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
if (isAdapterReady() && (connector == null)) setupConnector(device);
}
break;
case REQUEST_ENABLE_BT:
pendingRequestEnableBt = false;
if (resultCode != Activity.RESULT_OK) {
Toast.makeText(this, "Bt not enabled", Toast.LENGTH_LONG).show();
}
break;
}
}
private void setupConnector(BluetoothDevice connectedDevice) {
stopConnection();
connector = new DeviceConnector(new DeviceData(connectedDevice, getString(R.string.empty_device_name)), mHandler);
connector.connect();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_search:
if (isAdapterReady()) {
if (isConnected()) {
stopConnection();
} else {
startDeviceListActivity();
}
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void appendLog(String message) {
String msg = message.replaceAll("[\n\t\r ]*", "");
console.append(msg.length() + ": " + msg + "\n");
final int scrollAmount = console.getLayout().getLineTop(console.getLineCount()) - console.getHeight();
console.scrollTo(0, scrollAmount>0?scrollAmount:0);
delete(getCacheDir());
}
private boolean isConnected() {
return (connector != null) && (connector.getState() == DeviceConnector.STATE_CONNECTED);
}
public static MainActivity getInstance() {
return instance;
}
public void delete(File file) {
if (file.exists()) {
if (file.isFile()) {
file.delete();
} else if (file.isDirectory()) {
for (File f:file.listFiles()) {
delete(f);
}
}
}
}
}
this code is downloaded, it isn't mine, I just modified it.
I have implemented Twilio in my android app for outgoing and incoming calls. But I'm facing an issue while getting incoming call with the background service. The issue is that I get calls in first 30-40 mins only. After sometime phone stops getting incoming calls. I tried so much. Please respond me soon. I'm sharing code with you too.
I get token from a background service which generates token after a time period.
IncomingCallService.java
public class IncomingCallService extends Service implements LoginListener,
BasicConnectionListener, BasicDeviceListener, View.OnClickListener,
CompoundButton.OnCheckedChangeListener,
RadioGroup.OnCheckedChangeListener {
private static Handler handler, handler_login;
public IncomingPhone phone;
SharedPreferences login_details;
Vibrator vibrator;
Ringtone r;
Uri notification;
public static final String LOGIN_DETAILS = "XXXXXXXX";
AudioManager am;
Intent intent;
public static String DEFAULT_CLIENT_NAME = "developer";
static String Twilio_id = "",
INCOMING_AUTH_PHP_SCRIPT = MenuItems.INCOMING_AUTH_PHP_SCRIPT
+ MenuItems.Twilio_id;
Runnable newrun;
Activity context;
Context ctx;
static String op_id = "";
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
login_details = getSharedPreferences(LOGIN_DETAILS,
Context.MODE_PRIVATE);
if (login_details.contains("twilio_Id")) {
Twilio_id = login_details.getString("twilio_Id", "");
}
handler_login = new Handler();
handler_login.postDelayed(new Runnable() {
#Override
public void run() {
Login();
handler_login.postDelayed(this, 20000);
}
}, 1000);
}
public void Login() {
phone = IncomingPhone.getInstance(getApplicationContext());
phone.setListeners(this, this, this);
phone.login(DEFAULT_CLIENT_NAME, true, true);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.intent = intent;
// I know getIntent always return NULL in service
if (intent != null) {
op_id = intent.getStringExtra("operator_id");
onCallHandler();
}
return START_STICKY;
}
public void onCallHandler() {
handler = new Handler();
newrun = new Runnable() {
#Override
public void run() {
handler.removeCallbacks(newrun);
new IncomingTokenTask().execute();
if (phone.handleIncomingIntent(intent)) {
}
handler.postDelayed(this, 2000000);
}
};
handler.postDelayed(newrun, 8000000);
}
class IncomingTokenTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... params) {
IncomingPhone.capabilityToken = EntityUtils
.toString(entity);
}
}
The BasicPhone class of twilio
public class IncomingPhone implements DeviceListener, ConnectionListener {
private static final String TAG = "IncomingPhone";
static String decodedString = "";
static String capabilityToken = "";
// TODO: change this to point to the script on your public server
private static final String AUTH_PHP_SCRIPT = MenuItems.INCOMING_AUTH_PHP_SCRIPT+MenuItems.Twilio_id;
public interface LoginListener {
public void onLoginStarted();
public void onLoginFinished();
public void onLoginError(Exception error);
}
public interface BasicConnectionListener {
public void onIncomingConnectionDisconnected();
public void onConnectionConnecting();
public void onConnectionConnected();
public void onConnectionFailedConnecting(Exception error);
public void onConnectionDisconnecting();
public void onConnectionDisconnected();
public void onConnectionFailed(Exception error);
}
public interface BasicDeviceListener {
public void onDeviceStartedListening();
public void onDeviceStoppedListening(Exception error);
}
private static IncomingPhone instance;
public static final IncomingPhone getInstance(Context context) {
if (instance == null)
instance = new IncomingPhone(context);
return instance;
}
private final Context context;
private LoginListener loginListener;
private BasicConnectionListener basicConnectionListener;
private BasicDeviceListener basicDeviceListener;
private static boolean twilioSdkInited;
private static boolean twilioSdkInitInProgress;
private boolean queuedConnect;
private Device device;
private Connection pendingIncomingConnection;
private Connection connection;
private boolean speakerEnabled;
private String lastClientName;
private boolean lastAllowOutgoing;
private boolean lastAllowIncoming;
private IncomingPhone(Context context) {
this.context = context;
}
public void setListeners(LoginListener loginListener,
BasicConnectionListener basicConnectionListener,
BasicDeviceListener basicDeviceListener) {
this.loginListener = loginListener;
this.basicConnectionListener = basicConnectionListener;
this.basicDeviceListener = basicDeviceListener;
}
private void obtainCapabilityToken(String clientName,
boolean allowOutgoing, boolean allowIncoming) {
StringBuilder url = new StringBuilder();
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient httpclient = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory
.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(
httpclient.getParams(), registry);
#SuppressWarnings("unused")
DefaultHttpClient httpClient = new DefaultHttpClient(mgr,
httpclient.getParams());
// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
url.append(AUTH_PHP_SCRIPT);
// This runs asynchronously!
new GetAuthTokenAsyncTask().execute(url.toString());
}
private boolean isCapabilityTokenValid() {
if (device == null || device.getCapabilities() == null)
return false;
long expTime = (Long) device.getCapabilities().get(
Capability.EXPIRATION);
return expTime - System.currentTimeMillis() / 1000 > 0;
}
//
private void updateAudioRoute() {
AudioManager audioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
audioManager.setSpeakerphoneOn(speakerEnabled);
}
public void login(final String clientName, final boolean allowOutgoing,
final boolean allowIncoming) {
if (loginListener != null)
loginListener.onLoginStarted();
this.lastClientName = clientName;
this.lastAllowOutgoing = allowOutgoing;
this.lastAllowIncoming = allowIncoming;
if (!twilioSdkInited) {
if (twilioSdkInitInProgress)
return;
twilioSdkInitInProgress = true;
Twilio.setLogLevel(Log.DEBUG);
Twilio.initialize(context, new Twilio.InitListener() {
#Override
public void onInitialized() {
twilioSdkInited = true;
twilioSdkInitInProgress = false;
obtainCapabilityToken(clientName, allowOutgoing,
allowIncoming);
}
#Override
public void onError(Exception error) {
twilioSdkInitInProgress = false;
if (loginListener != null)
loginListener.onLoginError(error);
}
});
} else {
obtainCapabilityToken(clientName, allowOutgoing, allowIncoming);
}
}
private void reallyLogin(final String capabilityToken) {
try {
if (device == null) {
device = Twilio.createDevice(capabilityToken, this);
Intent intent = new Intent(context, IncomingPhoneActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(
context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
device.setIncomingIntent(pendingIntent);
} else
device.updateCapabilityToken(capabilityToken);
if (loginListener != null)
loginListener.onLoginFinished();
if (queuedConnect) {
// If someone called connect() before we finished initializing
// the SDK, let's take care of that here.
connect(null);
queuedConnect = false;
}
} catch (Exception e) {
if (device != null)
device.release();
device = null;
if (loginListener != null)
loginListener.onLoginError(e);
}
}
public void setSpeakerEnabled(boolean speakerEnabled) {
if (speakerEnabled != this.speakerEnabled) {
this.speakerEnabled = speakerEnabled;
updateAudioRoute();
}
}
public void connect(Map<String, String> inParams) {
if (twilioSdkInitInProgress) {
// If someone calls connect() before the SDK is initialized, we'll
// remember
// that fact and try to connect later.
queuedConnect = true;
return;
}
if (!isCapabilityTokenValid())
login(lastClientName, lastAllowOutgoing, lastAllowIncoming);
if (device == null)
return;
if (canMakeOutgoing()) {
disconnect();
connection = device.connect(inParams, this);
if (connection == null && basicConnectionListener != null)
basicConnectionListener
.onConnectionFailedConnecting(new Exception(
"Couldn't create new connection"));
}
}
public void disconnect() {
IncomingPhoneActivity.incomingAlert = null;
if (connection != null) {
connection.disconnect(); // will null out in onDisconnected()
if (basicConnectionListener != null)
basicConnectionListener.onConnectionDisconnecting();
}
}
public void acceptConnection() {
if (pendingIncomingConnection != null) {
if (connection != null)
disconnect();
pendingIncomingConnection.accept();
connection = pendingIncomingConnection;
pendingIncomingConnection = null;
}
}
public void connecta(String phoneNumber) {
Toast.makeText(context, "Calling...", Toast.LENGTH_SHORT).show();
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("group_id", "11");
// String capabilityToken;
try {
device = Twilio
.createDevice(decodedString, this /* DeviceListener */);
} catch (Exception e1) {
e1.printStackTrace();
}
try {
device.disconnectAll();
} catch (Exception e) {
e.printStackTrace();
}
connection = device.connect(parameters, this);
if (connection == null) {
Log.w(TAG, "Failed to create new connection");
}
}
public void ignoreIncomingConnection() {
if (pendingIncomingConnection != null) {
pendingIncomingConnection.ignore();
}
}
public boolean isConnected() {
return connection != null
&& connection.getState() == Connection.State.CONNECTED;
}
public Connection.State getConnectionState() {
return connection != null ? connection.getState()
: Connection.State.DISCONNECTED;
}
public boolean hasPendingConnection() {
return pendingIncomingConnection != null;
}
public boolean handleIncomingIntent(Intent intent) {
Device inDevice = intent.getParcelableExtra(Device.EXTRA_DEVICE);
Connection inConnection = intent
.getParcelableExtra(Device.EXTRA_CONNECTION);
if (inDevice == null && inConnection == null)
return false;
intent.removeExtra(Device.EXTRA_DEVICE);
intent.removeExtra(Device.EXTRA_CONNECTION);
if (pendingIncomingConnection != null) {
Log.i(TAG, "A pending connection already exists");
inConnection.ignore();
return false;
}
pendingIncomingConnection = inConnection;
pendingIncomingConnection.setConnectionListener(this);
return true;
}
public boolean canMakeOutgoing() {
if (device == null)
return false;
Map<Capability, Object> caps = device.getCapabilities();
return caps.containsKey(Capability.OUTGOING)
&& (Boolean) caps.get(Capability.OUTGOING);
}
public boolean canAcceptIncoming() {
if (device == null)
return false;
Map<Capability, Object> caps = device.getCapabilities();
return caps.containsKey(Capability.INCOMING)
&& (Boolean) caps.get(Capability.INCOMING);
}
public void setCallMuted(boolean isMuted) {
if (connection != null) {
connection.setMuted(isMuted);
}
}
#Override
/* DeviceListener */
public void onStartListening(Device inDevice) {
if (basicDeviceListener != null)
basicDeviceListener.onDeviceStartedListening();
}
#Override
/* DeviceListener */
public void onStopListening(Device inDevice) {
if (basicDeviceListener != null)
basicDeviceListener.onDeviceStoppedListening(null);
}
#Override
/* DeviceListener */
public void onStopListening(Device inDevice, int inErrorCode,
String inErrorMessage) {
if (basicDeviceListener != null)
basicDeviceListener.onDeviceStoppedListening(new Exception(
inErrorMessage));
}
#Override
/* DeviceListener */
public boolean receivePresenceEvents(Device inDevice) {
return false;
}
#Override
/* DeviceListener */
public void onPresenceChanged(Device inDevice, PresenceEvent inPresenceEvent) {
}
#Override
/* ConnectionListener */
public void onConnecting(Connection inConnection) {
if (basicConnectionListener != null)
basicConnectionListener.onConnectionConnecting();
}
#Override
/* ConnectionListener */
public void onConnected(Connection inConnection) {
updateAudioRoute();
if (basicConnectionListener != null)
basicConnectionListener.onConnectionConnected();
}
#Override
/* ConnectionListener */
public void onDisconnected(Connection inConnection) {
if (inConnection == connection) {
connection = null;
if (basicConnectionListener != null)
basicConnectionListener.onConnectionDisconnected();
} else if (inConnection == pendingIncomingConnection) {
pendingIncomingConnection = null;
if (basicConnectionListener != null)
basicConnectionListener.onIncomingConnectionDisconnected();
}
}
#Override
/* ConnectionListener */
public void onDisconnected(Connection inConnection, int inErrorCode,
String inErrorMessage) {
if (inConnection == connection) {
connection = null;
if (basicConnectionListener != null)
basicConnectionListener
.onConnectionFailedConnecting(new Exception(
inErrorMessage));
}
}
private class GetAuthTokenAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
IncomingPhone.this.reallyLogin(result);
}
#Override
protected String doInBackground(String... params) {
try {
capabilityToken = HttpHelper.httpGet(params[0]);
decodedString = capabilityToken.replace("\"", "");
} catch (Exception e) {
e.printStackTrace();
}
return decodedString;
}
}
}
And the activity which opens after getting incoming call via Service class.
public class IncomingPhoneActivity extends Activity implements LoginListener,
BasicConnectionListener, BasicDeviceListener, View.OnClickListener,
CompoundButton.OnCheckedChangeListener,
RadioGroup.OnCheckedChangeListener {
private static final Handler handler = new Handler();
public IncomingPhone phone;
SharedPreferences login_details;
Vibrator vibrator;
private LinearLayout disconnect_btn;
private LinearLayout mainButton;
private ToggleButton speakerButton;
private ToggleButton muteButton;
private EditText logTextBox;
static AlertDialog incomingAlert;
private EditText outgoingTextBox;
private EditText clientNameTextBox;
private Button capabilitesButton;
private CheckBox incomingCheckBox, outgoingCheckBox;
Button call_btn, dis_call_btn, updateButton;
public static String AUTH_PHP_SCRIPT, rating1, rating2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.call_screen);
Intent intent = getIntent();
Operator_id = intent.getStringExtra("operator_id");
gps = new GPSTracker(IncomingPhoneActivity.this);
if (gps.canGetLocation()) {
latitude = gps.getLatitude();
longitude = gps.getLongitude();
} else {
// gps.showSettingsAlert();
latitude = 0.00;
longitude = 0.00;
}
login_details = getSharedPreferences(LOGIN_DETAILS,
Context.MODE_PRIVATE);
if (login_details.contains("twilio_Id")) {
Twilio_id = login_details.getString("twilio_Id", "");
}
AUTH_PHP_SCRIPT = "http://xxxxxxxxxxxxxx/getGenToken?group_id="
+ Operator_id + "&twilio_id=" + Twilio_id + "&latitude="
+ latitude + "&longitude=" + longitude;
disconnect_btn = (LinearLayout) findViewById(R.id.d_call);
mainButton = (LinearLayout) findViewById(R.id.call);
call_btn = (Button) findViewById(R.id.call_btn);
dis_call_btn = (Button) findViewById(R.id.d_call_btn);
mainButton.setOnClickListener(this);
call_btn.setOnClickListener(this);
dis_call_btn.setOnClickListener(this);
disconnect_btn.setOnClickListener(this);
mainButton.setEnabled(false);
call_btn.setEnabled(false);
speakerButton = (ToggleButton) findViewById(R.id.speaker_btn);
speakerButton.setOnCheckedChangeListener(this);
muteButton = (ToggleButton) findViewById(R.id.mute_btn);
muteButton.setOnCheckedChangeListener(this);
logTextBox = (EditText) findViewById(R.id.log_text_box);
outgoingTextBox = (EditText) findViewById(R.id.outgoing_client);
clientNameTextBox = (EditText) findViewById(R.id.client_name);
clientNameTextBox.setText(DEFAULT_CLIENT_NAME);
capabilitesButton = (Button) findViewById(R.id.capabilites_button);
capabilitesButton.setOnClickListener(this);
outgoingCheckBox = (CheckBox) findViewById(R.id.outgoing);
incomingCheckBox = (CheckBox) findViewById(R.id.incoming);
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (MenuItems.Speaker == true) {
speakerButton.setVisibility(View.VISIBLE);
} else {
speakerButton.setVisibility(View.INVISIBLE);
}
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
phone = IncomingPhone.getInstance(getApplicationContext());
phone.setListeners(this, this, this);
phone.login(DEFAULT_CLIENT_NAME, outgoingCheckBox.isChecked(),
incomingCheckBox.isChecked());
}
private void syncMainButton() {
handler.post(new Runnable() {
public void run() {
if (IncomingPhone.decodedString.length() != 0) {
if (phone.isConnected()) {
switch (phone.getConnectionState()) {
default:
mainButton.setClickable(true);
mainButton.setEnabled(true);
call_btn.setEnabled(true);
mainButton.setVisibility(View.VISIBLE);
disconnect_btn.setVisibility(View.GONE);
disconnect_btn.setClickable(false);
break;
case DISCONNECTED:
mainButton.setVisibility(View.VISIBLE);
disconnect_btn.setVisibility(View.GONE);
disconnect_btn.setClickable(false);
break;
case CONNECTED:
mainButton.setVisibility(View.GONE);
disconnect_btn.setVisibility(View.VISIBLE);
disconnect_btn.setClickable(true);
break;
case CONNECTING:
mainButton.setVisibility(View.GONE);
disconnect_btn.setVisibility(View.VISIBLE);
disconnect_btn.setClickable(true);
break;
}
} else if (phone.hasPendingConnection()) {
mainButton.setClickable(true);
mainButton.setEnabled(true);
call_btn.setEnabled(true);
mainButton.setVisibility(View.VISIBLE);
disconnect_btn.setVisibility(View.GONE);
disconnect_btn.setClickable(false);
} else {
mainButton.setVisibility(View.VISIBLE);
disconnect_btn.setVisibility(View.GONE);
disconnect_btn.setClickable(false);
}
/*
* else { Toast.makeText(getApplicationContext(),
* "TRY AGAIN!", Toast.LENGTH_SHORT).show(); }
*/
}
}
});
}
public void onBackPressed() {
phone.disconnect();
incomingAlert = null;
Intent in = new Intent(IncomingPhoneActivity.this, MenuItems.class);
in.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(in);
finish();
}
class TokenTask extends AsyncTask<Void, Void, Void> {
String message;
JSONObject jsonResponse;
int crash_app;
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... params) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet(AUTH_PHP_SCRIPT);
try {
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
if (entity != null) {
IncomingPhone.capabilityToken = EntityUtils
.toString(entity);
IncomingPhone.decodedString = IncomingPhone.capabilityToken
.replace("\"", "");
}
}
} catch (Exception e) {
crash_app = 5;
message = "Something went wrong. Please try again later.";
return null;
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if (status.equals("success")) {
final Handler handler12 = new Handler();
handler12.postDelayed(new Runnable() {
public void run() {
mainButton.setEnabled(true);
call_btn.setEnabled(true);
mainButton
.setBackgroundResource(R.drawable.light_green_connect);
}
}, 3000);
}
if (status.equals("failure")) {
Toast.makeText(getApplicationContext(), message,
Toast.LENGTH_LONG).show();
// mainButton.setBackgroundColor(Color.parseColor("#4ca64c"));
mainButton.setBackgroundResource(R.drawable.dark_green_connect);
mainButton.setEnabled(false);
call_btn.setEnabled(false);
}
}
}
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
#Override
public void onResume() {
super.onResume();
if (phone.handleIncomingIntent(getIntent())) {
showIncomingAlert();
addStatusMessage(R.string.got_incoming);
if (Utils.isNetworkAvailable(IncomingPhoneActivity.this)) {
syncMainButton();
} else {
Toast.makeText(IncomingPhoneActivity.this,
"No internet connection!!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (phone != null) {
phone.setListeners(null, null, null);
phone = null;
}
}
#Override
public void onClick(View view) {
if ((view.getId() == R.id.d_call) || (view.getId() == R.id.d_call_btn)) {
phone.disconnect();
incomingAlert = null;
phone.setSpeakerEnabled(false);
phone.setCallMuted(false);
Intent in = new Intent(IncomingPhoneActivity.this, MenuItems.class);
startActivity(in);
finish();
}
if ((view.getId() == R.id.call) || (view.getId() == R.id.call_btn)) {
} else if (view.getId() == R.id.capabilites_button) {
phone.login(clientNameTextBox.getText().toString(),
outgoingCheckBox.isChecked(), incomingCheckBox.isChecked());
}
}
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (group.getId() == R.id.input_select) {
if (checkedId == R.id.input_number) {
outgoingTextBox.setInputType(InputType.TYPE_CLASS_PHONE);
outgoingTextBox.setHint(R.string.outgoing_number);
} else {
outgoingTextBox.setInputType(InputType.TYPE_CLASS_TEXT);
outgoingTextBox.setHint(R.string.outgoing_client);
}
outgoingTextBox.setText("");
}
}
#Override
public void onCheckedChanged(CompoundButton button, boolean isChecked) {
if (button.getId() == R.id.speaker_btn) {
phone.setSpeakerEnabled(isChecked);
} else if (button.getId() == R.id.mute_btn) {
phone.setCallMuted(isChecked);
}
}
private void addStatusMessage(final String message) {
handler.post(new Runnable() {
#Override
public void run() {
logTextBox.append('-' + message + '\n');
}
});
}
private void addStatusMessage(int stringId) {
addStatusMessage(getString(stringId));
}
private void showIncomingAlert() {
handler.post(new Runnable() {
#Override
public void run() {
if (incomingAlert == null) {
notification = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
r = RingtoneManager.getRingtone(getApplicationContext(),
notification);
am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
switch (am.getRingerMode()) {
case AudioManager.RINGER_MODE_SILENT:
r.play();
break;
case AudioManager.RINGER_MODE_VIBRATE:
long pattern[] = { 0, 500, 200, 300, 500 };
vibrator.vibrate(pattern, 0);
break;
case AudioManager.RINGER_MODE_NORMAL:
r.play();
break;
}
incomingAlert = new AlertDialog.Builder(
IncomingPhoneActivity.this)
.setTitle(R.string.incoming_call)
.setCancelable(false)
.setMessage(R.string.incoming_call_message)
.setPositiveButton(R.string.answer,
new DialogInterface.OnClickListener() {
#Override
public void onClick(
DialogInterface dialog,
int which) {
switch (am.getRingerMode()) {
case AudioManager.RINGER_MODE_SILENT:
r.stop();
break;
case AudioManager.RINGER_MODE_VIBRATE:
vibrator.cancel();
break;
case AudioManager.RINGER_MODE_NORMAL:
r.stop();
break;
}
phone.acceptConnection();
disconnect_btn
.setVisibility(View.VISIBLE);
mainButton.setVisibility(View.GONE);
incomingAlert = null;
}
})
.setNegativeButton(R.string.ignore,
new DialogInterface.OnClickListener() {
#Override
public void onClick(
DialogInterface dialog,
int which) {
switch (am.getRingerMode()) {
case AudioManager.RINGER_MODE_SILENT:
r.stop();
break;
case AudioManager.RINGER_MODE_VIBRATE:
vibrator.cancel();
break;
case AudioManager.RINGER_MODE_NORMAL:
r.stop();
break;
}
phone.ignoreIncomingConnection();
incomingAlert = null;
}
})
.setOnCancelListener(
new DialogInterface.OnCancelListener() {
#Override
public void onCancel(
DialogInterface dialog) {
phone.ignoreIncomingConnection();
}
}).create();
incomingAlert.show();
}
}
});
}
private void hideIncomingAlert() {
handler.post(new Runnable() {
#Override
public void run() {
if (incomingAlert != null) {
incomingAlert.dismiss();
incomingAlert = null;
}
}
});
}
#Override
public void onLoginStarted() {
addStatusMessage(R.string.logging_in);
}
#Override
public void onLoginFinished() {
addStatusMessage(phone.canMakeOutgoing() ? R.string.outgoing_ok
: R.string.no_outgoing_capability);
addStatusMessage(phone.canAcceptIncoming() ? R.string.incoming_ok
: R.string.no_incoming_capability);
syncMainButton();
}
#Override
public void onLoginError(Exception error) {
if (error != null)
addStatusMessage(String.format(getString(R.string.login_error_fmt),
error.getLocalizedMessage()));
else
addStatusMessage(R.string.login_error_unknown);
syncMainButton();
}
#Override
public void onIncomingConnectionDisconnected() {
hideIncomingAlert();
addStatusMessage(R.string.incoming_disconnected);
syncMainButton();
}
#Override
public void onConnectionConnecting() {
addStatusMessage(R.string.attempting_to_connect);
syncMainButton();
}
#Override
public void onConnectionConnected() {
addStatusMessage(R.string.connected);
syncMainButton();
}
#Override
public void onConnectionFailedConnecting(Exception error) {
if (error != null)
addStatusMessage(String.format(
getString(R.string.couldnt_establish_outgoing_fmt),
error.getLocalizedMessage()));
else
addStatusMessage(R.string.couldnt_establish_outgoing);
}
#Override
public void onConnectionDisconnecting() {
addStatusMessage(R.string.disconnect_attempt);
syncMainButton();
}
#Override
public void onConnectionDisconnected() {
addStatusMessage(R.string.disconnected);
syncMainButton();
}
#Override
public void onConnectionFailed(Exception error) {
if (error != null)
addStatusMessage(String.format(
getString(R.string.connection_error_fmt),
error.getLocalizedMessage()));
else
addStatusMessage(R.string.connection_error);
syncMainButton();
}
#Override
public void onDeviceStartedListening() {
addStatusMessage(R.string.device_listening);
}
#Override
public void onDeviceStoppedListening(Exception error) {
if (error != null)
addStatusMessage(String.format(
getString(R.string.device_listening_error_fmt),
error.getLocalizedMessage()));
else
addStatusMessage(R.string.device_not_listening);
}
}
I am working on create a speech recognition service on android and followed previous works from others here. The old version was based on android 5.0.1 and it worked perfectly fine.
However, when I try to move it to android 5.1, it always stops in the onError function in the recognition listener with a error code 7, which means ERROR_NO_MATCH.
I don't know why this happened. is there any difference on using speech recognizer in Android 5.0.1 and 5.1?
If someone can help me, I will be very appreciated. Thanks.
Here is my code:
public class speechrecognitionService extends Service
{
protected static AudioManager mAudioManager;
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));
protected boolean mIsListening;
protected volatile boolean mIsCountDownOn;
private static boolean mIsStreamSolo;
private static String voiceCommand;
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
public static final String TAG = null;
public static final String FEEDBACK = "com.kut.kutcamera";
public static final String COMMAND = "command";
public static final String standardVoiceCommand = "take a photo";
public static final String voiceCommandAlt1 = "take photo";
public static final String voiceCommandAlt2 = "photo";
public static final String voiceCommandAlt3 = "take";
#Override
public void onCreate()
{
super.onCreate();
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());
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());
Toast.makeText(this, "Service is created", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Toast.makeText(this, "Say your command loud and clear please.", Toast.LENGTH_LONG).show();
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
//startListenting(true);
//int result = super.onStartCommand(intent,flags,startId);
return super.onStartCommand(intent, flags, startId);
}
protected static class IncomingHandler extends Handler
{
private WeakReference<speechrecognitionService> mtarget;
IncomingHandler(speechrecognitionService target)
{
mtarget = new WeakReference<speechrecognitionService>(target);
}
#Override
public void handleMessage(Message msg)
{
final speechrecognitionService target = mtarget.get();
switch (msg.what)
{
case MSG_RECOGNIZER_START_LISTENING:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
// turn off beep sound
if (!mIsStreamSolo)
{
mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);
mIsStreamSolo = true;
}
}
if (!target.mIsListening)
{
target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
target.mIsListening = true;
//Log.d(TAG, "message start listening"); //$NON-NLS-1$
}
break;
case MSG_RECOGNIZER_CANCEL:
if (mIsStreamSolo)
{
mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, false);
mIsStreamSolo = false;
}
target.mSpeechRecognizer.cancel();
target.mIsListening = false;
//Log.d(TAG, "message canceled recognizer"); //$NON-NLS-1$
break;
}
}
}
// Count down timer for Jelly Bean work around
protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(30000, 1000)
{
#Override
public void onTick(long millisUntilFinished)
{
// TODO Auto-generated method stub
}
#Override
public void onFinish()
{
mIsCountDownOn = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_CANCEL);
try
{
mServerMessenger.send(message);
message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
}
};
#Override
public void onDestroy()
{
super.onDestroy();
if (mIsCountDownOn)
{
mNoSpeechCountDown.cancel();
}
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
//Toast.makeText(speechrecognitionService.this, "the recognizer is destroyed", Toast.LENGTH_LONG).show();
}
}
protected class SpeechRecognitionListener implements RecognitionListener
{
#Override
public void onBeginningOfSpeech()
{
// speech input will be processed, so there is no need for count down anymore
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
//Log.d(TAG, "onBeginingOfSpeech"); //$NON-NLS-1$
}
#Override
public void onBufferReceived(byte[] buffer)
{
}
#Override
public void onEndOfSpeech()
{
//Log.d(TAG, "onEndOfSpeech"); //$NON-NLS-1$
}
#Override
public void onError(int error)
{
Log.d(TAG, "onError: " + error);
if ((error == SpeechRecognizer.ERROR_NO_MATCH)
|| (error == SpeechRecognizer.ERROR_SPEECH_TIMEOUT)){
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
mIsListening = false;
Log.d("TESTING: SPEECH SERVICE: CALL START", "onError()");
startListening(true);
}
}
#Override
public void onEvent(int eventType, Bundle params)
{
}
#Override
public void onPartialResults(Bundle partialResults)
{
}
#Override
public void onReadyForSpeech(Bundle params)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
mIsCountDownOn = true;
mNoSpeechCountDown.start();
}
//Toast.makeText(speechrecognitionService.this, "Please say your command loudly and clearly", Toast.LENGTH_LONG).show();
}
#Override
public void onResults(Bundle results)
{
//Log.d(TAG, "onResults"); //$NON-NLS-1$
ArrayList strlist = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
voiceCommand = (String) strlist.get(0);
Toast.makeText(speechrecognitionService.this, voiceCommand, Toast.LENGTH_LONG).show();
if (voiceCommand.equals(standardVoiceCommand) || voiceCommand.equals(voiceCommandAlt1)
|| voiceCommand.equals(voiceCommandAlt2)||voiceCommand.equals(voiceCommandAlt3))
publishResults();
else {
Toast.makeText(speechrecognitionService.this, "Say the command again please.", Toast.LENGTH_LONG).show();
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}
}
#Override
public void onRmsChanged(float rmsdB)
{
}
private void startListening(boolean bMuteSound){
Log.d("TESTING: SPEECH SERVICE: startListening()", mIsListening? "true":"false");
if (bMuteSound==true && Build.VERSION.SDK_INT >= 16)//Build.VERSION_CODES.JELLY_BEAN)
{
// turn off beep sound
mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
}
if (!mIsListening)
{
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
//recognizeSpeechDirectly ();
mIsListening = true;
}
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private void publishResults() {
Intent intent = new Intent(FEEDBACK);
intent.putExtra(COMMAND, voiceCommand);
//intent.putExtra(RESULT, result);
sendBroadcast(intent);
}
}