onBeaconServiceConnect not called - android

As before, I work with Android Beacon Library,
It already worked and I can found out beacon via BLE - Bluetooth low energy,
But now, after updated to latest version of library, now method onBeaconServiceConnect() not run anymore.
Please tell me what I need to do to make it works,
Thank you,
p/s : Code :
Manifest.xml
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<service
android:name="org.altbeacon.beacon.service.BeaconService"
android:enabled="true"
android:isolatedProcess="false"
android:label="beacon" />
<service
android:name="org.altbeacon.beacon.BeaconIntentProcessor"
android:enabled="true" />
Java
public class FoundBeaconFragment extends Fragment
implements BeaconConsumer {
#Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
return false;
}
#Override
public Context getApplicationContext() {
return getActivity();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_found_beacon, null);
// Set adapter
foundBeaconAdapter = new FoundBeaconAdapter(
getActivity(),
R.layout.simple_list_item_found_beacon,
mAlFoundBeacon);
mLvFoundBeacon.setAdapter(foundBeaconAdapter);
// Register Scan beacons feature
register();
return v;
}
#Override
public void onDestroy() {
super.onDestroy();
try {
// Unbind scan beacon progress
if (beaconManager != null)
beaconManager.unbind(this);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void unbindService(ServiceConnection serviceConnection) {
}
// CUSTOM METHODS
private void register() {
beaconManager = BeaconManager.getInstanceForApplication(getActivity());
// To detect proprietary beacons, you must add a line like below corresponding to your beacon
// type. Do a web search for "setBeaconLayout" to get the proper expression.
try {
// todo
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
} catch (Exception e) {
e.printStackTrace();
}
// CAN SEE THIS LOG CAT, NO EXCEPTION
Log.i("", "Register Service");
beaconManager.bind(this);
}
#Override
public void onBeaconServiceConnect() {
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(
Collection<org.altbeacon.beacon.Beacon> beacons, Region region) {
Log.i("", "IS_SCAN_BEACON " + FoundBeaconFragment.IS_SCAN_BEACON);
if (FoundBeaconFragment.IS_SCAN_BEACON) {
Log.i("", "Found " + beacons.size() + " beacon!");
if (beacons.size() > 0) {
/**
* Begin transfer data
*/
for (final org.altbeacon.beacon.Beacon beacon : beacons) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
getDataViaBLE(getActivity(), beacon.getId1() + "",
beacon.getId2() + "", beacon.getId3() + "");
}
});
}
}
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(
new Region(Constant.UUID, null, null, null));
} catch (RemoteException e) {
e.printStackTrace();
}
}
public static String UUID = "01122334-4556-6778-899a-abbccddeeff0";
ANSWER
Since I used Fragment not Activity as sample codes from the library.
So I need do these changes :
#Override
public Context getApplicationContext() {
return getActivity().getApplicationContext();
}
#Override
public void unbindService(ServiceConnection serviceConnection) {
getActivity().unbindService(serviceConnection);
}
#Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
return getActivity().bindService(intent, serviceConnection, i);
}

If you are implementing the BeaconConsumer interface in a Fragment (and not an Activity, Service or Application instance), you need to chain all of the methods. Like this:
#Override
public Context getApplicationContext() {
return getActivity().getApplicationContext();
}
#Override
public void unbindService(ServiceConnection serviceConnection) {
getActivity().unbindService(serviceConnection);
}
#Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
return getActivity().bindService(intent, serviceConnection, i);
}

I am not sure.before few days ,this beacon code is working for me.please check.if any issue ,i will send whole my code.
try this one:
beaconManager.startRangingBeaconsInRegion(new Region("myBeaons", Identifier.parse(UUID), null, null));
instead of this line in your code.
beaconManager.startRangingBeaconsInRegion(
new Region(Constant.UUID, null, null, null));

