Android Bluetooth Programlama 1

Genel Bakış

Bluetooth programlamanın giriş yazısında kısa bir önbilgi vermiştik. Birinci bölüm olan bu bölümde bluetooth uygulama projemizi oluşturup ilk işlemleri gerçekleyeceğiz. İlk işlemlerimiz:

  • Bluetooth donanımını etkinleştirme
  • Bluetooth donanımını etkisizleştirme
  • Bluetooth donanımının durum değişimini sistem tarafından bilgi alma olacaktır.

Bluetooth'u etkinleştirme ve etkisizleştirme işlemini arayüzde basit bir tuş (button) kullanarak yapacağız. Ayrıca Android Studio'nun hata ayıklama (debug) ekranından yararlanarak program çalışırken neler olduğunu gözleyeceğiz.

Başlamadan önce küçük bir not

Ben eğitimi Linux işletim sistemi üzerinde hazırlıyorum. Farklı platformlarda çalışanlarınız olacaktır. Dolayısıyla farklı platformlarda bazı işlemlerin yapılışı burada anlattığımdan farklı olabilir. Eğer olursa, bu gibi farkları kapatmayı siz değerli okuyucularımıza bırakıyorum.

Bluetooth Açma, Kapatma, Durum Bilgisi Alma

Android Studio'yu başlattıktan sonra sıfırdan yeni proje oluşturarak bluetooth'u kontrol edecek kodları yazacağımız aşamaya dek adım adım ilerleyelim...

1. Projeyi Oluşturma

Yeni proje oluşturma

Yeni proje oluştur penceresinde Boş Etkinlik (Empty Activity) seçeneğini seçip Sonraki (Next) tuşuna basalım.

2. Yeni Projeyi Yapılandırma

Yeni projeyi yapılandırma

  • Bu ekranda Ad (Name) kutusuna istediğiniz bir adı proje adı olarak girebilirsiniz. Ben, "Bluetooth Gelistirme" olarak adlandırdım.
  • Kayıt konumu (Save location) kutusundaki klasör simgesine tıklayıp projeniz için özel bir konum seçebilirsiniz.
  • Dil (Language) olarak Java seçili olmalıdır.
  • En düşük (Minimum) SDK bölümünde SDK'yi Android 5.0 olarak seçtim. Daha aşağısını önermiyorum çünkü BluetoothLE (Bluetooth Low Energy) donanımı 4.3 sürümünden öncekilerde bulunmuyor. Biraz daha ileriki bölümlerde BluetoothLE ile ilgili eğitimler hazırlamayı planladığım için size önerim 5.0 sürümünden aşağı düşmemenizdir.
  • Artık Bitir (Finish) tuşuna tıklayarak programlamaya başlayabiliriz.

3. Bizi Main Activity Karşılar

Main Activity kod ekranı

Yeni projemizi oluşturduktan sonra bu şekilde kod ekranı bizi karşılayacaktır. Kodlamaya başlamadan önce yapmamız gereken küçük bir işimiz olacak...

4. GUI Tasarım Ekranı

GUI tasarım ekranı

Proje ilk açıldığında tasarım ekranında bir programcılık klasiği olan "Hello World!" yazısı ile karşılaşırız. Bu yazının barındırıcısı bir TextView denetimidir. Nitekim şu an için uygulamamızda bir TextView denetimine gerek duymuyoruz. Dolayısıyla bu denetimi imleç ile seçip klavyemizden Delete tuşuna basıp tasarım ekranından siliyoruz. Bunun yerine bluetooth'u kontrol etmek için bir tuş (Button) ekleyeceğiz.

5. GUI Tasarımı

GUI tasarımı

Boş ekranımıza kontrol tuşumuzu ekliyor ardından resimde görüldüğü gibi konumlandırıyoruz. Konumlandırabilmek için öncelikle denetimin sağ ve sol kıstırmalarını (constraints) sağdaki nitelikler (attributes) bölümünü kullanarak bağlayın. Kıstırmaları bağlamadan sürükleyip bırakırsanız tuşun bıraktığınız yerde değil ekranın sol üst köşesinde konumlandığını göreceksiniz. Bu yüzden konumlandırmak için önce en azından sağ ve sol kıstırmaları bağlayın. Sağ ve sol mesafeleri 0 seçerseniz tuş tasarım ekranında otomatik olarak ortalanacaktır. Son olarak alt kıstırmayı da bağlayıp mesafe olarak 16 seçin. Tasarım ekranının xml kodları şöyle:

 1<?xml version="1.0" encoding="utf-8"?>
 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3    xmlns:app="http://schemas.android.com/apk/res-auto"
 4    xmlns:tools="http://schemas.android.com/tools"
 5    android:layout_width="match_parent"
 6    android:layout_height="match_parent"
 7    tools:context=".MainActivity">
 8
 9    <Button
