Android Bluetooth Bağlantısı – 2

Merhaba arkadaşlar,

Bluetooth bağlantısı yazı dizisinin ilk bölümünde sizlere bluetooth desteği olan android cihazlarda bluetooth nasıl aktif hale getirilir, nasıl kapatılır özelliklerinden bahsetmiştim. İlk bölüme buradan ulaşabilirsiniz. Bluetooth bağlantısı yazı dizisinin ikinci bölümünde sizlere cihazınızı diğer cihazlar tarafından bulunabilir hale getirmeyi, bulunabilir cihazları listelemeyi ve diğer cihazlarla eşleştirmeyi anlatacağım.

Not: Bu yazı içerisindeki kod parçalarının anlamlı olabilmesi için birinci bölümdeki kodların incelenmesi gerekmektedir.

Android cihazlarda diğer bluetooth cihazlara sunucu olarak destek verecek bir yazılım yapıyorsak cihazımızın diğer cihazlar tarafından görünebilir olması gerekmektedir. Aksi takdirde diğer bluetooth cihazlar tarafından bizim cihazımız görünmediği için arada bir bağlantı kurmak mümkün olmayacaktır. Cihazımızı görünür yapmak için aşağıdaki kod parçasından faydalanabiliriz.

private void makeBTDiscoverable() {
   Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
   discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
   startActivityForResult(discoverableIntent, BT_VISIBLE_ENABLE);
}

Stardart olarak 120 saniye olan bulunma süresini yukarıdaki kod parçasında,

discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);

satırıyla birlikte 300 saniyeye çıkarttık. Bu parametre 0 ile 3600 aralığında istediğiniz değeri alabilir. Bu aralık dışında bir sayı girdiğinizde değer otomatik olarak 120 saniye olarak değer alacaktır. Değeri 0 yaptığınız takdirde diğer cihazlar tarafından bulunabilirliği sürekli olarak açık hale getirmiş olursunuz.

Bulunabilirliği aktif hale getirdikten sonra durum bilgisi onActivityResult methodu ile alınabilir. Bunu basit olarak örneklememiz gerekirse;

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == BT_VISIBLE_ENABLE) {
       //Cihaz başarılı bir şekilde bulunabilir hale getirildi.
    } else {
       //Cihaz bulunabilir hale getirilirken bir hata ile karşılaşıldı!
    }
}

Yukarıdaki kodu arayüz tasarımımızda bir CheckBox ile kontrol edebilir veya aynı şekilde ToggleButton kullanabiliriz.

Cihazımızı bulunabilir hale getirdikten sonra, diğer cihazları bulup listeleme işlemini gerçekleştirebiliriz. Bunun için aşağıdaki kod parçasından faydalanabiliriz. Öncelikle arayüz tasarımında bir ListView ekleyerek bulunan cihazların bu ListView’de listelenmesini sağlayabiliriz.

<ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btListView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"/>

Arayüze ListView ekledikten sonra tekrar MainActivity dönüp btListView içerisini doldurmak için gerekli işlemleri yapabiliriz.

private ListView btListView;
private ArrayList<String> btDeviceList;
private ArrayAdapter btArrayAdapter;

//bu işlemleri cihazları bulma işlemini başlatacağınız Listener içerisinde gerçekleştirebilirsiniz.
btListView = (ListView) findViewById(R.id.btListView);
btDeviceList = new ArrayList<String>();
btArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, btDeviceList);
//Bu fonksiyon ile cihazları tarama işlemini gerçekleştirebilirsiniz.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
            //Cihaz bulunduğunda ne yapılacağını bu adımda gerçekleştiriyoruz
            if(BluetoothDevice.ACTION_FOUND.equals(action)) {

                String deviceInfo = "";
                Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();

                //Intent sınıfından BluetoothDevice nesnesini alıyoruz
                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                deviceInfo += btDevice.getName() + "\n" + btDevice.getAddress();
                btDeviceList.add(btDevice);

                if(btDevice.getBondState() == BONDED_DEVICE) {
                    Log.d("BluetoothDevice", "Eslestirilmis cihaz bulundu.");
                    deviceInfo += " (ESLESTIRILMIS)";
                    isPaired = true;
                }
                btDeviceList.add(deviceInfo);
                btListView.setAdapter(btArrayAdapter);
                btListView.refreshDrawableState();
      }
   }
};

