Immortal Service - java

I need to implement a project, such as chat. We decided to use the Socket.IO library. FCM is not considered. To receive messages in the background using Service. Here:
public class SocketServiceProvider extends Service {
private Socket mSocket;
private final String EVENT_NEW_MESSAGE = "new_message";
private final String LOG_TAG = "SocketServiceProvider";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.e(LOG_TAG, "created()");
realm = Realm.getDefaultInstance();
startForeground(1, new Notification());
if (mSocket == null)
mSocket = BaseApplication.getSocket();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(LOG_TAG, "onStartedCommand()");
startSocket();
return START_STICKY;
}
private void startSocket() {
if (mSocket.connected()){
stopSocket();
}
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(EVENT_NEW_MESSAGE, onNewMessage);
mSocket.connect();
}
private void stopSocket() {
mSocket.off();
mSocket.disconnect();
}
private Emitter.Listener onConnect = new Emitter.Listener() {
#Override
public void call(Object... args) {
new Handler(Looper.getMainLooper()).post(() -> {
if (mSocket.connected()) {
isOnline = true;
Log.e(LOG_TAG, "Connected!");
}
});
}
};
private Emitter.Listener onNewMessage = args -> {
final JSONObject data = (JSONObject) args[0];
final String username;
final String message;
try {
username = data.getString("from");
message = data.getString("message");
} catch (JSONException e) {
Log.e("MainActivity", e.getMessage());
return;
}
Log.e(LOG_TAG, username + " wrote: " + message);
};
#Override
public void onDestroy() {
super.onDestroy();
Log.e(LOG_TAG, "onDestroy()");
stopSocket();
ContextCompat.startForegroundService(this, new Intent(this, SocketServiceProvider.class));
}
}
The only problem is that when the phone goes into Doze mode, messages do not come. Tried to wake up with AlarmManager in onTaskRemoved(), onDestroy(), unsuccessfully.
Even with onDestroy() tried to call BroadcastReceiver, so that it started back my Service, just did not understand why, but its onReceive() method does not work.
Here is my last option, the code that posted. There is I usе startForegroundService. And this option worked, at least not dying. Only in this case, the battery discharges quickly
Googled, Write that using JobIntentService can be implemented, but nowhere described in detail.
Question: How can this be done and how did you implement such tasks? And how can this be achieved with JobIntentService?

Related

Why can't attributes of "custom defined" classes be set (in java (7))?

I'm working on an android project that overrides the code of BroadcastReceiver:
private void registerBroadcastReceiver() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(REQ_ACTION);
intentFilter.addAction(RESPONSE_ACTION);
this.broadcastReceiver = new BroadcastReceiver() {
private Object syncObject;
private WebServer webServer;
public void setSyncObject(Object obj) {
this.syncObject = obj;
}
public void setWebServer(WebServer webServer) {
this.webServer = webServer;
}
#Override
public void onReceive(Context context, Intent intent) {
printIntentInfo(intent);
}
};
// Registers the receiver so that the service will listen for broadcasts
this.registerReceiver(this.broadcastReceiver, intentFilter);
}
where registerBroadcastReceiver is called in onCreate() (in a service).
Whenever I try to call setSyncObject() in broadcast receiver:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Starting web server");
syncObject = new Object();
try {
webServer = new WebServer(getApplicationContext(), PORT_NO);
broadcastReceiver.setSyncObject(syncObject); // <= ERROR HERE
} catch (IOException e) {
Log.d(TAG, "\nCouldn't start web server on port " + PORT_NO + "\n");
e.printStackTrace();
}
...
}
I get an error:
Cannot resolve method setSyncObject in BroadcastReceiver
The answer seems obvious, just create a new receiver that extends bc and add the methods there. But I'm curious as to why the methods can't be seen(, unless they're resolved at compile time).
Even when creating a separate object:
public class CustomBroadcastReceiver extends BroadcastReceiver {
private Object syncObject;
private WebServer webServer;
public void setSyncObject(Object obj) {
this.syncObject = obj;
}
public void setWebServer(WebServer webServer) {
this.webServer = webServer;
}
#Override
public void onReceive(Context context, Intent intent) {
printIntentInfo(intent);
}
}
the attribute has to be cast to its type
((CustomBroadcastReceiver)broadcastReceiver).setSyncObject(syncObject);

How to check queue length of android Messenger

I had a android service, it communication with client with Messenger (because the service have to execute the command serially so chose the messenger), messenger will queue the tasks if there are multiple requests at the same time. The client want to check the server queue length to decide whether to line up, so how to check the queue length of messenger?
Exp code:
public class MessengerService extends Service {
private static final String TAG = "Serial Service";
private static final int MSG_EXECMD = 0x1;
private Messenger mMessenger;
private HandlerThread mHandlerThread;
private Handler mHandler;
private Message mmessageToClient;
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return mMessenger.getBinder();
}
#Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "onUnbind pid=" + android.os.Process.myPid());
return super.onUnbind(intent);
}
#Override
public void onCreate() {
mHandlerThread = new HandlerThread("serial-work-thread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper()) {
#Override
public void handleMessage(Message msgfromClient) {
Message msgToClient = Message.obtain(msgfromClient);
mmessageToClient = Message.obtain(msgfromClient);
switch (msgfromClient.what) {
case MSG_EXECMD:
msgToClient.what = MSG_EXECMD;
try {
//takes time here about 3s
Thread.sleep(3000);
msgToClient.arg1 = 0;
msgToClient.arg2 = msgfromClient.arg2;
msgfromClient.replyTo.send(msgToClient);
} catch (Exception e) {
Log.e(TAG, "Error:" + e.getMessage());
}
break;
}
}
};
mMessenger = new Messenger(mHandler);
super.onCreate();
}
}

