hi again
have bent my head on getting this to work for 3 days now.
The serviceBinder is always NULL when i select picture in Share menu.
I debug this with LogCat, stepping the code.. and see no obvious error. Also the bindService return false. I have a service class but think the hickup is here somewhere.
Please point me in the right direction!
package com.example.ptpp;
public class ServicesDemo extends Activity {
private MyService serviceBinder = null;
private static final String TAG = "ServicesDemo";
boolean mIsBound;
ServiceConnection mConnection = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, MyService.class));
Intent intent = getIntent();
Bundle extras = intent.getExtras();
final String mimeType = intent.getType();
String action = intent.getAction();
mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
serviceBinder = ((MyService.MyBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
serviceBinder = null;
}
};
Intent bindIntent = new Intent(ServicesDemo.this, MyService.class);
bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
if (Intent.ACTION_SEND.equals(action)) {
if (extras.containsKey(Intent.EXTRA_STREAM)) {
Uri uri = (Uri)extras.getParcelable(Intent.EXTRA_STREAM);
try {
if(serviceBinder != null)
// here i call my service to do stuff with the
//picture i got from "share" menu
serviceBinder.addAttachment(mimeType, uri, false);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
} else if (extras.containsKey(Intent.EXTRA_TEXT)) {
return;
}
}
}
void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
}
package com.example.ptpp;
public class MyService extends Service {
private static final String TAG = "MyService";
private final IBinder binder = new MyBinder();
private ServicesDemo callingActivity = null;
public void setActivity(ServicesDemo i) {
callingActivity = i;
}
public IBinder onBind(Intent intent) {
return binder;
}
public class MyBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
public void onCreate() {
}
public void onDestroy() {
}
public void onStart(Intent intent, int startid) {
}
public int onStartCommand(Intent intent, int flags, int startId)
{
return START_STICKY;
}
public void addAttachment(String mimeType, Uri uri, boolean b) throws UnknownHostException, IOException {
}
}
A problem is right here:
bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
Binding to a service is asynchronous. You're not guaranteed to be bound after the call to bindService() returns.
Related
I want to start 2 services at the start of an activity but only the first one starts and the second fails at bindService(). There is no error just when I want to do something with the service it gives me a nullpointer. I also tried to wait to do something but the service never starts.
The 2 services are pretty similar and I just want to know what is wrong with the implementation. I tried to debug and bindservice() function at startSoundmanagerService return 0, what is maybe the root of the problem but I don't know why.
public class SimulationActivity extends AppCompatActivity {
BluetoothService BService;
boolean mBound = false;
SoundManager SService;
boolean sBound = false;
#Override
protected void onStart() {
super.onStart();
if (bluetoothAdapter.isEnabled()) {
setStatusText("Bluetooth on");
}
else {
setStatusText("Bluetooth off");
}
if(!mBound) {
startServer();
}
conStatImageView.setImageResource(R.drawable.connection_off);
if(!sBound){
startSoundManagerService();
}
#Override
protected void onStop() {
super.onStop();
if(mBound) {
unbindService(bConnection);
mBound = false;
}
if(sBound){
unbindService(sConnection);
sBound = false;
}
}
private ServiceConnection bConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
BluetoothService.LocalBinder binder =
(BluetoothService.LocalBinder) service;
BService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
private ServiceConnection sConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
SoundManager.LocalBinder binder = (SoundManager.LocalBinder) service;
SService = binder.getService();
sBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
sBound = false;
}
public void startServer(){
if (bluetoothAdapter == null) {
Log.d("tag","Device doesn't support Bluetooth") ;
}
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
if(bluetoothAdapter.isEnabled()){
startBluetoothservice();
}
}
private void startBluetoothservice(){
Intent intent = new Intent (this,BluetoothService.class);
bindService(intent, bConnection, Context.BIND_AUTO_CREATE);
Log.i(TAG,"Trying to start bluetoothservice");
}
private void startSoundManagerService(){
Intent intent = new Intent (this,SoundManager.class);
bindService(intent, sConnection, Context.BIND_AUTO_CREATE);
Log.i(TAG,"Trying to start soundservice");
}
So how can I implement 2 different services in 1 activity?
Edit Solution: I forgot to register the service in the manifestfile. ;)
I found the solution: I forgot to register the 2nd Service in the manifest. Thats all ;)
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
I am making a game app but the music still keeps playing even when I closed the game. how to stop? and how to change background music once I go to another activity after I clicked a button
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.rysk);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
this is my main activity (PlayActivity.class)
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
I want to change the music when I clicked a button and went to CatActivity
You should have to work with registerReceiver,unregisterReceiver.
May this helps you.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button btn_startservice;
private Button btn_stopservice;
private TextView tv_servicecounter;
ServiceDemo myService;
boolean isBound;
BroadcastReceiver broadcastRec = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int datapassed = intent.getIntExtra("value", 0);
tv_servicecounter.setText(String.valueOf(datapassed));
}
};
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_servicecounter = (TextView) findViewById(R.id.tv_activity_main_count);
btn_startservice = (Button) findViewById(R.id.btn_activity_main_startservices);
btn_stopservice = (Button) findViewById(R.id.btn_activity_main_stopservices);
btn_startservice.setOnClickListener(
new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public void onClick(View v) {
Intent objIntent = new Intent(MainActivity.this, ServiceDemo.class);
if (!isBound) {
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound = true;
startService(objIntent);
} else {
isBound = false;
unbindService(myConnection);
}
}
}
);
btn_stopservice.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent objIntent = new Intent(MainActivity.this, ServiceDemo.class);
if (isBound) {
isBound = false;
unbindService(myConnection);
stopService(objIntent);
} else {
stopService(objIntent);
}
}
}
);
}
#Override
protected void onResume() {
registerReceiver(broadcastRec, new IntentFilter("USER_ACTION"));
super.onResume();
}
#Override
protected void onStop() {
this.unregisterReceiver(broadcastRec);
super.onStop();
}
private ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
myService = ((ServiceDemo.MyLocalBinder) service).getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
#Override
protected void onDestroy() {
super.onDestroy();
if (isBound) {
unbindService(myConnection);
isBound = false;
}
}
}
And ServiceDemo.java
public class ServiceDemo extends Service {
int i;
private MyThread mythread;
public boolean isRunning = false;
Notification notification;
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
mythread = new MyThread();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
if (!isRunning) {
mythread.start();
isRunning = true;
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mythread.interrupt();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
}
public void sendBrodcastMsg(int value) {
Intent intent = new Intent();
intent.setAction("USER_ACTION");
intent.putExtra("value", value);
sendBroadcast(intent);
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
class MyThread extends Thread {
static final long DELAY = 100;
#Override
public void run() {
while (isRunning) {
try {
i++;
Thread.sleep(DELAY);
sendBrodcastMsg(i);
shownotification();
} catch (InterruptedException e) {
isRunning = false;
e.printStackTrace();
}
}
stopSelf();
}
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public void shownotification() {
Intent in = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), in, 0);
notification = new NotificationCompat.Builder(this)
.setContentTitle(String.valueOf(i))
.setContentText(String.valueOf(i))
.setSmallIcon(R.drawable.musicplayer)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
;
startForeground(101, notification);
}
public class MyLocalBinder extends Binder {
ServiceDemo getService() {
return ServiceDemo.this;
}
}
private final IBinder myBinder = new MyLocalBinder();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return myBinder;
}
}
put this two lines in manifest.
<service android:name=".ServiceDemo"
android:enabled="true"/>
You need to stop the player in onPause(). Following code can be used:
#Override
protected void onPause() {
super.onPause();
if (this.isFinishing()){
player.stop();
}
}
Check Android Stop Background Music for more details
for that you should stop the service in the onCreate method of the Activity. Below is the code for it :
stopService(new Intent(MyService.MY_SERVICE));
Best of Luck!
In Your MainActivity , You Should Call stopService() Inside MainActivity
#Override
public void OnPause() {
stopService(svc);
}
I write a intent service to send image to server. I start a service in one activity (in onResume) in onDestroy I stop service. This should works just like this : I take a photo and I have a ArrayList with photo path . And In service I send a photo. I want to send a one photo and when is sending I wait and send another. When I capture photo , confirm (I have 2 photo to send ) and go back to intent (and start service) I see a black screeen.
Service :
public class Sendrer extends Service {
public static boolean running = false;
private Timer timer = new Timer();
private SendPhotoTask asyncSender;
#Override
public void onCreate() {
super.onCreate();
Log.e("tworzenie serwisu ", "tworzenie");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Dziełanie serwisu ", "Dziełanie");
while (! ConfirmDetailsPGOActivity.myList.isEmpty()) {
if(!running) {
asyncSender = new SendPhotoTask();
asyncSender.execute();
}
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
if (running) {
timer.cancel();
asyncSender.cancel(true);
running = false;
}
// asyncSender.cancel(true);
Log.e("service " , "nie działa");
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
class SendPhotoTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
running = true;
InputStream responseInputStream = null;
try {
responseInputStream = HttpConnectionsUtil.sendPhotoRequest(getApplicationContext(), true, ConfirmDetailsPGOActivity.myList.get(0));
} catch (IOException e) {
e.printStackTrace();
}
Log.e("Wysyłanie zdjęcia ", convertStreamToString(responseInputStream));
return convertStreamToString(responseInputStream);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
ConfirmDetailsPGOActivity.myList.remove(0);
}
}
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
And in activity I have this :
#Override
protected void onDestroy() {
super.onDestroy();
stopService();
}
#Override
protected void onResume() {
super.onResume();
startService();
}
private void stopService(){
stopService(myIntent);
}
private void startService(){
myIntent = new Intent(RouteDetailsActivity.this, Sendrer.class);
startService(myIntent);
}
Ok I think that a while is generate a black screen because all the time is check the list. I remove a while and did a check list diffrence and it works I did this:
public class Sendrer extends Service {
public static boolean running = false;
private Timer timer = new Timer();
private SendPhotoTask asyncSender;
private Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
Log.e("tworzenie serwisu ", "tworzenie");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Dziełanie serwisu ", "Dziełanie");
if (!MainActivity.photoListSend.isEmpty()) {
if(!running) {
asyncSender = new SendPhotoTask();
asyncSender.execute();
}
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
if (running) {
timer.cancel();
asyncSender.cancel(true);
running = false;
}
Log.e("service " , "nie działa");
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
class SendPhotoTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
running = true;
InputStream responseInputStream = null;
Log.e("start wysłania " , "start");
try {
responseInputStream = HttpConnectionsUtil.sendPhotoRequest(getApplicationContext(), true, MainActivity.photoListSend.get(0).getName());
} catch (IOException e) {
e.printStackTrace();
}
Log.e("Wysyłanie zdjęcia ", convertStreamToString(responseInputStream));
return convertStreamToString(responseInputStream);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
MainActivity.photoListSend.remove(0);
if(! MainActivity.photoListSend.isEmpty()){
asyncSender = new SendPhotoTask();
asyncSender.execute();
Log.e("Wysyłanie kolejnego " , "zdjecia");
}
}
}
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
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