Das habe ich bereits implementiert. Hier mein Code für den Verbindungsaufbau:
Java
package com.maiermar.testmenuestruktur;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Message;import android.util.Log;
public class VerbindungsService
{
// Debugging im LogFileprivate static final String TAG = "VerbindungsService";
private static final boolean D = true;
// Name für SDP Record, wenn ein Sock erstellt wirdprivate static final String NAME = "VerbindungsService";
// UUID für die Applikation (notwendig um Verbindung aufzubauen)private static final UUID MEINE_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
// Benötigte Objekteprivate final BluetoothAdapter meinBTAdapter;
private ServerThread meinServer;
private ClientThread meinClient;
// private VerbindungsThread meineVerbindung;private int meinStatus;
// Konstanten um den Verbindungsstatus zu identifizierenpublic static final int STATUS_NULL = 0;
public static final int STATUS_WARTEN = 1;public static final int STATUS_VERBINDEN = 2;public static final int STATUS_VERBUNDEN = 3;
// Konstruktorpublic VerbindungsService (Context context)
{meinBTAdapter = BluetoothAdapter.getDefaultAdapter();meinStatus = STATUS_NULL;
}
// Methode zum anzeigen des aktuellen Statusprivate synchronized void setState(int state)
{ if (D)
{Log.d(TAG, "setState() " + meinStatus + " -> " + state);
}meinStatus = state;
}
// Liefert aktuellen Status zurückpublic synchronized int getState()
{ return meinStatus;
}
//Startet Verbindungssessionpublic synchronized void start()
{ if (D) Log.d(TAG, "start");
// Cancel any thread attempting to make a connection if (meinClient != null)
{meinClient.cancel(); meinClient = null;
}
setState(STATUS_WARTEN);
// Start the thread to listen on a BluetoothServerSocket if (meinServer == null)
{ meinServer = new ServerThread(); meinServer.start();
}
}
// Methode zum Verbinden von zwei Gerätenpublic synchronized void connect(BluetoothDevice device, boolean secure)
{ if (D)
Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection if (meinStatus == STATUS_VERBINDEN)
{ if (meinClient != null)
{meinClient.cancel(); meinClient = null;
}
} meinClient = new ClientThread(device);
meinClient.start(); setState(STATUS_VERBINDEN);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device)
{if (D)
{Log.d(TAG, "connected");
}
// Cancel the thread that completed the connectionif (meinClient != null)
{meinClient.cancel(); meinClient = null;
}
// Cancel any thread currently running a connection
// if (meineVerbindung != null)
// {
// meineVerbindung.cancel();
// meineVerbindung = null;
// }
// Cancel the accept thread because we only want to connect to one deviceif (meinServer != null)
{meinServer.cancel();meinServer = null;
}// Start the thread to manage the connection and perform transmissions
// meineVerbindung = new VerbindungsThread(socket);
// meineVerbindung.start();
setState(STATUS_VERBUNDEN);
}
// Stoppt alle Threadspublic synchronized void stop()
{if (D)
{Log.d(TAG, "stop");
}
if (meinClient != null)
{meinClient.cancel();meinClient = null;
}if (meinServer != null)
{
meinServer.cancel();meinServer = null;
}setState(STATUS_NULL);
}
// Aufruf bei fehlgeschlagener Verbindungprivate void connectionFailed()
{ if (D)
{Log.d(TAG, "connectionFailed");VerbindungsService.this.start();
}
}
//Benötigt für: verbindungsmanager (3.Thread)
// private void connectionLost()
// {
// if(D)
// {
// Log.d(TAG, "Verbindung unterbrochen!");
// }
// VerbindungsService.this.start();
// }
// Implementierung des ServerKlasseprivate class ServerThread extends Thread
{private final BluetoothServerSocket meinServerSocket;public ServerThread()
{
BluetoothServerSocket tmp = null;try
{
// MY_UUID -> String der App, auch vom Clientcode genutzttmp = meinBTAdapter.listenUsingRfcommWithServiceRecord(NAME,MEINE_UUID);
} catch (IOException e)
{Log.e(TAG,"listen() failed", e);
}meinServerSocket = tmp;
} public void run()
{if (D) Log.d(TAG,"BEGIN meinServer" + this);
BluetoothSocket socket = null;
// Solange warten, bis Socket geliefert wirdwhile (true)
{try
{socket = meinServerSocket.accept();
} catch (IOException e)
{Log.e(TAG, "accept() failed", e);break;
}
// Wenn Verbindung akzeptiert wurde,if (socket != null)
{synchronized (VerbindungsService.this)
{switch (meinStatus)
{case STATUS_WARTEN:case STATUS_VERBINDEN:
{
connected(socket, socket.getRemoteDevice());break;
}case STATUS_NULL:
case STATUS_VERBUNDEN:
// Either not ready or already connected. Terminate new socket.try
{
socket.close();
} catch (IOException e)
{Log.e(TAG, "Could not close unwanted socket", e);
}break;
}
}
}
}
}public void cancel()
{if (D) Log.d(TAG,"cancel " + this);try
{meinServerSocket.close();
}catch (IOException e)
{Log.e(TAG,"close() of server failed",e);
}
}
}
//Implementierung der ClientKlasseprivate class ClientThread extends Thread
{private final BluetoothSocket meinSocket;
//Benötigt für: verbindungsmanager (3.Thread)private final BluetoothDevice meinDevice; public ClientThread(BluetoothDevice device)
{
BluetoothSocket tmp = null;meinDevice = device;
// Socket erstellen, mit gegebenem (gepaarten) Gerät verbindentry
{
// MY_UUID -> String der App, auch vom Servercode genutzttmp = device.createRfcommSocketToServiceRecord(MEINE_UUID);} catch (IOException e)
{Log.e(TAG, "create() failed", e);
}meinSocket = tmp;
}public void run()
{
Log.i(TAG, "BEGIN meinClient");meinBTAdapter.cancelDiscovery();try
{ meinSocket.connect();
}catch (IOException connectException)
{try
{meinSocket.close();
}catch (IOException closeException)
{Log.e(TAG, "unable to close() ", closeException);
}
//connectionFailed();return;
}synchronized (VerbindungsService.this)
{meinClient = null;
}
// Start the connected threadconnected(meinSocket, meinDevice);
}public void cancel()
{try
{meinSocket.close();
}catch (IOException e)
{Log.e(TAG, "close() of connection failed ", e);
}
}
}
}
Alles anzeigen
Nun noch der Code der Mainactivity:
Code
package com.maiermar.testmenuestruktur;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;import android.widget.Toast;
public class TestMenuestrukturActivity extends Activity
{
// Debugging im LogFileprivate static final String TAG = "VerbindungsService";
private static final boolean D = true;
// Intent Request Codesprivate static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_CONNECT_SECURE = 1;
// Objekt für ActionBarprotected Object mActionMode;
// Lokaler BT Adapterprivate BluetoothAdapter mBluetoothAdapter = null;
// Benutzerobjekt für verbindungsServiceprivate VerbindungsService meinVerbindungsService = null;
/*
* Hier wird die Hauptactivity aufgerufen und deren Layout festgelegt. BT wird auf verfügbarkeit überprüft
*/
@Overridepublic void onCreate(Bundle savedInstanceState)
{super.onCreate(savedInstanceState);setContentView(R.layout.main);
/* Hier wird festgelegt, was passieren soll, wenn lange auf ein Element geklickt wird (Rechtsklick mit Maus)
* Dazu wird ein setOnLongClickListener() implementiert. Dieser funktioniert genauso wie der setOnClickListener().
* Nur dass das Element länger gedrückt werden muss.
*/View vTextfeld = findViewById(R.id.etEingabe);vTextfeld.setOnLongClickListener(new View.OnLongClickListener()
{
// Methode die Aufgerufen wird, wenn lange auf ein Element geklickt wird.public boolean onLongClick(View view)
{if (mActionMode != null)
{return false;
}mActionMode = TestMenuestrukturActivity.this.startActionMode(mActionModeCallback);
view.setSelected(true);return true;
}
});mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if (mBluetoothAdapter == null)
{Toast.makeText(this,getString(R.string.tsKeinBT), Toast.LENGTH_SHORT).show();
}
}
@Overridepublic void onStart()
{super.onStart();if(D)
{Log.e(TAG, "++ ON START ++");
}
// Bluetooth einschaltenif (!mBluetoothAdapter.isEnabled())
{Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Fals BT bereits aktiviert, Verbindungssession
} else
{if (meinVerbindungsService == null) setupChat();
}
}
@Overridepublic synchronized void onResume()
{super.onResume();if(D)
{Log.e(TAG, "+ ON RESUME +");
}if (meinVerbindungsService != null)
{
// OÜberprüfung ob VerbindungsService bereits gestartet istif (meinVerbindungsService.getState() == VerbindungsService.STATUS_NULL)
{
// Startet VerbindungsServicemeinVerbindungsService.start();
}
}
}
private void setupChat()
{Log.d(TAG, "setupChat()");
// Initialize the BluetoothChatService to perform bluetooth connectionsmeinVerbindungsService = new VerbindungsService(this);
}
@Overridepublic synchronized void onPause()
{super.onPause();if(D)
{Log.e(TAG, "- ON PAUSE -");
}
}
@Overridepublic void onStop()
{super.onStop();if(D)
{Log.e(TAG, "-- ON STOP --");
}
}
@Overridepublic void onDestroy()
{super.onDestroy();
// Stop the Bluetooth chat servicesif (meinVerbindungsService != null)
{meinVerbindungsService.stop();
}if(D)
{Log.e(TAG, "--- ON DESTROY ---");
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data)
{if(D)
{Log.d(TAG, "onActivityResult " + resultCode);
}switch (requestCode)
{case REQUEST_CONNECT_SECURE:
// When DeviceListActivity returns with a device to connectif (resultCode == Activity.RESULT_OK)
{connectDevice(data, true);
}break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returnsif (resultCode == Activity.RESULT_OK)
{
// Bluetooth is now enabled, so set up a chat session
setupChat();
} else
{
// User did not enable Bluetooth or an error occurredLog.d(TAG, "BT not enabled");Toast.makeText(this, R.string.notFound, Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void connectDevice(Intent data, boolean secure)
{
// Get the device MAC addressString address = data.getExtras().getString(Aktualisieren.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice objectBluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the devicemeinVerbindungsService.connect(device, secure);
}
/*
* Ab hier werden nur noch die Menüs angelegt. Bluetooth ist hier abgeschlossen.
*/
@Overridepublic boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.actionbar, menu); return true;
}
@Overridepublic boolean onOptionsItemSelected(MenuItem item)
{Intent serverIntent = null;switch (item.getItemId())
{
case R.id.abRegionaleinstellung:Toast.makeText(this,getString(R.string.tsRegionalEinstellung), Toast.LENGTH_SHORT).show();
break;case R.id.abAktualisieren:
serverIntent = new Intent(this, Aktualisieren.class);startActivityForResult(serverIntent, REQUEST_CONNECT_SECURE);
return true;case R.id.abAnalyse:
Toast.makeText(this,getString(R.string.tsSieHaben) + " " + getString(R.string.abAnalyse) + " " + getString(R.string.tsGewaehlt), Toast.LENGTH_SHORT).show();break;
case R.id.abBeenden:Toast.makeText(this,getString(R.string.tsSieHaben) + " " + getString(R.string.abBeenden) + " " + getString(R.string.tsGewaehlt), Toast.LENGTH_SHORT).show();
break;case R.id.abDokumentation:
Toast.makeText(this,getString(R.string.tsSieHaben) + " " + getString(R.string.abDokumentation) + " " + getString(R.string.tsGewaehlt), Toast.LENGTH_SHORT).show();break;
case R.id.abFeldsatz:Toast.makeText(this,getString(R.string.tsSieHaben) + " " + getString(R.string.abFeldsatz) + " " + getString(R.string.tsGewaehlt), Toast.LENGTH_SHORT).show();
break;case R.id.abOptionen:
Toast.makeText(this,getString(R.string.tsSieHaben) + " " + getString(R.string.abOptionen) + " " + getString(R.string.tsGewaehlt), Toast.LENGTH_SHORT).show();break;
case R.id.abStatusmeldung:Toast.makeText(this,getString(R.string.tsSieHaben) + " " + getString(R.string.abStatusmeldung) + " " + getString(R.string.tsGewaehlt), Toast.LENGTH_SHORT).show();
break;default:break;
}return true;
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback()
{
// onCreate() erstellt das Kontexmenü (vgl. onCreate() beim Layout oder ActionBar (Vorlage: XML Menüfile)public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
// Bindet Kontexmenü ein
MenuInflater inflater = mode.getMenuInflater();inflater.inflate(R.menu.contexmenu, menu);return true;
}
// Wird immer aufgerufen wenn Kontexmnü geöffnet ist.public boolean onPrepareActionMode(ActionMode mode, Menu menu)
{return false;
}
// Methodenaufruf falls Menüpunkt <<Toast>> gewählt wurde und beendet das Kontexmenüpublic boolean onActionItemClicked(ActionMode mode, MenuItem item)
{switch (item.getItemId())
{case R.id.cmToast:Toast.makeText(TestMenuestrukturActivity.this,getString(R.string.tsDateiGespeichert),Toast.LENGTH_LONG).show();
mode.finish();
return true;default:return false;
}
}
// "Zerstört" das Kontexmenü (wird gelöscht)public void onDestroyActionMode(ActionMode mode)
{mActionMode = null;
}
};
}
Alles anzeigen