Service still running despite the App is killed - android

I am trying to understand the difference bwtettn STICKY and NOT_STICKY intent of a service in onStartCommand().
I created the MainActivity and the Service shown in the code below. I expected when I press the button mBtnStopApp, the onDestroy() wil be called and then
I should receive this log ** Log.w(TAG, SubTag.bullet("++++++++ SERVICE IS NOT RUNNING ++++++++")); **
because onStartCommand() returns NOT_STICKY intnet which means, when the App is killed, the service should also be stopped
but that never happens.
what happens is, when i press the button mBtnStopApp, the App is finished but i receive the following log:
** Log.w(TAG, SubTag.bullet("++++++++ SERVICE IS RUNNING ++++++++")); **
please let me know why the service is still running despite it returns START_NOT_STICKY and the App was killed
MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private TextView mTv = null;
private Button mBtnStartStickyService = null;
private Button mBtnStartNonStickyService = null;
private Button mBtnStopApp = null;
private Button mBtnStopNonStickyService = null;
private Button mBtnStopStickyService = null;
private ServicesUtils mServiceUtils = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.w(TAG, SubTag.bullet("#onCreate"));
this.mServiceUtils = new ServicesUtils(this);
this.mBtnStartNonStickyService = (Button) findViewById(R.id.btnNonStickyService);
this.mBtnStartStickyService = (Button) findViewById(R.id.btnStickyService);
this.mBtnStopApp = (Button) findViewById(R.id.btnStopApp);
this.mBtnStopNonStickyService = (Button) findViewById(R.id.btnStopNonStickyService);
this.mBtnStopStickyService = (Button) findViewById(R.id.btnStopStickyService);
this.mTv = (TextView) findViewById(R.id.tv);
this.mBtnStartNonStickyService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ComponentName componentName = startService(setRunningStateForService(NonStickyService.class, "start"));
Log.i(TAG, "#mBtnStartNonStickyService: componentName: " + componentName);
}
});
this.mBtnStopNonStickyService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ComponentName componentName = startService(setRunningStateForService(NonStickyService.class, "stop"));
Log.i(TAG, "#mBtnStopNonStickyService: componentName: " + componentName);
}
});
this.mBtnStopApp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
private Intent setRunningStateForService(Class<NonStickyService> serviceClass, String state) {
Log.w(TAG, SubTag.bullet("#setRunningStateForService"));
Intent intent = new Intent(this, serviceClass);
intent.putExtra("running", state);
return intent;
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.w(TAG, SubTag.bullet("#onDestroy"));
if (this.isNonStickyServiceRunning()) {
Log.w(TAG, SubTag.bullet("++++++++ SERVICE IS RUNNING ++++++++"));
} else {
Log.w(TAG, SubTag.bullet("++++++++ SERVICE IS NOT RUNNING ++++++++"));
}
}
private boolean isNonStickyServiceRunning() {
ActivityManager manager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (NonStickyService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
code:
public class NonStickyService extends Service {
private static final String TAG = NonStickyService.class.getSimpleName();
private HeavyWorkRunnable mHeavyWorkRunnable = null;
private String running = null;
#Override
public void onCreate() {
super.onCreate();
Log.w(TAG, SubTag.bullet("#onCreate"));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.w(TAG, SubTag.bullet("#onStartCommand"));
running = intent.getStringExtra("running");
if (running != null && !running.isEmpty() && running.equals("start")) {
this.StartHeavyWorkThread();
}
return Service.START_NOT_STICKY;
}
private void StartHeavyWorkThread() {
Log.w(TAG, SubTag.bullet("#StartHeavyWorkThread"));
this.mHeavyWorkRunnable = new HeavyWorkRunnable();
new Thread(this.mHeavyWorkRunnable).start();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.w(TAG, SubTag.bullet("#onBind"));
return null;
}
#Override
public void onDestroy() {
Log.w(TAG, SubTag.bullet("#onDestroy"));
super.onDestroy();
this.running = "stop";
}
class HeavyWorkRunnable implements Runnable {
int counter = 0;
private Bundle b = null;
public void run() {
Log.w(TAG,SubTag.bullet("#HeavyWorkRunnable"));
while(running.equals("start")) {
b = new Bundle();
b.putInt("what", ++counter);
Log.w(TAG,SubTag.bullet("#HeavyWorkRunnable: counter: " + counter));
Log.w(TAG,SubTag.bullet("#HeavyWorkRunnable: b.getInt('what'): " + b.getInt("what")));
Message msg = handler.obtainMessage();
msg.setData(b);
handler.sendMessage(msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i(TAG,SubTag.bullet("NonStickyService will Stop"));
stopSelf();
}
}
android.os.Handler handler = new android.os.Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int what = msg.getData().getInt("what");
Log.w(TAG,SubTag.bullet("#handler: what: " + what));
}
};
}

Related

Android service not working with bindService()

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

Delay application close and make an send a message

Actually i have a TCP Client that onStart connect to the server and send the device IP and number to it, but now i want that when the application is getting closed ( onDestroy ) delay it for some seconds ( the right time to reopen the connection and send another message ) and send another message in which i'm saying that the device is offline.
I've tryed to do it onDestroy method but probably it's madness and obviously
that didn't worked ( i tryed to do the following stuff onDestroy :
protected void onDestroy() {
new ConnectTask().execute("");
if (client != null) {
client.sendMessage(trm + "OFFLINE");
}
if (client != null) {
client.stopClient();
}
super.onDestroy();
server.onDestroy();
}
Here is my MainActivity code where i evocate the TCP Client and sending start message:
public class MainActivity extends AppCompatActivity {
Server server;
static Client client;
settings Settings;
public static TextView terminale, indr, msg;
TextView log;
static TextView msgServer;
static String ipp;
static String trm;
static DataBaseHandler myDB;
allert Allert;
SharedPreferences prefs;
String s1 = "GAB Tamagnini SRL © 2017 \n" +
"Via Beniamino Disraeli, 17,\n" +
"42124 Reggio Emilia \n" +
"Telefono: 0522 / 38 32 22 \n" +
"Fax: 0522 / 38 32 72 \n" +
"Partita IVA, Codice Fiscale \n" +
"Reg. Impr. di RE 00168780351 \n" +
"Cap. soc. € 50.000,00 i.v. \n" + "" +
"REA n. RE-107440 \n" +
"presso C.C.I.A.A. di Reggio Emilia";
ImageButton settings, helps, allerts, home;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Utils.darkenStatusBar(this, R.color.colorAccent);
server = new Server(this);
myDB = DataBaseHandler.getInstance(this);
msg = (TextView) findViewById(R.id.msg);
log = (TextView) findViewById(R.id.log_avviso);
settings = (ImageButton) findViewById(R.id.impo);
helps = (ImageButton) findViewById(R.id.aiut);
allerts = (ImageButton) findViewById(R.id.msge);
home = (ImageButton) findViewById(R.id.gab);
terminale = (TextView) findViewById(R.id.terminal);
indr = (TextView) findViewById(R.id.indr);
msgServer = (TextView) findViewById(R.id.serverMSG);
final Cursor cursor = myDB.fetchData();
if (cursor.moveToFirst()) {
do {
indr.setText(cursor.getString(1));
terminale.setText(cursor.getString(2));
Client.SERVER_IP = cursor.getString(1);
trm = cursor.getString(2);
} while (cursor.moveToNext());
}
startService(new Intent(MainActivity.this,FinalizingOperationsService.class));
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
ipp = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
startConnection.postDelayed(runnableConnection,5000);
startMessage.postDelayed(runnableMessage,5500);
cursor.close();
server.Parti();
home.setOnClickListener(new View.OnClickListener() {
int counter = 0;
#Override
public void onClick(View view) {
counter++;
if (counter == 10) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setMessage(s1);
builder.show();
counter = 0;
}
}
});
settings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent impostazioni = new Intent(getApplicationContext(), settingsLogin.class);
startActivity(impostazioni);
}
});
helps.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent pgHelp = new Intent(getApplicationContext(), help.class);
startActivity(pgHelp);
}
});
allerts.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Server.count = 0;
SharedPreferences prefs = getSharedPreferences("MY_DATA", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.clear();
editor.apply();
msg.setVisibility(View.INVISIBLE);
Intent pgAlert = new Intent(getApplicationContext(), allert.class);
startActivity(pgAlert);
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
server.onDestroy();
}
public static class ConnectTask extends AsyncTask<String, String, Client> {
#Override
protected Client doInBackground(String... message) {
client = new Client(new Client.OnMessageReceived() {
#Override
public void messageReceived(String message) {
publishProgress(message);
}
});
client.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
msgServer.setTextColor(Color.parseColor("#00FF00"));
msgServer.setText("ONLINE");
Log.d("test", "response " + values[0]);
}
}
static Handler startConnection = new Handler();
static Runnable runnableConnection = new Runnable() {
#Override
public void run() {
new ConnectTask().execute("");
}
};
static Handler startMessage = new Handler();
static Runnable runnableMessage = new Runnable() {
#Override
public void run() {
final Cursor cursor = myDB.fetchData();
if (cursor.moveToFirst()) {
do {
Client.SERVER_IP = cursor.getString(1);
trm = cursor.getString(2);
} while (cursor.moveToNext());
}
if (client != null) {
client.sendMessage(ipp + "#" + trm);
}
}
};
static Handler startMessageClose = new Handler();
static Runnable runnableMessageClose = new Runnable() {
#Override
public void run() {
if (client != null) {
client.sendMessage(trm + "IS OFFLINE");
}
}
};
}
The right command for open the connection is new ConnectTask().execute("");
while i'm sending the message with if (client != null) { client.sendMessage(ipp + "#" + trm); }
FinalizingOperationsService.java code:
public class FinalizingOperationsService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("FOService", "Service Started");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("FOService", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("FOService", "Service Ends");
MainActivity.startConnection.removeCallbacks(MainActivity.runnableConnection);
MainActivity.startConnection.postDelayed(MainActivity.runnableConnection,100);
MainActivity.startMessageClose.removeCallbacks(MainActivity.runnableMessageClose);
MainActivity.startMessageClose.postDelayed(MainActivity.runnableMessageClose,110);
stopSelf();
}
}
Create a new service like this,
public class FinalizingOperationsService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("FOService", "Service Started");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("FOService", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("FOService", "Service Ends");
// write server updation code here
// after completing code perform stopself() to stop this service;
}
}
And define this service in manifest file like this,
<service android:name=". FinalizingOperationsService" android:stopWithTask="false"/>
Finally start service in onCreate method of your main activity
startService(newIntent(getContext(),FinalizingOperationsService.class));
Explanation:
onTaskRemoved() method of the service is called when application is killed or destroyed, so in this method you can perform your final operations to notify server and stop your service after operations done. Hope it will help you.