this Code is working for me.please try this code:
Create Application Class:
public class BeaconReferenceApplication extends Application implements BootstrapNotifier {
private BackgroundPowerSaver backgroundPowerSaver;
private boolean haveDetectedBeaconsSinceBoot = false;
private MonitoringActivity monitoringActivity = null;
private String UUID = "23542266-18D1-4FE4-B4A1-23F8195B9D39";
private static final String TAG = ".MyApplicationName";
private RegionBootstrap regionBootstrap;
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "App started up");
BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
// To detect proprietary beacons, you must add a line like below corresponding to your beacon
// type. Do a web search for "setBeaconLayout" to get the proper expression.
// beaconManager.getBeaconParsers().add(new BeaconParser().
// setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
// wake up the app when any beacon is seen (you can specify specific id filers in the parameters below)
Region region = new Region("com.example.myapp.boostrapRegion", null, null, null);
regionBootstrap = new RegionBootstrap(this, region);
}
#Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
// Don't care
}
#Override
public void didEnterRegion(Region arg0) {
Log.d(TAG, "Got a didEnterRegion call");
// This call to disable will make it so the activity below only gets launched the first time a beacon is seen (until the next time the app is launched)
// if you want the Activity to launch every single time beacons come into view, remove this call.
regionBootstrap.disable();
Intent intent = new Intent(this, MainActivity.class);
// IMPORTANT: in the AndroidManifest.xml definition of this activity, you must set android:launchMode="singleInstance" or you will get two instances
// created when a user launches the activity manually and it gets launched from here.
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
}
#Override
public void didExitRegion(Region arg0) {
// Don't care
}
}
Activity Class
public class MainActivity extends Activity implements BeaconConsumer {
public static final String TAG = "BeaconsEverywhere";
private BeaconManager beaconManager;
private String UUID = "23542266-18D1-4FE4-B4A1-23F8195B9D39";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser()
.setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
beaconManager.bind(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
beaconManager.unbind(this);
}
#Override
public void onBeaconServiceConnect() {
final Region region = new Region("myBeaons", Identifier.parse(UUID), null, null);
beaconManager.setMonitorNotifier(new MonitorNotifier() {
#Override
public void didEnterRegion(Region region) {
try {
Log.d(TAG, "didEnterRegion");
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void didExitRegion(Region region) {
try {
Log.d(TAG, "didExitRegion");
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void didDetermineStateForRegion(int i, Region region) {
}
});
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
for (Beacon oneBeacon : beacons) {
Log.d(TAG, "distance: " + oneBeacon.getDistance() + " id:" + oneBeacon.getId1() + "/" + oneBeacon.getId2() + "/" + oneBeacon.getId3());
}
}
});
try {
beaconManager.startMonitoringBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}

Related

sometimes both enter and exit method called when user in range

i am new to android developing. i am using Altbeacon lib to detect beacons and i have kontakt.io beacons. i am trying to create an app which is notify user when they enter in Region but when user first time enter the didEnterRegion() method perfectly but after some times didExitRegion() region called even when user in same Region. i am facing some problem when user lost the region and come again it takes too much time to detect user again.
public class MainActivity extends AppCompatActivity implements BeaconConsumer {
protected static final String TAG = "MonitoringActivity";
private BeaconManager beaconManager;
Region region;
String Eddystone_Namespace_ID="f7826da6bc5b71e0893e";
Button next;
Handler ha=new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beaconManager = BeaconManager.getInstanceForApplication(this);
next=findViewById(R.id.next);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,TestingBeacon.class);
startActivity(intent);
}
});
beaconManager.setEnableScheduledScanJobs(false);
beaconManager.setForegroundScanPeriod(2000);
beaconManager.setForegroundBetweenScanPeriod(0);
beaconManager.setBackgroundScanPeriod(200);
beaconManager.setBackgroundBetweenScanPeriod(0);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
beaconManager.bind(this);
}
#Override
protected void onResume() {
super.onResume();
region=new Region("myRangingUniqueId", Identifier.parse(Eddystone_Namespace_ID), null, null);
try {
beaconManager.startMonitoringBeaconsInRegion(region);
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
}
}
#Override
public void onBeaconServiceConnect() {
beaconManager.addMonitorNotifier(new MonitorNotifier() {
#Override
public void didEnterRegion(Region region) {
Log.e(TAG, "I just saw an beacon for the first time!");
Toast.makeText(MainActivity.this,"Near By To Beacon",Toast.LENGTH_SHORT).show();
}
#Override
public void didExitRegion(Region region) {
Log.e(TAG, "I no longer see an beacon");
Toast.makeText(MainActivity.this,"Beacon Range Lost",Toast.LENGTH_SHORT).show();
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void didDetermineStateForRegion(int state, Region region) {
Log.e(TAG, "I have just switched from seeing/not seeing beacons: "+state);
}
});
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
for (Beacon beacon : beacons) {
Log.e("MainActivity", "I see a beacon that is about "+beacon.getDistance()+" meters away.");
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
beaconManager.unbind(this);
}
i want user notify when they in region and same with when exit in region.

Is any issue scan long period of Android AltBeacon Library?

I use altbeacon library to scan BLE Kit.
When I use method like this,
#Override
public void onBeaconServiceConnect() {
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
Log.d("BeaconInfo","" + collection.size);
}
});
try {
beaconManager.startRangingBeaconsInRegion(defaultRegion);
} catch (RemoteException e) {
e.printStackTrace();
}
}
It worked normally at first time, but after five minutes or long, It occurs error like, like when I select button to load video file or image file from server, or I reload that activity which is scan BLE Kit, It returns collection size is 0.
I did when do another thing, I should use this method.
private void stopBeacon(){
beaconManager.unbind(this);
}
When I start the App first time, it returns collection size normally but I stay about 3minutues, occurs error.
I don't understand of it
If you know about of it, please help me
BeaconManager beaconManager;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mainr);
beaconManager = BeaconManager.getInstanceForApplication(this);
button.setOnClickLister(new View.OnClickListener() {
#Override
public void onClick(View v) {
moveList();
}
});
startBeacon();
}
#Override
public void onBeaconServiceConnect() {
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
Log.d("BeaconInfo","" + collection.size());
}
});
try {
beaconManager.startRangingBeaconsInRegion(defaultRegion);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void startBeacon(){
beaconManager.bind(this);
}
private void stopBeacon(){
beaconManager.unbind(this);
}
public void moveList(){
stopBeacon();
Intent intent = new Intent(this,ListActivity.class);
startActivity(intent);
finish();
}

Altbeacon library with android version 6

I'm updating the altbeacon library to the latest 2.9.1 but I don't get any beacon when I range for it, this is using android 6.0.1.
public class BeaconService extends IntentService implements BeaconConsumer {
private BeaconManager mBeaconManager;
private static ArrayList<Beacon> beaconsList=new ArrayList<Beacon>();
private Region region=new Region("rid", null, null, null);
private static final String LOGTAG = "BeaconService";
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public BeaconService() {
super(Constants.BEACON_SERVICE);
}
#Override
public void onBeaconServiceConnect() {
try {
mBeaconManager.startRangingBeaconsInRegion(region);
mBeaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Intent localIntent =new Intent(Constants.BEACON_ACTION);
beaconsList.clear();
beaconsList.addAll(beacons);
Collections.sort(beaconsList,new Comparator<Beacon>() {
#Override
public int compare(Beacon lhs, Beacon rhs) {
return Double.compare(lhs.getDistance(), rhs.getDistance());
}
});
localIntent.putParcelableArrayListExtra(Constants.BEACON_LIST,beaconsList);
LocalBroadcastManager.getInstance(BeaconService.this).sendBroadcast(localIntent);
}
});
} catch (RemoteException e) {
Log.e(LOGTAG,"Error BeaconService",e);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
mBeaconManager = BeaconManager.getInstanceForApplication(this);
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
mBeaconManager.bind(this);
}
#Override
public void onDestroy() {
super.onDestroy();
mBeaconManager.unbind(this);
}
/**
* Stop Scanning
*/
public void stopRanging(){
try {
mBeaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
Log.e(LOGTAG,"Error BeaconService - StopRanging",e);
}
}
/**
* Start Scanning
*/
public void startRanging(){
try {
mBeaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
Log.e(LOGTAG,"Error BeaconService - StartRanging",e);
}
}
#Override
public IBinder onBind(Intent intent) {
return new LocalBinder();
}
#Override
protected void onHandleIntent(Intent intent) {
}
public class LocalBinder extends Binder {
public BeaconService getService() {
return BeaconService.this;
}
}
I did try changing to monitoring and the same result, also I did try adding more layouts but I don't get any beacons on the list
looks like you need to add the permission at runtime, I did fix it by doing this
#Override
public void initialize(final CordovaInterface cordova, CordovaWebView webView) {
Log.i(LOGTAG, "initialize");
context = webView.getContext();
beaconServiceIntent = new Intent(context, BeaconService.class);
context.bindService(beaconServiceIntent, serviceBeaconConnection, Service.BIND_AUTO_CREATE);
BeaconReceiver beaconReciever = new BeaconReceiver();
IntentFilter intentFilter = new IntentFilter(Constants.BEACON_ACTION);
LocalBroadcastManager.getInstance(context).registerReceiver(beaconReciever, intentFilter);
mainActiviy = (Activity) context;
checkPermission();
}
#TargetApi(Build.VERSION_CODES.M)
private void checkPermission() {
if(this.mainActiviy.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){
AlertDialog.Builder builder = new AlertDialog.Builder(((Activity)context));
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect beacons.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
mainActiviy.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}

Ranging beacons stops when new Android Intent is open

I have created an Application, which range beacons and calculates the position when more than three beacons are ranged.
The Problem is, that when I want to show the position, it's necessary to start a new Intent, so the main activity is not still in Foreground. After approximately 5 seconds the ranging of the beacons stops, and my position calculating also because the distances of the beacons doesn't change any more.
Is there any possibility to continue ranging beacons? I've tried to start an async task in my main activity, but it doesn't work, maybe there is a mistake, i don't know.
Here is my Code of the async task and the OnBeaconServiceConnect():
public class Monitor_Screen extends Activity implements BeaconConsumer,
SensorEventListener {
private class asyncThread extends AsyncTask<Activity, Void, BeaconManager> {
#Override
protected BeaconManager doInBackground(Activity... arg0) {
// TODO Auto-generated method stub
Thread.currentThread().setName("BeaconManagerThread");
Application myApplication = new Application();
// BeaconManager
myBeaconManager = BeaconManager.getInstanceForApplication(myApplication);
myBeaconManager
.getBeaconParsers()
.add(new BeaconParser()
.setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
myBeaconManager.setBackgroundScanPeriod(TimeUnit.SECONDS.toMillis(1));
myBeaconManager.bind(Monitor_Screen.this);
// Region
myRegion = new Region("all beacons", null, null, null);
startService(Monitor_Screen.this.getIntent());
return myBeaconManager;
}
}
#Override
public void onBeaconServiceConnect() {
// // range beacons on connect
try {
myBeaconManager.startRangingBeaconsInRegion(myRegion);
} catch (RemoteException e) {
Toast.makeText(getApplicationContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
myBeaconManager.setRangeNotifier(new RangeNotifier() {
public void didRangeBeaconsInRegion(Collection<Beacon> beacons,
Region myRegion) {
if (beacons.size() > 0) {
Iterator<Beacon> myIterator = beacons.iterator();
while (myIterator.hasNext()) {
Beacon tempBeacon = myIterator.next();
MyBeacon myBeacon = new MyBeacon(tempBeacon.getId1(),
tempBeacon.getId2(), tempBeacon.getId3(),
tempBeacon.getBluetoothAddress(), tempBeacon
.getRssi(), tempBeacon.getDistance(),
tempBeacon.getTxPower(), System
.currentTimeMillis(),
new Position(0, 0));
boolean isIn = false;
for (MyBeacon blub : myVector) {
if (blub.getBTAdress().equals(
myBeacon.getBTAdress())) {
isIn = true;
blub.distance = myBeacon.getDistance();
}
}
if (!isIn)
myVector.add(myBeacon);
}
}
logBeaconData();
for (int i = 0; i < myVector.size(); i++) {
if (System.currentTimeMillis()
- myVector.get(i).getTimeStamp() > 10000) {
myVector.remove(i);
}
}
}
});
try {
myBeaconManager.startMonitoringBeaconsInRegion(myRegion);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myBeaconManager.setMonitorNotifier(new MonitorNotifier() {
#Override
public void didExitRegion(Region arg0) {
// TODO Auto-generated method stub
}
#Override
public void didEnterRegion(Region arg0) {
// TODO Auto-generated method stub
}
#Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
// TODO Auto-generated method stub
}
});
}
The easiest way to have beacon ranging continue in the background is to set up beacon ranging in a custom android.app.Application class, and have it forward the callbacks to your Activity to update the display only if that Activity is in the foreground.
You can see an example of doing this in the reference application for the Android Beacon Library here: https://github.com/AltBeacon/android-beacon-library-reference
Below is an excerpt from the custom android.app.Application class where this is set up. Note that ranging is set up once, and will continue for the whole lifecycle of the application. The ranging callback is passed to the mRangingActivity if it exists, so it can do any UI processing necessary.
public class BeaconReferenceApplication extends Application implements BootstrapNotifier, RangeNotifier {
...
public void onCreate() {
mAllBeaconsRegion = new Region("all beacons", null, null, null);
mBeaconManager = BeaconManager.getInstanceForApplication(this);
mBackgroundPowerSaver = new BackgroundPowerSaver(this);
mRegionBootstrap = new RegionBootstrap(this, mAllBeaconsRegion);
}
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> arg0, Region arg1) {
if (mRangingActivity != null) {
mRangingActivity.didRangeBeaconsInRegion(arg0, arg1);
}
}
#Override
public void didEnterRegion(Region arg0) {
try {
Log.d(TAG, "entered region. starting ranging");
mBeaconManager.startRangingBeaconsInRegion(mAllBeaconsRegion);
mBeaconManager.setRangeNotifier(this);
} catch (RemoteException e) {
Log.e(TAG, "Cannot start ranging");
}
}
...
}

How to register a custom speech recognition service?

I created a simple speech recognition service: for this purpose I created a subclass of android.speech.RecognitionService and I created an activity to start and stop this service.
My custom speech recognition service trivially uses the default speech recognizer, because my goal is simply to understand how the RecognitionService and RecognitionService.Callback classes work.
public class SimpleVoiceService extends RecognitionService {
private SpeechRecognizer m_EngineSR;
#Override
public void onCreate() {
super.onCreate();
Log.i("SimpleVoiceService", "Service started");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("SimpleVoiceService", "Service stopped");
}
#Override
protected void onCancel(Callback listener) {
m_EngineSR.cancel();
}
#Override
protected void onStartListening(Intent recognizerIntent, Callback listener) {
m_EngineSR.setRecognitionListener(new VoiceResultsListener(listener));
m_EngineSR.startListening(recognizerIntent);
}
#Override
protected void onStopListening(Callback listener) {
m_EngineSR.stopListening();
}
/**
*
*/
private class VoiceResultsListener implements RecognitionListener {
private Callback m_UserSpecifiedListener;
/**
*
* #param userSpecifiedListener
*/
public VoiceResultsListener(Callback userSpecifiedListener) {
m_UserSpecifiedListener = userSpecifiedListener;
}
#Override
public void onBeginningOfSpeech() {
try {
m_UserSpecifiedListener.beginningOfSpeech();
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void onBufferReceived(byte[] buffer) {
try {
m_UserSpecifiedListener.bufferReceived(buffer);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void onEndOfSpeech() {
try {
m_UserSpecifiedListener.endOfSpeech();
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void onError(int error) {
try {
m_UserSpecifiedListener.error(error);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void onEvent(int eventType, Bundle params) { ; }
#Override
public void onPartialResults(Bundle partialResults) {
try {
m_UserSpecifiedListener.partialResults(partialResults);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void onReadyForSpeech(Bundle params) {
try {
m_UserSpecifiedListener.readyForSpeech(params);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void onResults(Bundle results) {
try {
m_UserSpecifiedListener.results(results);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void onRmsChanged(float rmsdB) {
try {
m_UserSpecifiedListener.rmsChanged(rmsdB);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
I start and stop the service using the following activity.
public class VoiceServiceStarterActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button startButton = new Button(this);
startButton.setText("Start the service");
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { startVoiceService(); }
});
Button stopButton = new Button(this);
stopButton.setText("Stop the service");
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { stopVoiceService(); }
});
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(startButton);
layout.addView(stopButton);
setContentView(layout);
}
private void startVoiceService() {
startService(new Intent(this, SimpleVoiceService.class));
}
private void stopVoiceService() {
stopService(new Intent(this, SimpleVoiceService.class));
}
}
Finally I declared my service on the AndroidManifest.xml (see VoiceRecognition sample within Android SDK folder).
<service android:name="SimpleVoiceService"
android:label="#string/service_name" >
<intent-filter>
<action android:name="android.speech.RecognitionService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
Then I installed this application on an Android device and I start it:
- when I start the service, it starts properly;
- when I stop it, it stops properly.
But if I launch the following code in a another activity, the activities List contains only an element, which is the default speech recognizer.
PackageManager pm = getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(
new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
Why is my speech recognizer not returned among those present in the system?
If you want queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0) to pick up your activity (VoiceServiceStarterActivity) then you have to declare in your app's Manifest that this activity handles RecognizerIntent.ACTION_RECOGNIZE_SPEECH, like this
<activity android:name="VoiceServiceStarterActivity">
<intent-filter>
<action android:name="android.speech.action.RECOGNIZE_SPEECH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
...
</activity>
For more concrete code have a look at the project Kõnele (source code) which is essentially an open source implementation of the interfaces via which speech recognition is provided on Android, i.e. it covers:
ACTION_RECOGNIZE_SPEECH
ACTION_WEB_SEARCH
RecognitionService
and uses open source speech recognition servers.
Yes, you need to use createSpeechRecognizer(Context context, ComponentName serviceComponent)

Categories

Resources