Я хочу подключить общее устройство midp2 j2me, поддерживающее bluetooth (jsr082), к устройству Android, используя аналогичное пользовательское приложение, которое я пишу. Android-устройство только появляется, чтобы "видеть" другие Android-устройства Bluetooth поблизости?
Возможно ли это?
Да, это возможно, вам нужно будет использовать отражение, чтобы поразить несколько методов (которые не документально), чтобы получить такое же поведение, как и j2me.
createRfcommSocket(int channel)
в android.bluetooth.BluetoothDevice
как
Class cls = Class.forName("android.bluetooth.BluetoothDevice");
java.lang.reflect.Method meth = cls.getMethod("createRfcommSocket", new Class[] { Integer.TYPE});
BluetoothSocket iBluetoothSocket = (BluetoothSocket) meth.invoke(theBTDevice,new Object[] { new Integer(channel)});
и
// getUuids() also in android.bluetooth.BluetoothDevice
// i.e.
Class cls = Class.forName("android.bluetooth.BluetoothDevice");
java.lang.reflect.Method meth = cls.getMethod("getUuids", new Class[0]);
ParcelUuid[] uuidlist = (ParcelUuid[]) meth.invoke(theBTDevice);
немного информации об использовании можно найти здесь:
Методы доступны в более ранних версиях android (я думаю, из 2.0), но являются частными, поэтому требуется отражение (возможно, они были непроверены и, следовательно, скрыты).
Мне недавно пришлось это сделать. Я использовал api 8, поэтому только
BluetoothAdapter.listenUsingRfcommWithServiceRecord(String,UUID);
официально доступен.
Так как Android не позволяет просматривать постоянную видимость, я работал со списком устройств, сохраненных моим приложением.
Здесь упрощается мой код, который устанавливает Android как сервер с прослушивающим сокетом и телефоном j2me (я использовал Nokia N95) в качестве клиента для создания соединения RFCOMM.
Здесь Android-материал:
int bytes = 0, offset = 0;
byte[] buffer;
BluetoothServerSocket btServerSocket = btAdapter.listenUsingRfcommWithServiceRecord("serv",myUUID);
BluetoothSocket btSocket = btServerSocket.accept();
OutputStream out = btSocket.getOutputStream();
InputStream in = btSocket.getInputStream();
bytes = in.read();
buffer = new byte[bytes];
out.write(0);
out.flush();
while (true)
{
bytes = in.read(buffer, offset, buffer.length - offset);
offset += bytes;
if (bytes == -1 || offset >= buffer.length)
{
Log.d("MyBT", "message: " + new String(buffer));
break;
}
}
out.close();
in.close();
btSocket.close();
btServerSocket.close();
и здесь материал J2ME:
class ARemoteDevice extends javax.bluetooth.RemoteDevice
{
public ARemoteDevice(String btaddr)
{
super(btaddr);
}
}
RemoteDevice targetDevice = new ARemoteDevice("00FF00FF00FF");
String message = "Hello my dear android device";
UUID[] uuidSet = {new UUID("yourUUIDHERE",false)};
Vector URLS = new Vector();
int ENCRYPTMODE = ServiceRecord.AUTHENTICATE_ENCRYPT;
final Object serviceSearchCompletedEvent = new Object();
DiscoveryListener listener = new DiscoveryListener()
{
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {}
public void inquiryCompleted(int discType) {}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord)
{
for (int i = 0; i < servRecord.length; i++)
{
String connectionURL = servRecord[i].getConnectionURL(ENCRYPTMODE, false);
if (connectionURL != null)
{
URLS.addElement(connectionURL);
}
}
}
public void serviceSearchCompleted(int transID, int respCode) {
synchronized (serviceSearchCompletedEvent) {
serviceSearchCompletedEvent.notifyAll();
}
}
};
synchronized (serviceSearchCompletedEvent) {
discAgent.searchServices(null, uuidSet, targetDevice, listener);
serviceSearchCompletedEvent.wait();
}
if (URLS.isEmpty())
{
System.out.println("no connectionurl found");
return;
}
try {
for (int i = 0; i < URLS.size(); ++i) {
System.out.println("Trying: " + (String) URLS.elementAt(i));
try {
sc = (StreamConnection) Connector.open((String) URLS.elementAt(i));
in = sc.openInputStream();
out = sc.openOutputStream();
out.write(length);
out.flush();
in.read();
try {
Thread.sleep(50);
} catch (Exception e) {
e.printStackTrace();
}
break;
} catch (Exception e) {
sc = null;
System.out.println("Failed BT COnn");
}
} // TODO: handle case if all URLS fail
int bytesSent = 0;
int bytesToSend = 0;
int length=message.length();
int MTU=256;//or whatever..?
while (true) {
if ((length - bytesSent) > MTU) {
bytesToSend = MTU;
} else {
bytesToSend = length - bytesSent;
}
out.write(message.getBytes(), bytesSent, bytesToSend);
out.flush();
bytesSent += bytesToSend;
if (bytesSent >= length) {
Thread.sleep(200);
break;
}
}
if (in != null) {
in.close();
in = null;
}
if (out != null) {
out.close();
out = null;
}
if (sc != null) {
sc.close();
sc = null;
}
}
это позволило моему устройству Android принять сообщения, отправленные из j2me. Я скопировал важные части из моего кода, поэтому я не уверен, что все это работает, потому что я не пробовал выполнить его inline, поскольку я представляю его здесь, но вы должны быть в состоянии заполнить все ошибки, которые я сделал, когда копирование вставляет это.
Удачи!