Bu adımları gerçekleştirdikten sonra uygulamayı cihazımızda çalıştırıp tarama işlemini başlattığımızda etrafta bulunan ulaşılabilir bluetooth cihazların isimleri MAC adreslerini listeleyecektir.

ListView içerisinde listelenen cihazlarla bağlantı kurabilmek için bir cihazın sunucu(server) olarak servis açıp bağlantı beklemesi gerekmekte, diğer cihazında yine sunucu(server) veya kullanıcı(client) olarak bağlantı isteği göndermesi gerekmektedir. Bu işlemler için iki ayrı Thread sınıfı oluşturarak bu işlemleri Threadler üzerinden gerçekleştirebiliriz.

Sunucu(Server) bağlantısı için gerekli kodlar aşağıdaki gibidir.

public class ServerBTConnection extends Thread {
    private final BluetoothServerSocket serverSocket;
    private static final String serviceName = "BluetoothDataTransfer";

    public ServerBTConnection(BluetoothAdapter btAdapter) {
        Log.d("BluetoothDevice Server", "Bluetooth Server Connection Thread calisiyor...");
        BluetoothServerSocket tempServerSocket = null;
        try {
            tempServerSocket = btAdapter.listenUsingRfcommWithServiceRecord(serviceName, UUID.fromString("f4798eca-54ed-49b7-8b12-925b1084aa5a"));
        } catch (IOException e) {
            Log.d("BluetoothDevice Server", "BluetoothServerSocket Hata: " + e.toString());
        }
        serverSocket = tempServerSocket;
    }
    @Override
    public void run() {
        BluetoothSocket btSocket = null;
        while(true) {
            try {
                btSocket = serverSocket.accept();
            } catch (IOException e) {
                Log.d("BluetoothDevice Server", "Gelen baglanti istegi kabul edilmedi.");
                break;
            }
            if(btSocket != null) {
                Log.d("BluetoothDevice", "Socket baglanti istegi kabul edildi.");
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    Log.d("BluetoothDevice Server", "ServerSocket baglantisi kapatilamadi: " + e.toString());
                }
                break;
            }
        }
    }
}

Bu Thread’i MainActivity sınıfından başlanmak için;

Thread serverThread = new ServerBTConnection(bluetoothAdapter);
serverThread.run();

Kullanıcı(Client) bağlantısı için gerekli kodlar ise;

public class ClientBTConnection extends Thread {

    private BluetoothSocket btSocket;
    private BluetoothDevice btDevice;
    private static final String uuidVal = "f4798eca-54ed-49b7-8b12-925b1084aa5a";

    public ClientBTConnection(BluetoothDevice device) {
        Log.d("BluetoothDevice Client", "Bluetooth Client Connection Thread calisiyor...");
        BluetoothSocket tempSocket = null;
        btDevice = device;
        try {
            tempSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(uuidVal));
        } catch (IOException e) {
            Log.d("BluetoothDevice Client", "RFCOMM socket olusturulamadi: " + e.toString());
        }
        btSocket = tempSocket;
    }

    @Override
    public void run() {
        try {
            btSocket.connect();
        } catch (IOException e) {
            Log.d("BluetoothDevice Client", "Baglanti basarisiz: " + e.toString());
            try {
                btSocket.close();
            } catch (IOException e1) {
                Log.d("BluetoothDevice Client", "Baglanti kapatma basarisiz: " + e.toString());
            }
            return;
        }
    }
}

Bu Thread’i MainActivity sınıfında başlatmak için;

Thread clientThread = new ClientBTConnection(bluetoothDevice);
clientThread.run();

kodu kullanılabilir. Yazılan uygulamada bağlantının başarılı bir şekilde sağlanması için UUID değerlerinin aynı olmasına dikkat edilmelidir. Yukarıdaki yapıyı bir cihaz sunucu(server) başka bir cihaz yine sunucu(server) veya kullanıcı(client) olacak şekilde kurabilir ve bu şekilde sunucu socket açıp istek beklemeye başladığında diğer cihaz tarafından bağlantı isteği yollanabilir. Bu şekilde iki cihaz arasında bağlantı sağlanacağı gibi eşleştirme işlemide gerçekleştirilmiş olacaktır.