10        android:id="@+id/btn_ac_kapat"
11        android:layout_width="wrap_content"
12        android:layout_height="wrap_content"
13        android:layout_marginBottom="16dp"
14        android:text="BLUETOOTH AÇ"
15        app:layout_constraintBottom_toBottomOf="parent"
16        app:layout_constraintEnd_toEndOf="parent"
17        app:layout_constraintHorizontal_bias="0.498"
18        app:layout_constraintStart_toStartOf="parent" />
19</androidx.constraintlayout.widget.ConstraintLayout>

Bu aşamadan sonra basit kontrol ekranımız artık kullanıma hazır. Sırada kodlama var!

6. Manifest Bluetooth İzin Bildirimleri

Android sisteminde temel bluetooth işlemleri BluetoothAdapter adında bir sınıf ya da diğer bir deyişle API aracılığıyla geçekleştirilir. Ancak temel kullanım ve kontrol işlemlerini yapabilmek için öncelikle projemizin manifest dosyasında BLUETOOTH ve BLUETOOTH_ADMIN adında iki adet bluetooth izni bildirmemiz gerekmektedir. Bu izinler aşağıdaki gibi tanımlanır.

 1<?xml version="1.0" encoding="utf-8"?>
 2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3    package="com.kozmotronik.bluetoothgelistirme">
 4
 5    <uses-permission android:name="android.permission.BLUETOOTH"/>
 6    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 7
 8    <application
 9        android:allowBackup="true"
10        android:icon="@mipmap/ic_launcher"
11        android:label="@string/app_name"
12        android:roundIcon="@mipmap/ic_launcher_round"
13        android:supportsRtl="true"
14        android:theme="@style/AppTheme">
15        <activity android:name=".MainActivity">
16            <intent-filter>
17                <action android:name="android.intent.action.MAIN" />
18
19                <category android:name="android.intent.category.LAUNCHER" />
20            </intent-filter>
21        </activity>
22    </application>
23
24</manifest>

7. Kontrol İçin Gerekli Denetimleri Tanımlama

Kontrol tuşumuzu ve bluetooth'u kendisi ile kontrol edeceğimiz BluetoothAdapter sınıfını ilklemek için MainActivity.Java dosyasına geçelim...

1public class MainActivity extends AppCompatActivity {
2    private BluetoothAdapter bltAdaptor;
3    private Button btAcKapat;
4    ...
5}

Burada sınıf değişkenlerimizi tanımlıyoruz. Adlandırmaları sizler arzunuza göre yapabilirsiniz. Ancak henüz oldukça başlangıç aşamasındaysanız kod takibini kolaylaştırmak için aynı biçimde yazmanız önerilir.

8. Kontrol İçin gerekli Denetimleri İlkleme

 1@Override
 2protected void onCreate(Bundle savedInstanceState) {
 3    super.onCreate(savedInstanceState);
 4    setContentView(R.layout.activity_main);
 5
 6    btAcKapat = findViewById(R.id.btn_ac_kapat);
 7    bltAdaptor = BluetoothAdapter.getDefaultAdapter();
 8    if (bltAdaptor == null) {
 9        // Bu cihazda etkin bir bluetooth donanımı bulunmuyor
10    }
11}

MainActivity sınıfının onCreate() yordamı (method) içerisinde kontrol değişkenlerimiz olan btAcKapat ve bltAdaptor değişkenlerini bu şekilde ilkliyoruz1.