How to pass a String from a UDP Listening Service to the MainActivity?

I have a service listening for UDP packets that is bound to my MainActivity (which is the only activity in the app). The service runs on its own thread and I can see the UDP messages as well as the parsed messages in logcat. I created a setParsedMessage() and a public getParsedMessage() in order to get the parsed string and send it to my main activity in order to change a TextView and an ImageView depending on what the parsed message is, however it does not appear to be retrieving the String for some reason. I read about this method on the Developer.Android website, however I've also seen something about using Handler to do this instead. Here is my code:
MainActivity:
public class MainActivity extends Activity {
AlertAssignments mAlertAssignments;
Button startListeningButton;
boolean started;
int counter;
boolean mBound = false;
Context context;
ListenerService mListenerService;
TextView mTextView;
TextView mBlinkView;
ImageView mImageView;
private StartListening _StartListeningTask;
String messageFromService = "";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//start listener service
Intent listenerServiceIntent = new Intent(MainActivity.this, ListenerService.class);
this.bindService(listenerServiceIntent, mConnection, Context.BIND_AUTO_CREATE);
mImageView = (ImageView) findViewById(R.id.image_view);
mTextView = (TextView) findViewById(R.id.alert_text);
mBlinkView = (TextView) findViewById(R.id.blinking_text);
Animation mAnimation = new AlphaAnimation(0.0f, 1.0f);
mAnimation.setDuration(50);
mAnimation.setStartOffset(20);
mAnimation.setRepeatCount(Animation.INFINITE);
mAnimation.setRepeatMode(Animation.REVERSE);
mBlinkView.startAnimation(mAnimation); //animation value
mAlertAssignments = new AlertAssignments();
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
ListenerService.LocalBinder binder = (ListenerService.LocalBinder) service;
mListenerService = binder.getService();
mBound = true;
if(mBound) {
Log.e("UDP", "Service has been bound successfully");
}
else {
Log.e("UDP", "Service has not been bound");
}
readFromService();
}
#Override
public void onServiceDisconnected(ComponentName name) {
mBound = false;
}
};
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onStop() {
super.onStop();
//unbind from service
if(mBound) {
this.unbindService(mConnection);
mBound = false;
}
}
private void readFromService() {
try {
Integer parsedMessage = Integer.valueOf(mListenerService.getParsedMessage());
mImageView.setImageResource(mAlertAssignments.alarmImages[parsedMessage]);
if(parsedMessage >= 10 && parsedMessage <= 19 && parsedMessage != 0) {
mTextView.setText(mAlertAssignments.alertTextMessages[parsedMessage]);
} else {
mBlinkView.setText(mAlertAssignments.alertTextMessages[parsedMessage]);
}
} catch(NumberFormatException e) {
e.printStackTrace();
}
}
}
I had read that using the public getter like this:
Integer parsedMessage = Integer.valueOf(mListenerService.getParsedMessage());
would allow me to access the string value of mListenerService.getParsedMessage, however I'm guessing that may only work for started services, not bound services.
AlertAssignments is a simple enumeration that uses ordinal arrays to bind images and Strings to values, so mImageView.setImageResource(mAlertAssignments.alarmImages[parsedMessage]) would set the ImageView to an image. Finally, here is the Service:
public class ListenerService extends Service{
public String the_alarm_S;
public String parsedMessage = "";
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
ListenerService getService() {
return ListenerService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
DatagramSocket socket;
Thread UDPBroadcastThread;
void startListenForUDPBroadcast() {
UDPBroadcastThread = new Thread(new Runnable() {
public void run() {
try {
while (shouldRestartSocketListen) {
try {
socket = new DatagramSocket(12001);
socket.setReuseAddress(true);
String message = "";
byte[] recvBuf = new byte[1024];
DatagramPacket packet = new DatagramPacket(recvBuf, 1024);
Log.e("UDP", "Waiting for UDP broadcast");
try {
socket.receive(packet);
Log.e("UDP", "Received Packet");
} catch (IOException e) {
e.printStackTrace();
}
message = new String(packet.getData());
Log.e("UDP", "Got UDB broadcast message: " + message);
setParsedMessage(message);
if(socket != null) {
socket.close();
}
} catch (SocketException e) {
e.printStackTrace();
}
}
//if (!shouldListenForUDPBroadcast) throw new ThreadDeath();
} catch (Exception e) {
Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage());
}
}
});
UDPBroadcastThread.start();
}
private Boolean shouldRestartSocketListen = true;
private void setParsedMessage(String messageContents) {
the_alarm_S = messageContents;
String parseMessage[] = the_alarm_S.split("!!!");
Log.e("UDP", "Parsed message with value " + parseMessage[1]);
parsedMessage = parseMessage[1];
}
public String getParsedMessage() {
return parsedMessage;
}
private void stopListen() {
shouldRestartSocketListen = false;
if(socket != null) {
socket.close();
}
}
#Override
public void onCreate() {
startListenForUDPBroadcast();
}
#Override
public void onDestroy() {
stopListen();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
shouldRestartSocketListen = true;
startListenForUDPBroadcast();
Log.i("UDP", "Service started");
return START_STICKY;
}
}
Can someone give me the simplest method of getting the String from the service to the main activity, or if I already have it, where I am going wrong in using it? I would like to avoid having to rewrite my Service as an IntentService unless it's absolutely necessary to do so since this is a relatively simple object to pass to MainActivity
Thanks
You could try subscribing to the service. What I mean is pass some interface that the service calls to notify the activity about changes, here's an example I just tested:
A Subscriber interface
public interface ServiceSubscriber {
void messageCallback(String message);
}
Subscribe to the service using the Subscriber
public class TestService extends Service {
ArrayList<ServiceSubscriber> subscribers = new ArrayList<>();
private TestBinder testBinder = new TestBinder();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(){
#Override
public void run() {
while(true){
//this is where you are receiving UDP packets
doStuff();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return testBinder;
}
private void doStuff() {
System.out.println("Service is doing stuff!");
//loop through your subscribers and notify them of your changes
//a loop here isn't very costly, if there aren't many subscribers
for (ServiceSubscriber subscriber : subscribers) {
subscriber.messageCallback("I'm doing stuff");
}
}
public class TestBinder extends Binder {
public TestService getService() {
return TestService.this;
}
}
public void subscribeToMessages(ServiceSubscriber subscriber) {
subscribers.add(subscriber);
}
public void unSubscribeToMessages(ServiceSubscriber subscriber) {
subscribers.remove(subscriber);
}
}
Now for the usual Binding Activity, where you define what you need to do with the Message Callback:
public class MainActivity extends AppCompatActivity {
private TestService testService;
private Subscriber subscriber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
bindService(new Intent(this, TestService.class),serviceConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
testService = ((TestService.TestBinder)service).getService();
subscriber = new ServiceSubscriber() {
#Override
public void messageCallback(String message) {
//I'm just printing out the message received
//Be careful if you need to do UI stuff to use a
//Handler
System.out.println(message);
}
}
testService.subscribeToMessages(subscriber );
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
};
}
Of course don't forget to unsubscribe on destroy.
Updating UI often doesn't break your app if you do it by using a handler
//activity fields
Handler handler
//in activity constructor
handler = new Handler();
//update UI by calling
handler.post(new Runnable(){
#Override
public void run(){
//update the UI here
}
EDIT: I forgot to keep a reference of the subscriber, to unsubscribe later. Changed from anonymous instance to a field.
Make below method to your sevice class:
private void sendMessage() {
Intent intent = new Intent("message");
intent.putExtra("message", your_message);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
And put the below code in your activity class:
#Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this)
.registerReceiver(mMessageReceiver,
new IntentFilter("message"));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String yourMessage = intent.getIntExtra("message",-1);
}
};
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(mMessageReceiver);
super.onPause();
}
Note: -1 is for default value

Smack Android, creating a service to receive messages

I'm doing a chat with the library smack Android 4.1.4. This library uses the XMPP protocol. To receive messages, you must authenticate to a server (for example openfire) and login using XMPPCONNECTION. All of this is quite simple if performed when the application starts. The problem comes when you have to receive messages when the application is closed. I tried to use an "Android service" to maintain this alive the connection between the client and the server. (In this case I did) but I do not think is the best method. Also because Android through service when the phone is switched off and on again the service does not restart by itself, and messages received while the phone was switched off will be lost. I attach the code Android. Do you have any advice ?. It would be useful to know how to do other chat applications such as whatsapp, badoo, facebook, telegram, etc ..
public class ServizioMessaggi extends Service {
public static final int NOTIFICATION_ID = 1;
static ChatManager chatmanager;
public static AbstractXMPPConnection connessione;
ConnettiServizio connetti;
MySQLiteHelper db;
String SharedPreferences = "Whisper";
public ServizioMessaggi() {
super();
}
#Override
public void onCreate() {
SharedPreferences sharedPref = getSharedPreferences(SharedPreferences, Context.MODE_PRIVATE);
connetti = new ConnettiServizio();
connetti.execute(sharedPref.getString("username",""),sharedPref.getString("password",""),"vps214588.ovh.net");
db = new MySQLiteHelper(this);
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class ConnettiServizio extends AsyncTask<String,String,String> {
public AbstractXMPPConnection con;
#Override
protected String doInBackground(String... strings) {
con = new XMPPTCPConnection(strings[0],strings[1],strings[2]);
try {
con.connect();
con.login();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XMPPException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
connessione = con;
con.addConnectionListener(new ConnectionListener() {
#Override
public void connected(XMPPConnection connection) {
System.out.println("connected");
}
#Override
public void authenticated(XMPPConnection connection, boolean resumed) {
System.out.println("autenticathed");
}
#Override
public void connectionClosed() {
System.out.println("Connection Close");
}
#Override
public void connectionClosedOnError(Exception e) {
System.out.println("Connection Close whith error");
}
#Override
public void reconnectionSuccessful() {
System.out.println("reconnection ");
}
#Override
public void reconnectingIn(int seconds) {
}
#Override
public void reconnectionFailed(Exception e) {
System.out.println("recconnection failed");
}
});
ascolta();
}
}
private void ascolta() {
chatmanager = ChatManager.getInstanceFor(connetti.con);
chatmanager.addChatListener(new ChatManagerListener() {
public void chatCreated(final Chat chat, final boolean createdLocally) {
Log.i("chat creata", "****************");
chat.addMessageListener(new ChatMessageListener() {
public void processMessage(Chat chat, Message message) {
Log.i("messaggio arrivato", "****************");
//JOptionPane.showMessageDialog(null, "Rec: For " + chat.getParticipant() + " from " + message.getFrom() + "\n" + message.getBody());
String sender = message.getFrom();
System.out.println("Received message: " + (message != null ? message.getBody() : "NULL"));
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(ServizioMessaggi.this, Chat.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(ServizioMessaggi.this, 0,
notificationIntent, 0);
// scelta suoneria per notifica
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mBuilder =
(NotificationCompat.Builder) new NotificationCompat.Builder(ServizioMessaggi.this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setColor(Color.argb(0,0,176,255))
.setTicker("Nuovo messaggio da " + message.getFrom())
.setContentTitle(sender.substring(0,sender.indexOf("#")))
.setContentText(message.getBody())
.setContentIntent(intent)
.setSound(sound);
// effettua la notifica
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
SimpleDateFormat s = new SimpleDateFormat("hh:mm:ss");
String ora = s.format(new Date());
//aggiungo il messaggio al database
Messaggio ms = new Messaggio();
ms.setUsername(message.getFrom().substring(0, message.getFrom().indexOf("/")));
ms.setIsmy("no");
ms.setTimestamp(ora);
ms.setMessaggio(message.getBody());
db.addMessaggio(ms);
if(ChatActivity.isvisible){
((Activity)ChatActivity.c).runOnUiThread(new Runnable() {
#Override
public void run() {
ChatActivity.updateListMessaggi();
}
});
} else {
}
}
});
}
});
}
}
Actually i am not solve yet this kind of stuff. But, i do way to change BackgroundService to ForegroundService for this case. Remember this will not solve any Android devices.
Unlike whatsapp, telegram, fb. They play in Native C (NDK) to force OS which permit app to run in backgroundservice.
You can dive in Telegram Source Code for this issue.
when app is closed we cannot maintain connection.
you have to receive message via push notification. And re connect it with server then ...

SpeechRecognitionService with word recognition

The title it's not clear i think. In my project i want a service that runs in background and when the user says "hello phone" or some word/phrase my app starts to recognize the voice. Actually it "works" but not in right way... I have a service and this service detect the voice.
public class SpeechActivationService 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 String TAG = "Icaro";
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
private int mBindFlag;
private Messenger mServiceMessenger;
#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());
//mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}
protected static class IncomingHandler extends Handler
{
private WeakReference<SpeechActivationService> mtarget;
IncomingHandler(SpeechActivationService target)
{
mtarget = new WeakReference<SpeechActivationService>(target);
}
#Override
public void handleMessage(Message msg)
{
final SpeechActivationService target = mtarget.get();
switch (msg.what)
{
case MSG_RECOGNIZER_START_LISTENING:
if (Build.VERSION.SDK_INT >= 16);//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(TAG, "message start listening"); //$NON-NLS-1$
}
break;
case MSG_RECOGNIZER_CANCEL:
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)
{
// 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 int onStartCommand (Intent intent, int flags, int startId)
{
//mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
try
{
Message msg = new Message();
msg.what = MSG_RECOGNIZER_START_LISTENING;
mServerMessenger.send(msg);
}
catch (RemoteException e)
{
}
return START_NOT_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
if (mIsCountDownOn)
{
mNoSpeechCountDown.cancel();
}
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
}
}
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)
{
String sTest = "";
}
#Override
public void onEndOfSpeech()
{
Log.d("TESTING: SPEECH SERVICE", "onEndOfSpeech"); //$NON-NLS-1$
}
#Override
public void onError(int error)
{
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
try
{
mIsListening = false;
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 >= 16);//Build.VERSION_CODES.JELLY_BEAN)
{
mIsCountDownOn = true;
mNoSpeechCountDown.start();
mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
}
Log.d("TESTING: SPEECH SERVICE", "onReadyForSpeech"); //$NON-NLS-1$
}
#Override
public void onResults(Bundle results)
{
ArrayList<String> data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
Log.d(TAG, (String) data.get(0));
//mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
mIsListening = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
try
{
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
Log.d(TAG, "onResults"); //$NON-NLS-1$
}
#Override
public void onRmsChanged(float rmsdB)
{
}
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
And i start service in my MainActivity just to try:
Intent i = new Intent(context, SpeechActivationService.class);
startService(i);
It detect the voice input...and TOO MUCH!!! Every time it detects something it's a "bipbip". Too many bips!! It's frustrating.. I only want that it starts when i say "hello phone" or "start" or a specific word!! I try to look at this https://github.com/gast-lib/gast-lib/blob/master/library/src/root/gast/speech/activation/WordActivator.java but really i don't know how use this library. I try see this question onCreate of android service not called but i not understand exactly what i have to do.. Anyway, i already import the gast library.. I only need to know how use it. Anyone can help me step by step? Thanks
Use setStreamSolo(AudioManager.STREAM_VOICE_CALL, true) instead of setStreamMute. Remember to add setStreamSolo(AudioManager.STREAM_VOICE_CALL, false) in case MSG_RECOGNIZER_CANCEL

Categories

Resources