Örnek kodun tamamına GitHub üzerinden erişebilirsiniz.

Konuyla ilgili her türlü soru ve yorumlarınızı aşağıdaki form aracılığı ile bana ulaştırabilirsiniz.

3

Eren Başaran

Software Developer
Mobilhanem Yazarı

9 Yorum

  • Teşekkürler elinize sağlık ancak
    The application may be doing too much work on its main thread.
    sorunun yaşıyorum bunu nasıl çözebilirim?

    • Merhaba,
      Bu problem tüm işlemleri arayüz thread’inde yapıldığı zaman ortaya çıkabilir. İşlemleri daha küçük parçalara ayırarak UI Thread yapısından ayırırsanız problem çözülecektir. Bu hatayı sadece bu kodlar için değil UI Thread yapısı altında bir çok işlem yaptığınız tüm projelerde alabilirsiniz.

  • MERHABA..EMEĞİNİZE SAĞLIK..ÇOK TESEKKÜR EDERİM..git hub dan programı yükledim HC 05 görüyor,fakat baglantıyı kuramadım..(mit app invertor 2 de bağlantıyı sağladım)…eksiğim nerededir.?..ilgine şimdiden tesekkürler..iş hayatın da başarılar..

    • onActivityResult içerisini aşağıdaki gibi düzenleyip. bir dosyayı transfer edebilirsiniz. (alıntıdır)

      if(resultCode==DISCOVER_DURATION&&requestCode==REQUEST_BLU){
      Intent intent=new Intent();
      intent.setAction(Intent.ACTION_SEND);
      intent.setType(“text/plain”);
      File f = new File(Environment.getExternalStorageDirectory(),”/dosyaismi.txt”);
      intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(f));

      PackageManager pm= getPackageManager();
      List appsList=pm.queryIntentActivities(intent,0);

      if(appsList.size() > 0){
      String packageName=null;
      String className=null;
      boolean found=false;

      for(ResolveInfo info:appsList){
      packageName=info.activityInfo.packageName;
      if(packageName.equals(“com.android.bluetooth”)){
      className=info.activityInfo.name;
      found=true;
      break;
      }
      }

      if (!found){
      TOASTMSG(“Bluetooth haven’t been found”);
      }else{
      intent.setClassName(packageName,className);
      startActivity(intent);
      }
      }
      }else{
      TOASTMSG(“Bluetooth cancelled”);
      }
      }

  • Merhabalar. Programlama dersi için ödev olarak “Bluetooth RGB Bulp Controller” yapıyorum. Yazı dizinizdeki uygulamalar çok işime yaradı öncelikle onun için çok teşekkür ederim.
    Yanlız kafama takılan bi durum var;
    Renk kontrolünü ardüino ile yapınca veri göndereceğimiz yerleri biliyor ve ona göre gönderiyoruz ancak hoca bana e27 ampul (kendi uygulaması olan) bi lamba aldırdı. Tamamen ticari ve kapalı kutu olan bi lambaya renk verisi gönderimi mümkün mü, mümkünse nasıl? Şimdiden teşekkür ederim. İyi çalışmalar.

    • Merhaba,

      e27 ampül muhtemelen bir API sunuyordur. O API kullanılarak iletişim kurulabilir. Fakat API ücretli ise veya bir şekilde ulaşamıyorsan iletişim kurmak biraz şansa birazda önceki tecrübelerden iletişimi nasıl kuracağı ile ilgili tahminlere kalıyor.

  • Mesela üç 05 in alanından çıktık ve bağlantı koptu,geri yaklastigimizda otomatik bağlantı yapacak kod var mı,hani kullanıcı her defasında ugrasmasin diye

  • merhaba hocam verdiğiniz kodları inceledim ve aygıt tarama kısmını kendi projeme entegre ettim
    fakat uygulama durdu hatası alıyorum yardımcı olurmusunuz

Haftalık Bülten

Mobilhanem'de yayınlanan dersleri haftalık mail almak ister misiniz?