BluetoothAdapter sınıfı çalışılan cihazdaki (varsa) bluetooth donanımını temsil eder. Bu sınıfın statik bir yordamı olan getDefaultAdaptor() ile bu nesnenin referansı alınmış olur. Eğer cihazda bir bluetooth donanımı bulunmuyorsa getDefaultadaptor() null döndürür. Biz de bu durumdan yararlanıp adaptör ilklemesini yapar yapmaz cihazda bluetooth donanımının olup olmadığını basit bir if koşuluyla yokluyoruz. Bu koşul sağlanırsa (seçimsel olarak) istersek bluetooth donanımı olmadığından dolayı finish() yordamını çağırarak uygulamayı sonlandırabiliriz. Nitekim bu kodu bir Android emülatörde çalıştırırsanız bu koşul sağlanacaktır. Çünkü emülatörler bluetooth donanımı öykünmez (Öykünen varsa da ben henüz rastlamadım).

Sıra bluetooth'u açıp kapatacak kodları yazmaya geldi. Bluetooth'u etkinleştirme işlemi doğrudan yapılamamaktadır. Bunun yerine kullanıcıya bir açma isteği gönderilerek dolaylı olarak yapılır. Bu isteği bir Intent sınıfı kullanarak yaparız. Nitekim BluetoothAdapter API belgelendirmesini inceleyecek olursanız bir enable() yordamının olduğunu göreceksiniz. Ancak Google bu yordamı bizim uygulama gibi üçüncü parti uygulamaların doğrudan kullanmamasını, bunun yerine kullanıcıya az önce söz ettiğim biçimde etkinleştirme isteği göstermemizi belirtmektedir.

9. Kontrol Tuşunun İşlevi

1// Kontrol tuşumuza basınca ne yapacağını belirtiyoruz.
2btAcKapat.setOnClickListener(new View.OnClickListener() {
3    @Override
4    public void onClick(View view) {
5        bluetoothAcKapat();
6    }
7});

onCreate() yordamının içinde kontrol tuşuna bastığımızda sistem tarafından algılanması için OnClickListener() arayüzünü (interface) gerçekliyoruz. Böylece ekranda tuşa dokunduğumuzda sistem bu arayüzün onClick() soyut (abstract) yordamını çağırıyor ve tuşumuza bağlı işlemleri çalıştırıyor. Burada amacımız, içeriğini bizim yazacağımız bluetoothAcKapat() yordamının tuşa dokunulduğunda sistem tarafından çağırılmasıdır. Diğer bir deyişle; tuşa basma olayını yakalamaktır. Bluetooth açma ve kapatma işlemlerini bu yordamın içinde gerçekleyeceğiz.

10. Bluetooth Açma ve Kapatma İşlevi

 1private void bluetoothAcKapat() {
 2    if (!bltAdaptor.isEnabled()) {
 3        // Bluetooth etkisizleştirilmiş, etkinleştirme isteği çalıştır.
 4        Intent BTAcIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
 5        startActivity(BTAcIntent);
 6    } else {
 7        // Bluetooth etkinleştirilmiş, etkisizleştirme doğrudan yapılabilir.
 8        bltAdaptor.disable();
 9    }
10}

bluetoothAcKapat() yordamımızı onCreate() yordamının dışında ancak MainActivity sınırlarının içerisinde bir yerde yazıyoruz. Bu yordamımızda basitçe BluetoothAdapter sınıfının isEnabled() yordamını kullanarak bluetooth'un açık mı yoksa kapalı mı olduğunu sorguluyor; kapalıysa açma isteği çalıştırıyor, açıksa bluetooth'u kapatıyoruz. isEnabled() yordamı bluetooth açıksa true, kapalıysa false döndürür.

Bluetooth'un durum bilgisinden haberdar olmamız gerektiğinden son bir adımımız daha kaldı; IntentFilter ve BroadcastReceiver nesnelerini kullanarak sistemin bluetooth durumu ile ilgili yayınladığı bildirimleri yakalamak.

11. Bluetooth Durum Değişimlerini İzleme

1// Bluetooth durum değiştirdiğinde sistem bildirimini yakalalamak için gerekli kod
2IntentFilter BTDurumIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
3registerReceiver(bluetoothDurumAbonesi, BTDurumIntentFilter);

