I've copied the following code from Android documentation but doesn't discovery any device. Anyone know why?
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private TextView tvBoundedDevices;
private TextView tvDiscoveredDevices;
private IntentFilter intentFilter = new IntentFilter();
private BroadcastReceiver broadcastReceiver;
private ProgressDialog progressDialog;
private ArrayList<BluetoothDevice> bluetoothDevicesFound = new ArrayList<>();
private Set<BluetoothDevice> bluetoothDevicesBounded;
#Override
protected void onDestroy() {
unregisterReceiver(broadcastReceiver);
bluetoothAdapter.cancelDiscovery();
super.onDestroy();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvBoundedDevices = findViewById(R.id.tvBoundedDevices);
tvDiscoveredDevices = findViewById(R.id.tvDiscoveredDevices);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action){
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
progressDialog = ProgressDialog.show(MainActivity.this,"Attendere","Scan in corso");
break;
case BluetoothDevice.ACTION_FOUND:
bluetoothDevicesFound.add((BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
if(progressDialog.isShowing())
progressDialog.dismiss();
break;
default:
Toast.makeText(context, "Action=" + action, Toast.LENGTH_LONG).show();
}
}
};
registerReceiver(broadcastReceiver,intentFilter);
}
public void turnBluetoothOn(View view){
if(!bluetoothAdapter.isEnabled()){
bluetoothAdapter.enable();
Toast.makeText(this,"Bluetooth attivato",Toast.LENGTH_SHORT).show();
}
}
public void turnBluetoothOff(View view){
if(bluetoothAdapter.isEnabled()){
bluetoothAdapter.disable();
Toast.makeText(this,"Bluetooth disattivato",Toast.LENGTH_SHORT).show();
}
}
public void scanDevices(View view){
turnBluetoothOn(null);
if(bluetoothAdapter.isDiscovering())
bluetoothAdapter.cancelDiscovery();
Toast.makeText(this, "Scansione " + (bluetoothAdapter.startDiscovery()?"":"non") + " avviata.", Toast.LENGTH_SHORT).show();
printDevices();
}
String toStamp = "";
private void printDevices(){
bluetoothDevicesBounded = bluetoothAdapter.getBondedDevices();
if(!bluetoothDevicesBounded.isEmpty()){
toStamp = "Dispositivi associati:\n";
for(BluetoothDevice b : bluetoothDevicesBounded){
toStamp += b.getName() + " | " + b.getAddress() + "\n";
}
tvBoundedDevices.setText(toStamp + "");
}
if(!bluetoothDevicesFound.isEmpty()){
toStamp = "Dispositivi trovati:\n";
for(BluetoothDevice b : bluetoothDevicesFound){
toStamp += b.getName() + " | " + b.getAddress() + "\n";
}
tvDiscoveredDevices.setText(toStamp + "");
}
}
Pastebin: https://pastebin.com/CnEBAtwt
What works:
- List of bounded devices
- Broadcast for "start discovery" and "end discovery"
What doesn't works:
- Discovery nearby devices
Thank you
You need to add one of the following permission to found devices:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
or
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If you are working on API 23 and higher you must ensure this permission is granted because it is a dangerous level permission.
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app
See this guide to request permission.
Related
How can I use an app to detect when the otg cable is plugged in and when it's not?
Is there an intent for otg cables like the one below for usb devices: "android.hardware.usb.action.USB_DEVICE_ATTACHED"
I have created an app but it only detects a flash drive and not an otg cable:
public class MainActivity extends AppCompatActivity
{
private TextView mInfo;
private Logger mLogger;
private HashMap<UsbDevice, UsbDataBinder> mHashMap = new HashMap<UsbDevice, UsbDataBinder>();
private UsbManager mUsbManager;
private PendingIntent mPermissionIntent;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mInfo = (TextView)findViewById(R.id.log);
mLogger = new Logger(this);
mLogger.setMode(Logger.MODE_TOAST);
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
usbConnection();
}
private void usbConnection() {
IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
registerReceiver(mUsbAttachReceiver , filter);
filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(mUsbDetachReceiver , filter);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
showDevices();
}
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mUsbDetachReceiver);
unregisterReceiver(mUsbAttachReceiver);
unregisterReceiver(mUsbReceiver);
};
BroadcastReceiver mUsbDetachReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
// call your method that cleans up and closes communication with the device
UsbDataBinder binder = mHashMap.get(device);
if (binder != null) {
binder.onDestroy();
mHashMap.remove(device);
Toast.makeText(MainActivity.this, "Attached!", Toast.LENGTH_SHORT).show();
}
}
}
}
};
BroadcastReceiver mUsbAttachReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
showDevices();
Toast.makeText(MainActivity.this, "Detached!", Toast.LENGTH_SHORT).show();
}
}
};
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
// call method to set up device communication
UsbDataBinder binder = new UsbDataBinder(mUsbManager, device);
mHashMap.put(device, binder);
Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
}
} else {
// Log.d(TAG, "permission denied for device " + device);
}
}
}
}
};
private void showDevices() {
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next();
mUsbManager.requestPermission(device, mPermissionIntent);
//your code
mLogger.log("usb", "name: " + device.getDeviceName() + ", " +
"ID: " + device.getDeviceId());
mInfo.append(device.getDeviceName() + "\n");
mInfo.append(device.getDeviceId() + "\n");
mInfo.append(device.getDeviceProtocol() + "\n");
mInfo.append(device.getProductId() + "\n");
mInfo.append(device.getVendorId() + "\n");
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
}
I never tried USB OTG, but from https://github.com/shakalaca/USB-OTG-Manager you can use
<intent-filter>
<action android:name="com.sonyericsson.hardware.action.USB_OTG_DEVICE_CONNECTED" />
<action android:name="com.sonyericsson.hardware.action.USB_OTG_DEVICE_DISCONNECTED" />
<action android:name="com.sonyericsson.hardware.action.USB_OTG_ERROR" />
<action android:name="com.sonyericsson.usbotg.ACTION_ERROR_OK" />
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
From the documentation:
USB OTG Manager
This software is originally designed for Sony Ericsson Xperia Arc S.
Since OTG is enabled in kernel, I'm wondering why I can't access my
memory stick. So I've created this little application for reading
books on my thumb disk, and happily ever after ! :D
Supported Phone:
* Sony Ericsson Xperia Arc S (4.0.2.A.042, 4.0.2.A.062)
* Sony Ericsson Xperia Mini Pro (4.0.2.A.042, 4.0.2.A.058)
* Samsung Galaxy Nexus
Supported USB Device:
* FAT USB memory stick
* Card Reader
related project: https://github.com/mik3y/usb-serial-for-android
you're on your own boat now.
I have made an application that allows many-to-one communication using Bluetooth and it is working perfectly fine. Now, i wanted to use the service of the application in another application (e.g. Discovering Devices, Connecting to Device). So, I marked my project as library and added it as library in my new project. However, when i call the Discovering Device Activity (Available in library) from the application, the activity starts, but it doesn't discovers the devices ? Can someone help on this ?
I have included all the library project activity and permissions in my app's manifest.
Here is the sample code for the same -
In Library -
This is how the DeviceListActivity Looks like -
`
public class DeviceListActivity extends Activity{
String insecure="8ce255c0-200a-11e0-ac64-0800200c9a66";
private int flag=0;
int flag_toast=0;
ArrayList<Pair<String,String>> x=new ArrayList<Pair<String,String>>();
private static final String TAG = "DeviceListActivity";
ArrayList<String> temp=new ArrayList<String>();
Map<String, String> services = new HashMap<String, String>();
/**
* Return Intent extra
*/
public static String EXTRA_DEVICE_ADDRESS = "device_address";
/**
* Member fields
*/
private BluetoothAdapter mBtAdapter;
/**
* Newly discovered devices
*/
ImageView animation;
private ArrayList<BluetoothDevice> btDeviceList = new ArrayList<BluetoothDevice>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the window
// requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_device_list);
// Set result CANCELED in case the user backs out
setResult(Activity.RESULT_CANCELED);
// Initialize the button to perform device discovery
animation=(ImageView)findViewById(R.id.imageAnimation);
/*scanButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
doDiscovery();
v.setVisibility(View.GONE);
}
});*/
// Initialize array adapters. One for already paired devices and
// one for newly discovered devices
//ArrayAdapter<String> pairedDevicesArrayAdapter =new ArrayAdapter<String>(this, R.layout.device_name);
//mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
//Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_UUID);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
/* this.registerReceiver(mReceiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
*/
// Get the local Bluetooth adapter
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
animation.setBackgroundResource(R.drawable.animation);
doDiscovery();
}
#Override
protected void onDestroy() {
super.onDestroy();
// Make sure we're not doing discovery anymore
if (mBtAdapter != null) {
mBtAdapter.cancelDiscovery();
}
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver);
}
/**
* Start device discover with the BluetoothAdapter
*/
public void doDiscovery() {
Log.d(TAG, "doDiscovery()");
// If we're already discovering, stop it
if (mBtAdapter.isDiscovering()) {
mBtAdapter.cancelDiscovery();
}
// Request discover from BluetoothAdapter
mBtAdapter.startDiscovery();
}
private void connect_automatic(String name){
flag++;
Log.d(name,"Called " + Integer.toString(flag)+" times");
Log.d("Flag is = ",Integer.toString(flag));
int i,j;
for(i=0;i<x.size();i++){
for (j=i+1;j<x.size();j++)
if (x.get(i).getFirst().equals(x.get(j).getFirst())==true && x.get(i).getSecond().equals(x.get(j).getSecond())==true)
x.remove(j);
}
for(i=0;i<x.size();i++){
Log.d("Found "+x.get(i).getFirst(),x.get(i).getSecond());
}
Log.d("Size =",Integer.toString(x.size()));
if (x.size()>=1){
Log.d("Size is =",Integer.toString(x.size()));
String address = x.get(0).getFirst();
if (flag_toast==0)
Toast.makeText(DeviceListActivity.this, "Merchant Found", Toast.LENGTH_SHORT).show();
flag_toast++;
Log.d("Connecting to ",x.get(0).getFirst());
// Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
}
/**
* The BroadcastReceiver that listens for discovered devices and changes the title when
* discovery is finished
*/
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
flag++;
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
//mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
btDeviceList.add(device);
// When discovery is finished, change the Activity title
}
else
{
Log.d("Action=",action.toString());
if(BluetoothDevice.ACTION_UUID.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
if(uuidExtra!=null)
for (int i=0; i<uuidExtra.length; i++) {
if(uuidExtra[i].toString().length()>0){
Log.d("\n Device: " + device.getName() + ", " + device, ", Service: " + uuidExtra[i].toString());
// services.put(device.getName(), uuidExtra[i].toString());
//flag=btDeviceList.size();
if (/*uuidExtra[i].toString().equals(secure)==true ||*/ uuidExtra[i].toString().equals(insecure)==true){
Pair<String,String> t=new Pair<String, String>(device.getAddress(), uuidExtra[i].toString());
x.add(t);
}
//connect_automatic();
}
}
Log.d("Device List =",Integer.toString(flag));
connect_automatic(device.getName());
//Log.d("Boolean",Boolean.toString(services.isEmpty()))
}
else
{
if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Log.d("Discovery","Started...");
}
else
{
if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Log.d("Discover","Finished");
//setProgressBarIndeterminateVisibility(false);
Iterator<BluetoothDevice> itr = btDeviceList.iterator();
while (itr.hasNext()) {
// Get Services for paired devices
BluetoothDevice device = itr.next();
temp.add(device.getName());
Log.d("ok","Getting Services for " + device.getName() + ", " + device);
if(!device.fetchUuidsWithSdp()) {
Log.d("!ok","SDP Failed for " + device.getName());
}
else{
Log.d("SDP Passed for ",device.getName());
}
}
//connect_automatic();
}
}
}
}
}
};}`
And here is how i call it in my new application -
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null)
{
ensureDiscoverable();
Intent intent = new Intent(this, DeviceListActivity.class);
startActivityForResult(intent, REQUEST_CONNECT_DEVICE_INSECURE);
}
}
i want to search and listing bluetooth devices in android, my program now able to list all the active devices but not able to send pairing request to the other devices .I want to implement this onItemClick of list element.And also if bluetooth is not enabled of my device then show a permission to active device,if i go for yes then ok,but if i go for no then permission show again until i press yes..how can i do this?plz help with code..here is my code..
public class Main extends Activity {
TextView out;
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter btAdapter;
private ArrayList<BluetoothDevice> btDeviceList = new ArrayList<BluetoothDevice>();
private ArrayList<String> mylist= new ArrayList<String>();
private ListView lv;
private Button btn;
public Parcelable[] uuidExtra;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void search(View view)
{
//Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_UUID);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(ActionFoundReceiver, filter); // Don't forget to unregister during onDestroy
// Getting the Bluetooth adapter
btAdapter = BluetoothAdapter.getDefaultAdapter();
Toast.makeText(getApplicationContext(),"\nAdapter: " + btAdapter,5000).show();
CheckBTState();
}
private void setDeviceList(ArrayList<String> list) {
lv = (ListView) findViewById(R.id.listView);
ArrayAdapter<String> adapter= new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list);
lv.setAdapter(adapter);
}
/* This routine is called when an activity completes.*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ENABLE_BT) {
CheckBTState();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (btAdapter != null) {
btAdapter.cancelDiscovery();
}
unregisterReceiver(ActionFoundReceiver);
}
private void CheckBTState() {
// Check for Bluetooth support and then check to make sure it is turned on
// If it isn't request to turn it on
// List paired devices
// Emulator doesn't support Bluetooth and will return null
if(btAdapter==null) {
Toast.makeText(getApplicationContext(),"\nBluetooth NOT supported. Aborting.",5000).show();
return;
} else {
if (btAdapter.isEnabled()) {
Toast.makeText(getApplicationContext(),"\nBluetooth is enabled...",5000).show();
// Starting the device discovery
btAdapter.startDiscovery();
} else if (!btAdapter.isEnabled()){
Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
/* else{
Intent intent = new Intent(btAdapter.ACTION_STATE_CHANGED);
startActivityForResult(intent, RESULT_CANCELED);
}*/
}
}
private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(getApplicationContext(),"\n Device: " + device.getName() + ", " + device,5000).show();
mylist.add(device.getName());
setDeviceList(mylist);
} else {
if(BluetoothDevice.ACTION_UUID.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
for (int i=0; i<uuidExtra.length; i++) {
Toast.makeText(getApplicationContext(),"\n Device: " + device.getName() + ", " + device + ", Service: " + uuidExtra[i].toString(),5000).show();
}
} else {
if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Toast.makeText(getApplicationContext(),"\nDiscovery Started...",5000).show();
} else {
if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Toast.makeText(getApplicationContext(),"\nDiscovery Finished",5000).show();
Iterator<BluetoothDevice> itr = btDeviceList.iterator();
while (itr.hasNext()) {
// Get Services for paired devices
BluetoothDevice device = itr.next();
Toast.makeText(getApplicationContext(),"\nGetting Services for " + device.getName() + ", " + device,5000).show();
if(!device.fetchUuidsWithSdp()) {
Toast.makeText(getApplicationContext(),"\nSDP Failed for " + device.getName(),5000).show();
}
}
}
}
}
}
}
};
}
It's too late but here is code -> You need to use background thread to connect with bluetooth device as a client. and UUID is Universal Uniquely identification you can use online UUID generator. for secure connections and then get socket with device and connect with it;
ConnectWithDevice(context : ConnectWithBluetooth, device : BluetoothDevice) : Thread(){
private val mContext : ConnectWithBluetooth = context
private val mmSocket : BluetoothSocket
private val mmDevice : BluetoothDevice
// Default UUID
private val mmDefaultUUID = UUID.fromString("78c374fd-f84d-4a9e-aa5b-9b0b6292952e")
init {
var temp : BluetoothSocket? = null
mmDevice = device
try {
// Try here device.createInsecureConnect if it's work then start with this;
temp = device.createRfcommSocketToServiceRecord(mmDevice.uuids[0].uuid)
}catch (en : NullPointerException){
en.printStackTrace()
// Try here device.createInsecureConnect if it's work then start with this;
temp = device.createRfcommSocketToServiceRecord(mmDefaultUUID)
}catch (e : IOException){
e.printStackTrace()
Log.e("TAG","Socket's create() method failed",e)
}
mmSocket = temp!!
Log.i("TAG","Got the Socket")
}
override fun run() {
// Cancel discovery because it otherwise slows down the connection.
if(mContext.bluetoothAdapter != null){
mContext.bluetoothAdapter!!.cancelDiscovery()
}
try{
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
Log.i("TAG","Connecting...")
mmSocket.connect()
Log.i("TAG","Bluetooth Successfully Connected")
}catch (connectException : IOException){
// Unable to connect; close the socket and return.
try{
mmSocket.close()
}catch (closeException : IOException){
Log.e("TAG","Could not close the client socket",closeException)
}
return
}
// The connection attempt succeeded. Perform work associated with
// the connection in a separate thread.
Log.i("TAG","Device is Connected")
//manageMyConnectedSocket(mmSocket)
}
// Closes the client socket and causes the thread to finish.
// Call this method from the main activity to shut down the connection.
fun cancel(){
try {
mmSocket.close()
} catch (e: IOException) {
Log.e(ContentValues.TAG, "Could not close the client socket", e)
}
}
}
We have a demo android application (Android 4.0.3) that runs voice recognition as a service, and (continuosly) logs the results of the recognition on the view.
Everything is working fine in our smartphones.
We would like to replicate this scenario in a Google Glass immersion application, but we always have this error message when we try to start the service:
no selected voice recognition service
Are there some known limitations? Or have someone figured out how to resolve this kind of problem?
Thanks in advance
This is some significant code of the activity:
public class MainActivity extends Activity implements Observer {
...
#Override
protected void onStart() {
super.onStart();
//Toast.makeText(this, "Hi guys", Toast.LENGTH_LONG);
startService(new Intent(this, SilentVoiceRecognitionService.class));
}
...
}
And this is the code of the service:
public class SilentVoiceRecognitionService extends Service {
protected AudioManager mAudioManager;
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));
private Model model = Model.getInstance();
static final String TAG = "SilentRecognizer";
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
protected boolean mIsListening;
#Override
public void onCreate()
{
super.onCreate();
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());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
return START_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
}
}
protected class SpeechRecognitionListener implements RecognitionListener
{
...
}
protected static class IncomingHandler extends Handler
{
private WeakReference<SilentVoiceRecognitionService> mtarget;
IncomingHandler(SilentVoiceRecognitionService target)
{
mtarget = new WeakReference<SilentVoiceRecognitionService>(target);
}
#Override
public void handleMessage(Message msg)
{
final SilentVoiceRecognitionService target = mtarget.get();
switch (msg.what)
{
case MSG_RECOGNIZER_START_LISTENING:
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;
}
}
}
}
This feature has been recently accepted but not yet available, see https://code.google.com/p/google-glass-api/issues/detail?id=245
You can load the additional mentioned apk to get the functionality for the mean time.
See Using Android Speech Recognition APIs from Google Glass
As of XE16 it is now possible to use the SpeechRecognizer directly and get the results through the SpeechRecognitionListener.
Unfortunately this still dosen't work offline.
I need to get a list of available bluetooth devices in the area using google android 2.1.
Thing is, i don't just need a list of those devices, i need some unique id for each device found and i need an indicator, how "good" the signal is received (like the "level" in android.wifi.ScanResult)... How do i do that?
Check out code below :
Starting search
mBluetoothAdapter.startDiscovery();
mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//Finding devices
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
Call method bluetoothScanning, context is required
void bluetoothScanning(){
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(mReceiver, filter);
final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.startDiscovery();
}
// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
Log.i("Device Name: " , "device " + deviceName);
Log.i("deviceHardwareAddress " , "hard" + deviceHardwareAddress);
}
}
};
Result
Name: LE-Bose Revolve+ SoundLink
deviceHardwareAddress: MAC .....
This code uses BeaconManager, it continuously scans for new Bluetooth devices and returns a Beacons List object which you can use to get what ever information you need.
Make sure you import BeaconManager
private BeaconManager beaconManager;
//In onCreate method
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"));
//use these out of the onCreate method
public void onScanStart(View view) {
stopScanButton.setEnabled(true);
scanningButton.setEnabled(false);
beaconManager.bind(this);
}
#Override
public void onBeaconServiceConnect() {
beaconManager.removeAllRangeNotifiers();
beaconManager.addRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
for (Beacon b : beacons) {
System.out.println(String.format("%s: %f: %d", b.getBluetoothName(), b.getDistance(), b.getRssi()));
});
try {
//Tells the BeaconService to start looking for beacons that match the passed.
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
} catch (RemoteException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
}
}
Let me know if that works for you!
To able to discovery devices by bluetooth. Make sure you
Enable bluetooth
Allow required permissions for your application (some permission is runtime permission). You can check here https://developer.android.com/about/versions/12/features/bluetooth-permissions
AndroidManifest.xml
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
MainActivity
class MainActivity : AppCompatActivity() {
private var bluetoothAdapter: BluetoothAdapter? = null
private val bluetoothReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) {
val action = intent.action
Log.i("TAG", "onReceive $action")
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED == action) {
Log.i("TAG", "Discovery finished, hide loading")
} else if (BluetoothDevice.ACTION_FOUND == action) {
val device =
intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
Log.i("TAG", "Device Name: " + (device?.name ?: ""))
Log.i("TAG", "Device Address:" + (device?.address ?: ""))
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
...
findViewById<Button>(R.id.button_start_discovery).setOnClickListener {
if (bluetoothAdapter == null) {
initBluetoothDiscovery()
}
startDiscovery()
}
}
private fun initBluetoothDiscovery() {
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
bluetoothAdapter = bluetoothManager.adapter
val intentFilter = IntentFilter().apply {
addAction(BluetoothDevice.ACTION_FOUND)
addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
}
registerReceiver(bluetoothReceiver, intentFilter)
}
private fun startDiscovery() {
if (bluetoothAdapter?.isDiscovering == true) {
Log.i("TAG", "cancel start discovery")
bluetoothAdapter?.cancelDiscovery()
}
Log.i("TAG", "start discovery, show loading")
bluetoothAdapter?.startDiscovery()
}
override fun onDestroy() {
super.onDestroy()
bluetoothAdapter?.cancelDiscovery();
unregisterReceiver(bluetoothReceiver);
}
}