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.
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ştur penceresinde Boş Etkinlik (Empty Activity) seçeneğini seçip Sonraki (Next) tuşuna basalım.
2. 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
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ı
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ı
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:
Projeyi İndirin
Projenin tamamını buradaki github adresinden elde edebilirsiniz. Bir sonrakinde görüşmek üzere bluetooth uygulamanız ile iyi eğlenceler...
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. ↩