Yine onCreate() yordamı içerisinde; bir IntentFilter nesnesi yaratıp kurucuya parametre olarak BluetoothAdapter.ACTION_STATE_CHANGED sabitini veriyoruz. Burada bir nevi Android işletim sistemine bluetooth değişimlerinden haberdar olmak istediğimizi bildiriyoruz. Sonrasında Context sınıfının bir üyesi olan registerReceiver() yordamını kullanarak biraz sonra BroadcastReceiver olarak oluşturacağımız bluetoothDurumAbonesi değişkenini ve dinlemek istediğimiz şeyi belirten bilgiyi taşıyan BTDurumIntentFilter değişkenini parametre olarak veriyoruz. Bu aşamadan sonra bluetooth durum değişimini dinliyor olabileceğiz. Hemen dinleyicimizi de gerçekleyelim...

 1private BroadcastReceiver bluetoothDurumAbonesi = new BroadcastReceiver() {
 2    @Override
 3    public void onReceive(Context context, Intent intent) {
 4        String eylem = intent.getAction(); // Bildirim eylemini intent nesnesinden al
 5        if (eylem.equals(BluetoothAdapter.ACTION_STATE_CHANGED)){
 6            /* Bluetooth durum değişimini burada yakaladık. Şimdi durum bilgisini alacağız...
 7             Durum bilgisi BluetoothAdapter sınıfı içinde tanımlanmış bir int türünde değerden ibarettir.
 8              Bu değer işletim sistemi tarafından intent nesnesine; BluetoothAdapter.EXTRA_STATE
 9              anahtarı ile extra veri olarak koyulur. */
10            int durum = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
11            switch (durum){
12
13                case BluetoothAdapter.STATE_OFF:
14                    Log.i("bluetoothDurumAbonesi","Bluetooth kapalı");
15                    // Bluetooth durumunu öğrendiğimiz için burada kontrol tuşumuzun yazısını güncelleyebiliriz
16                    btAcKapat.setText("BLUETOOTH AÇ");
17                    break;
18
19                case BluetoothAdapter.STATE_TURNING_OFF:
20                    Log.i("bluetoothDurumAbonesi","Bluetooth kapanıyor...");
21                    break;
22
23                case BluetoothAdapter.STATE_ON:
24                    Log.i("bluetoothDurumAbonesi","Bluetooth açık");
25                    // Burada artık bluetooth'un açık olduğunu biliyoruz. Dolayısıyla tuşumuzun yazısını güncelleyebiliriz
26                    btAcKapat.setText("BLUETOOTH KAPAT");
27                    break;
28
29                case  BluetoothAdapter.STATE_TURNING_ON:
30                    Log.i("bluetoothDurumAbonesi","Bluetooth açılıyor...");
31                    break;
32
33                case BluetoothAdapter.ERROR:
34                    Log.i("bluetoothDurumAbonesi","Bluetooth ile ilgili bir hata!");
35                    break;
36
37                default:
38                    Log.i("bluetoothDurumAbonesi","Tanınmayan bir bluetooth durumu...");
39
40            }
41        }
42    }
43};

12. Proje Denemeye Hazır!

İşte son aşamadayız! Son kodumuz olan bluetooth durum dinleyicisini de ekledikten sonra denemeye başlayabiliriz. Bu tanımlamayı onCreate() yordamı dışına ve MainActivity sınırları içinde bir yerde yazın. Sonra telefonunuzu bilgisayarınıza bağlayıp Android Studio'daki çalıştır (run) tuşuna basın2.

Derleme başarılı oldu ve uygulama telefonunuza başarıyla yüklendi ise "BLUETOOTH AÇ" kontrol tuşuna basıp Android Studio'nun hata ayıklayıcı (debugger) bölümündeki konsol çıktısını gözlemleyin. Şu çıktıları alabiliyor olmalısınız:

Bluetooth kontrol deneme çıktısı

Projeyi İndirin

Projenin tamamını buradaki github adresinden elde edebilirsiniz. Bir sonrakinde görüşmek üzere bluetooth uygulamanız ile iyi eğlenceler...

Lisans

Bu uygulamanın kodları MIT lisansı altında paylaşılmaktadır.


1. İlklemek İnglizcedeki initiate veya kısa yazılışıyla init sözcüğüne karşılık kullanılmıştır. Her ne kadar initiate başlatmak anlamına gelse de, yapılan iş bir şeyi ilk kullanıma hazırlamak olduğu için başlatmak yerine ilklemek sözcüğü daha uygun durmaktadır.

2. Telefonunuzun geliştirici kipini etkinleştirdiğinizden emin olun.

comments powered by Disqus