everyone.
I try to implement a pbap client on Android platform.
My client can get phonebook from most of android phones.
But when I connect to HTC G11, it does not work normally.
my main code is as follows:
mSocket = mDevice.createInsecureRfcommSocketToServiceRecord(ParcelUuid.fromString(PBAP_UUID).getUuid()); //it's OK here
mSocket.connect(); //it's OK here
mClientSession = new ClientSession(transport); //it's OK here
HeaderSet request_conn = new HeaderSet();
request_conn.setHeader(HeaderSet.TARGET, PBAP_TARGET);
HeaderSet return_header = mClientSession.connect(request_conn); //it's OK here
When mClientSession.connect(request_conn) called, remote device give a response code OBEX_HTTP_OK.
It means remote device accepted my pbap connection request.
But problem come out after that.
HeaderSet request_get = new HeaderSet();
request_get.setHeader(HeaderSet.NAME, name);
request_get.setHeader(HeaderSet.TYPE, type);
mGetOperation = (ClientOperation)mClientSession.get(request_get);
mInputStream = mGetOperation.openInputStream(); // problem come out here
I send a get request to remote device but remote give a response code 211 which means
OBEX_SERVICE_UNAVAILABLE. So I cannot get phonebook from htc G11.
I try Nokia N9, it is the same with HTC G11. Nokia N9 give a response code 211 too.
But Nokia N9 and HTC G11 can transfer phonebook each other,
and both of them can get phonebook from android phones.
Android implement pbap session layer APIs in framework/base/obex
I guess HTC G11 does not use the standard android session layer APIs.
But what does it use? what about Nokia N9?
Can anyone give me an answer or some right codes? Please help me.
I suffered from this problem a lot.
Thanks!
My email: yulf88#gmail.com
Related
Situation:
VS 2022, 17.0.4
Maui App,
net6.0-android
AndroidManifest.xml contains also:
android.permission.INTERNET
android.permission.CHANGE_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
Connected mobile Phone:
Samsung SM-G960F (Android 10.0 - API 29)
OS: Windows 11, latest patch.
All firewalls are down (for testing purpose only!)
While debugging the develop computer is only connected to a Wifi network; computers ethernet card is disabled.
Mobile phone is connected to this dev computer via USB cable (to be able to debug) and to the same Wifi network as the computer.
App starts and works fine, app can be debugged. No issue at all - except:
After the application is fully initialized and ready to accept user interactions -> Click on button -> Desired method is called -> Code is worked out -> The code should make a simple UDP call but it does not (or the packet does not reach the UDP listener due to missing configuration?).
The UDP receiver works fine and is capable to receive UDP packets.
My mobile phone and the UDP receiver app are using the same port.
I read/found already that in the previous cross-platform framework, means “Xamarin (Android SDK 12)”, some permissions must be set (I did, see above) and that the multicastlock must be set over the WifiManager …
I tried this in my MAUI app. But could not find anything guiding me nor figured it out by myself.
My MAUI sending code:
var dataToBeSend = "What ever ...";
var data = Encoding.UTF8.GetBytes(dataToBeSend);
var UdpClient = new UdpClient();
// UdpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
UdpClient.ExclusiveAddressUse = false;
UdpClient.EnableBroadcast = true;
// UdpClient.Client.Bind(new IPEndPoint(IPAddress.Parse("255.255.255.255"), BroadcastPort));
// UdpClient.Client.Bind(new IPEndPoint(IPAddress.Any, BroadcastPort));
UdpClient.Send(data, data.Length, "255.255.255.255", BroadcastPort);
As said: very easy and straight forward.
Notice that I also tried binding UDP code …
So please can someone be so kind to guide me or give me a hint?
Thank you very much in advance!
ANSWER:
After two days I found a solution - and would like to share it because may be it helps someone else.
The code to make the UDP call msut be placed in a THREAD (not task!)
codesnippet:
var communication = new Communication();
var udpThread = new Thread(new ThreadStart(communication.FireUDPCall));
udpThread.Start();
The firewalls can stay turned on / active!
I want to make a data sharing app which uses WiFi-Direct where there's one Activity for the sender device where a QR Code would be displayed containing all the info about the device for other peers to connect to this one (like MAC Address , which device is the group owner, etc.)
The receiver devices would then scan the QR code and connect to the device after which the Sender would open the explorer to choose the data to send and then send it.
The Problem:
I am not able to find any way to just connect the devices directly using the give data instead of first scanning and then connecting.
Can anyone help me for this?
I think this tutorial will help you..
https://dzone.com/articles/android-device-matching-with-socket-programming
QRGEncoder qrgEncoder = new QRGEncoder(preSharedKey, null, QRGContents.Type.TEXT, smallerDimension);
ServerSocket server = new ServerSocket(6678);
Socket socket = server.accept();
I set up an openfire server on a server within our network and gave it a domain name. I want to connect to it via my phone in a phonegap app and therefore implemented a strophe.js client within my app.
It works fine on my Nexus 5 (Android 4.4.3), but as soon as I want to run it on my Samsung Galaxy S2 (Android 4.1.2) or the Samsung Galaxy Tab (GT-P7501 - Android 4.0.4) I don't get any response from the server. Here is the code snippet of my connect:
var BOSH_SERVICE = 'http://SERVERNAME:7070/http-bind/';
var connection = null;
$(document).ready(function () {
connection = new Strophe.Connection(BOSH_SERVICE);
connection.rawOutput = log;
connection.rawInput = log;
connection.connect('id#servername/resource', 'test', onConnect);
});
function log(msg) {
console.log(msg);
}
function rawInput(data) {
log('RECV: ' + data);
}
function rawOutput(data) {
log('SENT: ' + data);
}
the console log will be:
SENT: <body rid='367573377' xmlns='http://jabber.org/protocol/httpbind' to='servername' xml:lang='en' wait='60' hold='1' content='text/xml; charset=utf-8' ver='1.6' xmpp:version='1.0' xmlns:xmpp='urn:xmpp:xbosh'/>
This will be repeated a few times but I don't get any incoming messages. The servers version number is openfire 3.9.3. As all this code works on my nexus 5 I assume that the code is correct. I Also doubt that my server is configured wrong, nevertheless I included a screenshot of the config settings of the openfire server in the end.
The openfire xmpp server is running on a windows server and I access it via wifi/dyndns.
Do you have any ideas why this does not work on the samsung galaxy? Every help will be appreciated. Thanks in advance !
I could "solve" this by myself. It is really not a big deal, but it took me a really long time (3 days) to realize this, so in case anyone will ever come accross the same phenomena this info might help:
In my case all the configurations of the server and the strophe client above are correct. Indeed the only reason the connect did not work properly on all devices seemed to be that these devices could not even ping the server, even though they are in the same network. In my case I gave the server a static domain name, which was the key issue. Somehow the Google Nexus 5 is able to resolve this name to an ip adress via the dns-server, but both the elder samsung galaxy s2 and the samsung galaxy tab aren't.
Solution: I replaced the static domain name with the corresponding ip-adress in my strophe.js connection.
I am new to android. I am just trying to connect my Android device to PC and pass a string to PC using Bluetooth. I have no idea on how to do it. Android side I read about the Bluetooth API. Please suggest me some ways to do it. Thanks in advance.
For Android, my code is slightly different from yours:
BluetoothSocket socket = Device.createRfcommSocketToServiceRecord(device_UUID);
socket.connect();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeChar('x'); // for example
socket.close();
I used DataOutputStream to send data to PC. But surely this doesn't matter, just for your reference.
For PC,
LocalDevice localDevice = LocalDevice.getLocalDevice();
localDevice.setDiscoverable(DiscoveryAgent.GIAC); // Advertising the service
String url = "btspp://localhost:" + device_UUID + ";name=BlueToothServer";
StreamConnectionNotifier server = (StreamConnectionNotifier) Connector.open(url);
StreamConnection connection = server.acceptAndOpen(); // Wait until client connects
//=== At this point, two devices should be connected ===//
DataInputStream dis = connection.openDataInputStream();
char c;
while (true) {
c = dis.readChar();
if (c == 'x')
break;
}
connection.close();
I am not sure if the above codes still work today, as this was done 2 years ago. The BlueCove API may have changed a lot. But anyway, these codes work for me. Hope this may help you.
One more note is that, I had to uninstall the Toshiba Bluetooth Driver in my PC and reinstall the Microsoft one in order to make use of BlueCove. Otherwise, it won't work. (However, latest version of BlueCove may have already supported different drivers, please correct me if I said anything wrong.)
(Author: Victor Wong)
For clarification: on the PC side, you usually have a bluetooth device that comes with a virtual COM port. For testing purposes, you can use any terminal program (e.g. http://realterm.sourceforge.net/). When you start it on your virtual bluetooth serial port and connect your Android device, it will show the received data.
I have been playing around with the bluetooth API for Android 2.2 (API level 8, HTC Desire) and had an app connecting to an embedded Bluetooth device using:
device.createRfcommSocketToServiceRecord(DEV_UUID);
This generated a pairing request as expected, however to streamline the connection process I wanted to avoid the user interaction when pairing so moved to API level 10 (HTC Desire with CyanogenMod 7) so I could use:
device.createInsecureRfcommSocketToServiceRecord(DEV_UUID);
When testing this also works as expected (connecting without prompting the user to pair), however when I try to create the secure RfcommSocket under API level 10 as before with 2.2 I get a connection refused exception...
java.io.IOException: Connection refused
at android.bluetooth.BluetoothSocket.connectNative(Native Method)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:204)
As far as I can tell this should still work in the same way, prompting the user to pair?
EDIT:
Just tried again using the following code and the outcome is the same (working for insecure but not for secure), I will try and get my hands on a stock 2.3 device to test on.
try {
Method m = dev.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class } );
BluetoothSocket bs = (BluetoothSocket)m.invoke(dev, devUUID);
Log.d("TEST", "Method Invoked");
bs.connect();
Log.d("TEST", "Connected to socket");
bs.close();
Log.d("TEST", "Closed Socket");
}
While looking for the solution of similar problem in my app, I have found this blog from code.google.com
It will help all those who are still looking for this problem solution on SO
http://mobisocial.stanford.edu/news/2011/03/bluetooth-reflection-and-legacy-nfc/ (link not working anymore)
The solution has become very simple now. Just include InsecureBluetooth.java in your project and change 2 lines in BluetoothChatService.java.
tmp = InsecureBluetooth.listenUsingRfcommWithServiceRecord(mAdapter, NAME, MY_UUID, true);
and
tmp = InsecureBluetooth.createRfcommSocketToServiceRecord(device, MY_UUID, true);
Thats it !