NullPointerException in `BluetoothAdapter` when startService() is invoked [duplicate]

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
.......
.......
}

Android v <= ICS continuous speech recognition ERROR_NETWORK_TIMEOUT

I created a continuous speech recognition Android app by following this thread, it works perfectly on my Moto G (4.4.2) but for some reason it crashes on 2.3.5 and 2.3.6, I already tried by removing the timer workaround for 4.1 and newer versions and it's the same.
The thing is that it works fine when I say words but when it catches some noise (like a mouse click) it takes like 10 seconds recognizing (or whatever it does after onEndOfSpeech()) and then it throws an ERROR_NETWORK_TIMEOUT.
My problem might be related to this one, but inmy case the error always happens.
I would really appreciate some help here.
Update:
Here is a minimum example which is based on the first link I mention, it still fails to me, additionally I had to add the service to the manifest (<service android:name="com.test.MyService"></service>), the two text views in activity_main.xml and RECORD_AUDIO permission.
MainActivity:
public class MainActivity extends Activity {
protected static final boolean DEBUG = false;
protected static final String TAG = null;
private int mBindFlag;
private MainActivity activityContext;
private Intent speechService;
public static TextView methodText;
public static TextView resultsText;
private static Messenger mServiceMessenger;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
methodText = (TextView) findViewById(R.id.textView1);
resultsText = (TextView) findViewById(R.id.textView2);
activityContext = this;
speechService = new Intent(activityContext, MyService.class);
activityContext.startService(speechService);
mBindFlag = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH ? 0 : Context.BIND_ABOVE_CLIENT;
}
#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;
}
#Override
protected void onStart() {
super.onStart();
bindService(new Intent(this, MyService.class), mServiceConnection, mBindFlag);
}
#Override
protected void onStop()
{
super.onStop();
if (mServiceMessenger != null)
{
unbindService(mServiceConnection);
mServiceMessenger = null;
}
}
private final ServiceConnection mServiceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName name, IBinder service)
{
if (DEBUG) {Log.d(TAG, "onServiceConnected");} //$NON-NLS-1$
mServiceMessenger = new Messenger(service);
sendMessage(MyService.MSG_RECOGNIZER_START_LISTENING);
}
#Override
public void onServiceDisconnected(ComponentName name)
{
if (DEBUG) {Log.d(TAG, "onServiceDisconnected");} //$NON-NLS-1$
mServiceMessenger = null;
}
}; // mServiceConnection
public static void sendMessage(int type){
Message msg = new Message();
msg.what = type;
try
{
mServiceMessenger.send(msg);
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
#Override
protected void onDestroy(){
super.onDestroy();
activityContext.stopService(speechService);
}
}
Service class:
public class MyService 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;
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
private static final String TAG = null;
#Override
public void onCreate()
{
super.onCreate();
MainActivity.methodText.setText("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());
}
protected static class IncomingHandler extends Handler
{
private WeakReference<MyService> mtarget;
IncomingHandler(MyService target)
{
mtarget = new WeakReference<MyService>(target);
}
#Override
public void handleMessage(Message msg)
{
MainActivity.methodText.setText("handleMessage");
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
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(5000, 5000)
{
#Override
public void onTick(long millisUntilFinished)
{
MainActivity.methodText.setText("onTick");
// TODO Auto-generated method stub
}
#Override
public void onFinish()
{
MainActivity.methodText.setText("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();
MainActivity.methodText.setText("onDestroy");
if (mIsCountDownOn)
{
mNoSpeechCountDown.cancel();
}
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
}
}
protected class SpeechRecognitionListener implements RecognitionListener
{
private static final String TAG = "SpeechApp";
#Override
public void onBeginningOfSpeech()
{
MainActivity.methodText.setText("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)
{
MainActivity.methodText.setText("onBufferReceived");
}
#Override
public void onEndOfSpeech()
{
//Log.d(TAG, "onEndOfSpeech"); //$NON-NLS-1$
MainActivity.methodText.setText("onEndOfSpeech");
}
#Override
public void onError(int error)
{
MainActivity.methodText.setText("onError");
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)
{
MainActivity.methodText.setText("onEvent");
}
#Override
public void onPartialResults(Bundle partialResults)
{
MainActivity.methodText.setText("onPartialResults");
}
#Override
public void onReadyForSpeech(Bundle params)
{
MainActivity.methodText.setText("onReadyForSpeech");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
mIsCountDownOn = true;
mNoSpeechCountDown.start();
}
Log.d(TAG, "onReadyForSpeech"); //$NON-NLS-1$
}
#Override
public void onResults(Bundle results)
{
MainActivity.methodText.setText("onResults");
System.out.println(results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION));
MainActivity.resultsText.setText(results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION).toString());
mIsListening = false;
MainActivity.sendMessage(MyService.MSG_RECOGNIZER_START_LISTENING);
}
#Override
public void onRmsChanged(float rmsdB)
{
MainActivity.methodText.setText("onRmsChanged");
}
}
#Override
public IBinder onBind(Intent intent) {
MainActivity.methodText.setText("onBind");
// TODO Auto-generated method stub
Log.d(TAG, "onBind"); //$NON-NLS-1$
return mServerMessenger.getBinder();
}
}

Android remote services: no communication

I am trying to make an Activity run a certain service.
I followed the tutorial here but adapted to my code, and I can't make it work, because when I am invoking the service after starting and binding it to the activity, my Interface (IMyRemoteCallsLoggingService) object does not seem to have the connection properly created.
I have been trying to make this work for several days but I can't seem to get rid of a NullPointException.
Not sure if I made myself clear, in which case here's the code:
public class MtprojectActivity extends Activity {
[...]
private boolean started = false;
private RemoteSmsLoggingServiceConnection SmsLoggingConn = null;
private RemoteCallsLoggingServiceConnection CallsLoggingConn = null;
private IMyRemoteCallsLoggingService callsLoggingService;
private IMyRemoteSmsLoggingService smsLoggingService;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
retrievePreferences();
Button prefBtn = (Button) findViewById(R.id.prefsBtn);
prefBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Explicit intent to call the preferences
Intent preferencesActivity = new Intent(getBaseContext(),
Preferences.class);
startActivity(preferencesActivity);
}
});
}
private void retrievePreferences() {
// Get the xml/preferences.xml preferences
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
callsCheckbox = prefs.getBoolean("callsLogChk", false);
smsCheckbox = prefs.getBoolean("smsLogChk", false);
locationCheckbox = prefs.getBoolean("locationLogChk", false);
if (callsCheckbox) {
startCallsService();
bindCallsService();
try {
invokeCallsService();
} catch (RemoteException e) {
e.printStackTrace();
}
} else {
}
private void startCallsService() {
if (started) {
Toast.makeText(MtprojectActivity.this, "Service already started",
Toast.LENGTH_SHORT).show();
} else {
Intent i = new Intent();
i.setClassName("app.mtproject", "app.mtproject.CallsLoggingService");
startService(i);
started = true;
updateCallsServiceStatus();
Log.d(getClass().getSimpleName(), "startService()");
}
}
private void bindCallsService() {
if (CallsLoggingConn == null) {
CallsLoggingConn = new RemoteCallsLoggingServiceConnection();
Intent i = new Intent();
i.setClassName("app.mtproject", "app.mtproject.CallsLoggingService");
bindService(i, CallsLoggingConn, Context.BIND_AUTO_CREATE);
updateCallsServiceStatus();
Log.d(getClass().getSimpleName(), "bindService()");
} else {
Toast.makeText(MtprojectActivity.this,
"Cannot bind - service already bound", Toast.LENGTH_SHORT)
.show();
}
}
private void invokeCallsService() throws RemoteException {
if (CallsLoggingConn == null) {
Toast.makeText(MtprojectActivity.this,
"Cannot invoke - service not bound", Toast.LENGTH_SHORT)
.show();
} else {
callsLoggingService.dumpCallsLog();
TextView t = (TextView) findViewById(R.id.notApplicable);
t.setText("It worked!");
Log.d(getClass().getSimpleName(), "invokeService()");
}
}
class RemoteCallsLoggingServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName className,
IBinder boundService) {
callsLoggingService = IMyRemoteCallsLoggingService.Stub
.asInterface((IBinder) boundService);
Log.d(getClass().getSimpleName(), "onServiceConnected()");
}
public void onServiceDisconnected(ComponentName className) {
callsLoggingService = null;
updateCallsServiceStatus();
Log.d(getClass().getSimpleName(), "onServiceDisconnected");
}
};
I get a NullPointerException right on callsLoggingService.dumpCallsLog() in the invokeCallsService() method, and I'm not sure what's the problem!
Here's the code of the service:
public class CallsLoggingService extends Service {
String date, duration, type;
private Handler serviceHandler;
private Task myTask = new Task();
#Override
public IBinder onBind(Intent arg0) {
Log.d(getClass().getSimpleName(), "onBind()");
return myRemoteCallsServiceStub;
}
private IMyRemoteCallsLoggingService.Stub myRemoteCallsServiceStub = new IMyRemoteCallsLoggingService.Stub() {
public void dumpCallsLog() throws RemoteException {
CallsLoggingService.this.dumpCallsLog();
}
};
#Override
public void onCreate() {
super.onCreate();
Log.d(getClass().getSimpleName(), "onCreate()");
}
#Override
public void onDestroy() {
super.onDestroy();
serviceHandler.removeCallbacks(myTask);
serviceHandler = null;
Log.d(getClass().getSimpleName(), "onDestroy()");
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
serviceHandler = new Handler();
serviceHandler.postDelayed(myTask, 10L);
Log.d(getClass().getSimpleName(), "onStart()");
}
class Task implements Runnable {
public void run() {
try {
myRemoteCallsServiceStub.dumpCallsLog();
} catch (RemoteException e) {
e.printStackTrace();
}
serviceHandler.postDelayed(this, 86400000L);
Log.i(getClass().getSimpleName(), "Calling the dumpCallsLog");
}
}
private synchronized void dumpCallsLog() {
ContentResolver cr = getContentResolver();
String columns[] = new String[] { CallLog.Calls.DATE,
CallLog.Calls.DURATION, CallLog.Calls.TYPE };
Uri mContacts = CallLog.Calls.CONTENT_URI;
Cursor c = cr.query(mContacts, columns, // Which columns to return
null, // WHERE clause; which rows to return(all rows)
null, // WHERE clause selection arguments (none)
CallLog.Calls.DEFAULT_SORT_ORDER // Order-by clause
// (ascending
// by name)
);
if (c.moveToFirst()) {
do {
// Get the field values
date = c.getString(c.getColumnIndex(CallLog.Calls.DATE));
duration = c
.getString(c.getColumnIndex(CallLog.Calls.DURATION));
type = c.getString(c.getColumnIndex(CallLog.Calls.TYPE));
} while (c.moveToNext());
}
}
}
Thanks a lot everybody for the help!
bindService() is asynchronous. You cannot use callsLoggingService until onServiceConnected() is called.

Categories

Resources