I have a collection of bluetooth earpieces and wanted to be able to connect directly to their AVRCP profile.
The main sticking point is that there is no publicly accessible way to construction an L2CAP socket.
In theory the code below ought to work, but I am getting a permssion denied error.
I do have these in my manifest:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
The code snippet is here:
private BluetoothSocket createL2CAP(BluetoothDevice bd, UUID uuid) {
BluetoothSocket result = null;
try {
c=BluetoothSocket.class.getDeclaredConstructor(int.class,int.class,boolean.class,boolean.class, BluetoothDevice.class,int.class,ParcelUuid.class);
result=(BluetoothSocket) c.newInstance(BluetoothSocket.TYPE_L2CAP, -1, true, true, bd, -1, new ParcelUuid(uuid));
} catch (NoSuchMethodException e) {
addln("BluetoothSocket: No Such Constructor");
} catch (IllegalAccessException e) {
addln("BluetoothSocket: Illegal access");
} catch (InvocationTargetException e) {
addln("BluetoothSocket: Target exception "+e.getMessage());
} catch (InstantiationException e) {
addln("BluetoothSocket: "+e.getMessage());
}
return result;
}
It's finding the constructor, but throwing the IllegalAccessException.
Has anyone had any luck persuading Android Bluetooth to make any connection type other than RFCOMM? And/or is there a different approach which may have more success?
(PS: addln is just sending messages to a textview so I can see what is happening)
Related
I can't find in the doc how to retrieve if device is configured as a portable hotspot.
I've read How to detect if a network is (configured as) a mobile hotspot on Android? but I don't know if the feature has been implemented?
You can use below code to check if Tethering is enabled or not on your device:
private static Method isWifiApEnabledMethod;
public static boolean isWifiApEnabled(WifiManager wifiManager) {
if (isWifiApEnabledMethod == null) {
try {
isWifiApEnabledMethod = wifiManager.getClass().getDeclaredMethod("isWifiApEnabled");
isWifiApEnabledMethod.setAccessible(true); //in the case of visibility change in future APIs
} catch (NoSuchMethodException e) {
Log.w(TAG, "Can't get method by reflection", e);
}
}
if (isWifiApEnabledMethod != null) {
try {
return (Boolean) isWifiApEnabledMethod.invoke(wifiManager);
} catch (IllegalAccessException e) {
Log.e(TAG, "Can't invoke method by reflection", e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Can't invoke method by reflection", e);
}
}
return false;
}
Don't forget to add below permission in AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
For the SO link mentioned above in question:
This feature is not available i.e. has not been implemented.
For more information check this link where Google officially marked the status as Status: Won't Fix (Obsolete)
Hope this will help you. Thanks!
I'm trying to create server socket on port 554 (rtsp) in Android and i'm getting BindException with 'denied' message:
public RequestListener() throws IOException {
try {
mRtspServerSocket = new ServerSocket(mPort);
start();
} catch (BindException e) {
Log.e(TAG, "Port bind exception");
throw e;
}
}
Are standard ports (or < 1024) unavailable for binding? Do i have to have root permission on the device for that?
PS. I have <uses-permission android:name="android.permission.INTERNET" /> in AndroidManifest.xml
You can't bind to ports <1024.
Either root your phone, modify the firmware, or don't bind to ports
lower than 1024. That's a Linux thing more than an Android thing.
I'm trying to check if server is available but when running this code I get error that server is not available or sometimes application freezes even server is properly running:
InetAddress in;
in = null;
try {
in = InetAddress.getByAddress(new byte[] { (byte)192, (byte)168, (byte)16, (byte)48});
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (in.isReachable(5000)) {
loadProduct();
} else
{
showAlertBox("Warning", "Server not available!");
}
} catch (IOException e) {
showAlertBox("Warning", "Server not available!");
}
Is there any better way to check if server is online?
Is there any better way to check if server is online
Yes. Try to connect to it. That is an infallible test. Don't do it until you need to, of course. Don't try to predict the future. Just connect and handle the failure.
I have tried with this
Socket socket = null;
boolean reachable = false;
try {
socket = new Socket("192.168.16.48", 80);
reachable = true;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
showAlertBox("Warning", "Server not available!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
showAlertBox("Warning", "Server not available!");
} finally {
if (socket != null) try { socket.close(); } catch(IOException e) { }
}
It works, but sometimes I get meesage that that applications is not responding, even if socket timeout is adjusted.
You can try to locate the server using its host name. The advantage: unlike the dynamic ip address, the host name probably has a longer validity. In the following example, both network interfaces can refer to the same host.
byte[] b = { 10, 0, 0, 1 };
String name = "Hostname";
InetAddress ia = Inet4Address.getByAddress(b);
InetAddress ia2 = Inet4Address.getByName(name);
Another possible solution: before using network operations on android, you must get the corresponding permissions from the android manifest. I don't know exactly, which of the following are must-haves:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
I want to code an Android app, which will connect to a network printer with a specific IP address, and then make a printing.
For printing I know that I need to write my own Postscript for specific files types, and connecting to a network is not a problem over WIFI.
How to connect to the network printer?
Any device connected to a network will communicate via their IP and Ports / sockets. The simplest way to connect via telnet or socket and write the data to their socket buffers.
try
{
Socket sock = new Socket("192.168.1.222", 9100);
PrintWriter oStream = new PrintWriter(sock.getOutputStream());
oStream.println("HI,test from Android Device");
oStream.println("\n\n\n");
oStream.close();
sock.close();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
You might be able to use lpdspooler, that is, if the printer supports LPR/LPD. If you can give some more details about the environment (printer, etc), I might be able to give more information.
Just Add This Code After oncreate Method
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Star has an Android SDK which has port discovery. It'll find any of their wifi receipt printers on your network. http://starmicronics.com/support/SDKDocumentation.aspx
Try to use PrintManager: https://developer.android.com/training/printing/custom-docs
private void doPrint() {
// Get a PrintManager instance
PrintManager printManager = (PrintManager) getActivity()
.getSystemService(Context.PRINT_SERVICE);
// Set job name, which will be displayed in the print queue
String jobName = getActivity().getString(R.string.app_name) + " Document";
// Start a print job, passing in a PrintDocumentAdapter implementation
// to handle the generation of a print document
printManager.print(jobName, new MyPrintDocumentAdapter(getActivity()),
null); //
}
My solution. I used Epson TM series. I think the port is 9100 for default.
In Manifest add:
<uses-permission android:name="android.permission.INTERNET"/>
in the activity use a Thread otherwise u you can the android.os.NetworkOnMainThreadException error.
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Socket sock = new Socket("192.168.1.168", 9100);
PrintWriter oStream = new PrintWriter(sock.getOutputStream());
oStream.println("Hi, test from Android Device");
oStream.println("\n");
oStream.close();
sock.close();
} catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}});
If not enough, add in manifest these:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Well, you cant connect any devices directly as you will need the driver installed. there are 3rd party apps like Google Cloud print that works seamlessly with Android though.
I'm trying to write a test app which connects to BlackBerry 655+ bluetooth headset. Basically what i want to do in this app is connect to the headset and catch button pressures on it. I think that could be done by reading the socket's inputstream. Anyway, i get some errors right when i try to connect to the socket. Here's the code:
BluetoothSocket tmp = null;
try {
tmp = mDevice.createRfcommSocketToServiceRecord(
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
} catch(IOException e) {}
mSocket = tmp;
mBtAdapter.cancelDiscovery();
try {
mSocket.connect(); // THIS ONE GIVES A "Service discovery failed" exception
} catch (IOException e1) {
Method m = null;
try {
m = mDevice.getClass().getMethod(
"createRfcommSocket", new Class[] {int.class});
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
tmp = (BluetoothSocket) m.invoke(mDevice, 1);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
mSocket = tmp;
try {
mSocket.connect(); // THIS ONE GIVES A "Connection refused" EXCEPTION
} catch (IOException e) {
e.printStackTrace();
}
}
What am i doing wrong? I already tried different ports in the m.invoke(mDevice, X) instruction but it always gives "Connection refused"
I worked with Bluetooth before but with python and Java ME so I understand the basics. I don't know much about the android API though.
Where did you get the UUID code from? That could be one of the reasons for the Service discovery failed.
Each bluetooth device may have several services each of them associated to one port (or channel). If you are running ubuntu try using the hci tools to know to which channel connect or which service to search for.
Here you have an official list with UUIDs from Bluetooth SIG. For Headset Profile the UUID is 0x1108, the UUID used by you it is Base Universally Unique Identifier and it is used for SDP.