06 Nisan 2026 16:28, Pazartesi 35 0
Android Saat Uygulaması — Sayfa Dokümantasyonu
Bu belge, uygulamayı oluşturan her sayfanın Java ve XML kaynak kodunu, kullanılan kütüphaneleri ve sayfanın işlevini açıklamaktadır.
package com.example.mobiluygulamasinav1;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private TextView mainTime, mainDate, nextAlarmText;
private DatabaseHelper db;
private Handler handler;
private Runnable runnable;
private final DateTimeFormatter timeFormatter =
DateTimeFormatter.ofPattern("HH:mm:ss", new Locale("tr"));
private final DateTimeFormatter dateFormatter =
DateTimeFormatter.ofPattern("EEEE, d MMMM", new Locale("tr"));
private final ZoneId zoneId = ZoneId.of("Europe/Istanbul");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DatabaseHelper(this);
mainTime = findViewById(R.id.main_time);
mainDate = findViewById(R.id.main_date);
nextAlarmText = findViewById(R.id.main_next_alarm);
handler = new Handler(Looper.getMainLooper());
runnable = new Runnable() {
@Override
public void run() {
ZonedDateTime now = ZonedDateTime.now(zoneId);
mainTime.setText(now.format(timeFormatter));
mainDate.setText(now.format(dateFormatter));
handler.postDelayed(this, 1000);
}
};
handler.post(runnable);
findViewById(R.id.go_alarm).setOnClickListener(v ->
startActivity(new Intent(this, AlarmActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)));
findViewById(R.id.go_stopwatch).setOnClickListener(v ->
startActivity(new Intent(this, StopWatchActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)));
findViewById(R.id.go_timer).setOnClickListener(v ->
startActivity(new Intent(this, TimerActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)));
findViewById(R.id.btn_show_logs).setOnClickListener(v -> {
startActivity(new Intent(this, LogActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
overridePendingTransition(0, 0);
});
}
@Override
protected void onResume() {
super.onResume();
if (nextAlarmText != null && db != null) {
nextAlarmText.setText("Siradaki Alarm: " + db.enSonAlarmiGetir());
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (handler != null) handler.removeCallbacks(runnable);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#1D1427"
android:orientation="vertical"
android:padding="24dp"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="4">
<TextView android:id="@+id/go_clock" ... android:text="Saat" android:textColor="#FF3D71"/>
<TextView android:id="@+id/go_alarm" ... android:text="Alarm"/>
<TextView android:id="@+id/go_stopwatch" ... android:text="Krono"/>
<TextView android:id="@+id/go_timer" ... android:text="Sayac"/>
</LinearLayout>
<LinearLayout android:layout_weight="1" android:gravity="center"
android:orientation="vertical">
<TextView android:id="@+id/main_time" android:text="00:00:00"
android:textSize="64sp" android:textStyle="bold"/>
<TextView android:id="@+id/main_date" android:text="Yukleniyor..."/>
<TextView android:id="@+id/main_next_alarm" android:text="Siradaki Alarm: --:--"
android:textColor="#FF3D71"/>
<Button android:id="@+id/btn_show_logs" android:text="Veritabani Loglari"/>
</LinearLayout>
<Button android:id="@+id/btn_set" android:text="SAATi AYARLA"
android:backgroundTint="#FF3D71"/>
</LinearLayout>
android.os.Handler / Runnable: Her saniye çalışan döngü kurulur. handler.postDelayed(this, 1000) ile 1000 ms sonra kendini tekrar çağıran bir Runnable oluşturulur; böylece saat bilgisi sürekli güncellenir.
java.time.ZonedDateTime / DateTimeFormatter (java.time paketi): Türkiye saat dilimine (Europe/Istanbul) göre anlık tarih ve saat alınır. timeFormatter ve dateFormatter sabitleri ile Türkçe dil paketi kullanılarak biçimlendirilmiş metin üretilir.
android.content.Intent + FLAG_ACTIVITY_NO_ANIMATION: Navigasyon butonları tıklandığında ilgili Activity'e geçiş animasyonsuz olarak gerçekleştirilir; bu sayede sekmeler arası geçiş akıcı görünür.
DatabaseHelper (özel sınıf): enSonAlarmiGetir() metoduyla SQLite veritabanından en son eklenen alarm saati çekilerek ekranda gösterilir.
Ana Sayfa, uygulamanın başlangıç ekranıdır. Ekranın ortasında büyük punto ile anlık saat (HH:mm:ss formatında) ve tam Türkçe tarih gösterilir. Altında bir sonraki aktif alarm saati pembe renkte yer alır. Üst kısımda dört sekmeli navigasyon çubuğuyla diğer sayfalara geçiş sağlanır; aktif sekme (Saat) kırmızı/pembe renkte öne çıkar. 'Veritabanı Logları' butonu log sayfasına yönlendirir.
package com.example.mobiluygulamasinav1;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Calendar;
import java.util.List;
public class AlarmActivity extends AppCompatActivity {
private DatabaseHelper db;
private List<String> alarmListesi;
private ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
db = new DatabaseHelper(this);
ListView listView = findViewById(R.id.alarm_list_view);
alarmListesi = db.tumAlarmlariGetir();
adapter = new ArrayAdapter<String>(this, 0, alarmListesi) {
@NonNull
@Override
public View getView(int position, @Nullable View convertView,
@NonNull ViewGroup parent) {
RelativeLayout layout = new RelativeLayout(getContext());
layout.setPadding(50, 40, 50, 40);
layout.setBackgroundColor(Color.parseColor("#2D2338"));
String vakit = alarmListesi.get(position);
int mevcutDurum = db.alarmDurumuGetir(vakit);
TextView textView = new TextView(getContext());
textView.setText(vakit);
textView.setTextColor(Color.WHITE);
textView.setTextSize(26f);
Switch sw = new Switch(getContext());
sw.setOnCheckedChangeListener(null);
sw.setChecked(mevcutDurum == 1);
updateSwitchColors(sw);
sw.setOnClickListener(v -> {
boolean isChecked = sw.isChecked();
db.alarmDurumGuncelle(vakit, isChecked ? 1 : 0);
updateSwitchColors(sw);
db.logEkle("Alarm (" + vakit + ") " + (isChecked ? "Acildi" : "Kapandi"));
if (isChecked) kurSistemAlarmi(vakit);
else iptalEtSistemAlarmi(vakit);
});
layout.addView(textView);
layout.addView(sw);
return layout;
}
};
listView.setAdapter(adapter);
listView.setOnItemLongClickListener((p, v, pos, id) -> {
String vakit = alarmListesi.get(pos);
iptalEtSistemAlarmi(vakit);
db.logEkle("Alarm Silindi: " + vakit);
db.alarmSil(vakit);
alarmListesi.remove(pos);
adapter.notifyDataSetChanged();
return true;
});
findViewById(R.id.btn_add_alarm).setOnClickListener(v -> {
Calendar mcurrentTime = Calendar.getInstance();
new TimePickerDialog(this, (view, h, m) -> {
String yeniVakit = String.format("%02d:%02d", h, m);
db.alarmEkle(yeniVakit);
db.logEkle("Yeni Alarm: " + yeniVakit);
kurSistemAlarmi(yeniVakit);
alarmListesi.clear();
alarmListesi.addAll(db.tumAlarmlariGetir());
adapter.notifyDataSetChanged();
}, mcurrentTime.get(Calendar.HOUR_OF_DAY),
mcurrentTime.get(Calendar.MINUTE), true).show();
});
}
private void kurSistemAlarmi(String vakit) {
try {
String[] parca = vakit.split(":");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(parca[0]));
cal.set(Calendar.MINUTE, Integer.parseInt(parca[1]));
cal.set(Calendar.SECOND, 0);
if (cal.before(Calendar.getInstance())) cal.add(Calendar.DATE, 1);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("vakit_verisi", vakit);
PendingIntent pi = PendingIntent.getBroadcast(this, vakit.hashCode(), intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
if (am != null)
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), pi);
} catch (Exception e) { e.printStackTrace(); }
}
private void iptalEtSistemAlarmi(String vakit) {
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, vakit.hashCode(), intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
if (am != null) am.cancel(pi);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:background="#1D1427"
android:orientation="vertical" android:padding="24dp">
<!-- Navigasyon cubugu -->
<LinearLayout android:weightSum="4" android:orientation="horizontal">
<TextView android:id="@+id/go_clock" android:text="Saat"/>
<TextView android:id="@+id/go_alarm" android:text="Alarm"
android:textColor="#FF3D71" android:textStyle="bold"/>
<TextView android:id="@+id/go_stopwatch" android:text="Krono"/>
<TextView android:id="@+id/go_timer" android:text="Sayac"/>
</LinearLayout>
<!-- Baslik ve + butonu -->
<RelativeLayout android:layout_marginTop="32dp">
<TextView android:text="Alarmlarim" android:textSize="28sp"
android:textStyle="bold" android:layout_alignParentStart="true"/>
<TextView android:id="@+id/btn_add_alarm" android:text="+"
android:textColor="#FF3D71" android:textSize="40sp"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
<!-- Alarm listesi -->
<FrameLayout android:layout_weight="1">
<ListView android:id="@+id/alarm_list_view"
android:divider="@android:color/transparent"
android:dividerHeight="16dp"/>
<TextView android:id="@+id/empty_view"
android:text="Henuz alarm eklemen." android:visibility="gone"/>
</FrameLayout>
</LinearLayout>
android.app.AlarmManager + PendingIntent: Kullanıcı bir alarmı açtığında kurSistemAlarmi() metodu çalışır. AlarmManager.setExactAndAllowWhileIdle() ile cihaz uyku modundayken bile tam zamanında tetiklenecek bir sistem alarmı kurulur. iptalEtSistemAlarmi() ise am.cancel(pi) ile bu alarmı iptal eder.
android.app.TimePickerDialog: '+' butonuna basıldığında bir saat seçici diyalog açılır. Kullanıcının seçtiği saat String.format('%02d:%02d', h, m) formatıyla kaydedilir.
android.widget.Switch + PorterDuff.Mode: Her alarm satırının sağında bir aç/kapa düğmesi bulunur. updateSwitchColors() metodu, Switch'in thumbDrawable ve trackDrawable renklerini pembe (#FF3D71) ya da gri (#4A4253) olarak dinamik şekilde boyar.
ArrayAdapter (özel getView): Adapter içinde her satır için programatik olarak RelativeLayout oluşturulur; standart XML satır şablonu yerine kod tarafında tasarım yapılır.
ListView.setOnItemLongClickListener: Bir alarmın üzerine uzun basılınca o alarm veritabanından silinir, sistem alarmı iptal edilir ve log kaydı eklenir.
Alarm Sayfası, kullanıcının alarm ekleyebildiği, açıp/kapattığı ve silebildiği ana alarm yönetim ekranıdır. Ekranın üstünde sekme navigasyonu, sağ üstte büyük '+' butonu yer alır. Kayıtlı alarmlar pembe renkli büyük saat yazısı ve Switch ile listelenir. Switch açıkken gerçek bir Android sistem alarmı kurulur; kapatıldığında veya alarm silindiğinde bu alarm iptal edilir.
package com.example.mobiluygulamasinav1;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class StopWatchActivity extends AppCompatActivity {
private TextView timeTxt;
private Button btnStartStop, btnReset;
private long startTime = 0L, pausedTime = 0L;
private Handler handler = new Handler();
private boolean isRunning = false;
private SharedPreferences prefs;
private DatabaseHelper db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stop_watch);
db = new DatabaseHelper(this);
prefs = getSharedPreferences("SW_Prefs", MODE_PRIVATE);
isRunning = prefs.getBoolean("isRunning", false);
pausedTime = prefs.getLong("pausedTime", 0L);
if (isRunning) {
startTime = prefs.getLong("startTime", System.currentTimeMillis());
handler.post(runnable);
}
btnStartStop.setOnClickListener(v -> {
if (!isRunning) {
startTime = System.currentTimeMillis();
isRunning = true;
prefs.edit().putBoolean("isRunning", true)
.putLong("startTime", startTime).apply();
handler.post(runnable);
} else {
pausedTime += (System.currentTimeMillis() - startTime);
isRunning = false;
db.logEkle("Kronometre: " + timeTxt.getText().toString());
prefs.edit().putBoolean("isRunning", false)
.putLong("pausedTime", pausedTime).apply();
handler.removeCallbacks(runnable);
}
});
btnReset.setOnClickListener(v -> {
handler.removeCallbacks(runnable);
isRunning = false;
pausedTime = 0L;
prefs.edit().clear().apply();
timeTxt.setText("00:00:00");
});
}
private void updateDisplay(long totalMs) {
int seconds = (int) (totalMs / 1000);
int minutes = seconds / 60;
int milli = (int) (totalMs % 1000) / 10;
timeTxt.setText(String.format("%02d:%02d:%02d",
minutes, seconds % 60, milli));
}
public Runnable runnable = new Runnable() {
public void run() {
long totalTime = pausedTime +
(System.currentTimeMillis() - startTime);
updateDisplay(totalTime);
handler.postDelayed(this, 10);
}
};
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:background="#1D1427"
android:orientation="vertical" android:padding="24dp">
<!-- Navigasyon cubugu -->
<LinearLayout android:weightSum="4" android:orientation="horizontal">
<TextView android:id="@+id/go_clock" android:text="Saat"/>
<TextView android:id="@+id/go_alarm" android:text="Alarm"/>
<TextView android:id="@+id/go_stopwatch" android:text="Krono"
android:textColor="#FF3D71" android:textStyle="bold"/>
<TextView android:id="@+id/go_timer" android:text="Sayac"/>
</LinearLayout>
<!-- Kronometre ekrani -->
<RelativeLayout android:layout_weight="1" android:gravity="center">
<TextView android:id="@+id/stopwatch_time"
android:layout_centerInParent="true"
android:text="00:00:00"
android:textColor="#FFFFFF"
android:textSize="60sp"
android:textStyle="bold"/>
</RelativeLayout>
<!-- Kontrol butonlari -->
<LinearLayout android:weightSum="2" android:orientation="horizontal">
<Button android:id="@+id/btn_start_stop"
android:text="BASLAT" android:backgroundTint="#FF3D71"
android:layout_weight="1"/>
<Button android:id="@+id/btn_reset"
android:text="SIFIRLA" android:backgroundTint="#2D2338"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
android.os.Handler + Runnable (10 ms döngü): Kronometrenin hassas sayımı için handler.postDelayed(this, 10) ile her 10 ms'de bir ekran güncellenir; böylece dakika:saniye:salise formatında akıcı bir görüntü elde edilir.
android.content.SharedPreferences: Kullanıcı uygulamadan çıksa bile kronometre durumu (isRunning, startTime, pausedTime) SharedPreferences'a kaydedilir. Sayfa tekrar açıldığında onResume()'de bu değerler okunarak sayım kaldığı yerden devam eder.
System.currentTimeMillis(): Başlatma anındaki zaman damgası startTime olarak kaydedilir. Her döngüde System.currentTimeMillis() - startTime hesabıyla geçen süre bulunur; bu yöntem sayesinde Handler gecikmelerinden bağımsız doğru zaman elde edilir.
DatabaseHelper.logEkle(): Kronometre durdurulduğunda o anki süre değeri veritabanına log olarak kaydedilir.
Kronometre Sayfası, milisaniye hassasiyetinde süre ölçen bir stopwatch ekranıdır. Ekranın ortasında büyük sayaç (DD:SS:ss formatında) gösterilir. 'Başlat' butonuyla sayım başlar, butona tekrar basılınca duraksatılır; süre kaybolmaz. 'Sıfırla' butonu her şeyi siler. Uygulama kapatılıp açılsa dahi sayım devam eder. Durdurulan her süre veritabanına kaydedilir.
package com.example.mobiluygulamasinav1;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.provider.Settings;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class TimerActivity extends AppCompatActivity {
private TextView hTxt, mTxt, sTxt;
private Button btnAction, btnReset;
private CountDownTimer timer;
private long timeLeftInMillis = 0;
private boolean isRunning = false;
private SharedPreferences prefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
hTxt.setOnClickListener(v -> selectTime());
mTxt.setOnClickListener(v -> selectTime());
sTxt.setOnClickListener(v -> selectTime());
btnAction.setOnClickListener(v -> {
if (isRunning) pauseTimer();
else startTimer();
});
btnReset.setOnClickListener(v -> resetLogic());
}
private void startTimer() {
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (am != null && !am.canScheduleExactAlarms()) {
Intent intent = new Intent(
Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
startActivity(intent);
return;
}
}
long stopAt = System.currentTimeMillis() + timeLeftInMillis;
prefs.edit().putLong("stopAt", stopAt)
.putBoolean("isRunning", true).apply();
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 8888, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
if (am != null)
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, stopAt, pi);
beginCountDown(timeLeftInMillis);
}
private void beginCountDown(long duration) {
timer = new CountDownTimer(duration, 1000) {
@Override public void onTick(long l) {
timeLeftInMillis = l;
updateDisplays();
}
@Override public void onFinish() { resetLogic(); }
}.start();
}
private void updateDisplays() {
int h = (int) (timeLeftInMillis / 3600000);
int m = (int) (timeLeftInMillis % 3600000) / 60000;
int s = (int) (timeLeftInMillis % 60000) / 1000;
hTxt.setText(String.format("%02d", h));
mTxt.setText(String.format("%02d", m));
sTxt.setText(String.format("%02d", s));
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:background="#1D1427"
android:orientation="vertical" android:padding="24dp">
<!-- Navigasyon cubugu -->
<LinearLayout android:weightSum="4" android:orientation="horizontal">
<TextView android:id="@+id/go_clock" android:text="Saat"/>
<TextView android:id="@+id/go_alarm" android:text="Alarm"/>
<TextView android:id="@+id/go_stopwatch" android:text="Krono"/>
<TextView android:id="@+id/go_timer" android:text="Sayac"
android:textColor="#FF3D71" android:textStyle="bold"/>
</LinearLayout>
<!-- Saat / Dakika / Saniye secici -->
<LinearLayout android:layout_weight="1" android:gravity="center"
android:weightSum="3">
<LinearLayout android:layout_weight="1" android:orientation="vertical"
android:gravity="center">
<TextView android:id="@+id/txt_h" android:text="00"
android:textSize="55sp" android:textStyle="bold"/>
<TextView android:text="Saat" android:textColor="#6E647A"/>
</LinearLayout>
<LinearLayout android:layout_weight="1" android:orientation="vertical"
android:gravity="center">
<TextView android:id="@+id/txt_m" android:text="00"
android:textSize="55sp" android:textStyle="bold"/>
<TextView android:text="Dakika" android:textColor="#6E647A"/>
</LinearLayout>
<LinearLayout android:layout_weight="1" android:orientation="vertical"
android:gravity="center">
<TextView android:id="@+id/txt_s" android:text="00"
android:textSize="55sp" android:textStyle="bold"/>
<TextView android:text="Saniye" android:textColor="#6E647A"/>
</LinearLayout>
</LinearLayout>
<!-- Butonlar -->
<LinearLayout android:weightSum="2">
<Button android:id="@+id/btn_timer_action" android:text="BASLAT"
android:backgroundTint="#FF3D71" android:layout_weight="1"/>
<Button android:id="@+id/btn_timer_reset" android:text="SIL"
android:backgroundTint="#2D2338" android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
android.os.CountDownTimer: beginCountDown() içinde CountDownTimer başlatılır. Her 1000 ms'de onTick() tetiklenerek kalan süre ekrana yansıtılır; süre dolduğunda onFinish() çağrılarak ekran sıfırlanır.
AlarmManager.setExactAndAllowWhileIdle(): Geri sayım tamamlandığında AlarmReceiver tetiklenmesi için sistem seviyesinde bir alarm kurulur. Android 12 ve üzeri için canScheduleExactAlarms() izni sorgulanır; izin yoksa sistem ayarları sayfasına yönlendirme yapılır.
SharedPreferences (stopAt kaydı): Sayaç başlatıldığında bitiş zamanı (System.currentTimeMillis() + kalan süre) SharedPreferences'a kaydedilir. Uygulama kapatılıp açıldığında checkTimerStatus() bu değeri okuyarak kalan süreyi hesaplar ve sayacı yeniden başlatır.
TimePickerDialog: Sayı ekranlarına (saat, dakika, saniye alanlarına) tıklanınca bir zaman seçici diyalog açılır; kullanıcı saat ve dakika değerini seçer, bu değer milisaniyeye çevrilerek timeLeftInMillis değişkenine atanır.
Geri Sayım Sayfası, belirli bir süre sonunda alarm verecek bir zamanlayıcı ekranıdır. Saat, Dakika ve Saniye alanlarına tıklanarak süre belirlenir. 'Başlat' ile geri sayım başlar, 'Duraklat' ile duraklatılır; süre kaybolmaz. 'Sil' butonuyla tamamen sıfırlanır. Süre sona erdiğinde AlarmReceiver devreye girerek bildirim verir. Uygulama arka plandayken de sistem alarmı çalışmaya devam eder.
package com.example.mobiluygulamasinav1;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.List;
public class LogActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log);
DatabaseHelper db = new DatabaseHelper(this);
List<String> tumKayitlar = db.tumVerileriGetir();
ListView listView = findViewById(R.id.logListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this, android.R.layout.simple_list_item_1, tumKayitlar) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView text = view.findViewById(android.R.id.text1);
text.setTextColor(Color.WHITE);
text.setTextSize(16f);
return view;
}
};
listView.setAdapter(adapter);
findViewById(R.id.btn_clear_logs).setOnClickListener(v -> {
db.tumLoglariSil();
tumKayitlar.clear();
adapter.notifyDataSetChanged();
Toast.makeText(this, "Loglar temizlendi", Toast.LENGTH_SHORT).show();
});
findViewById(R.id.btn_back).setOnClickListener(v -> {
finish();
overridePendingTransition(0, 0);
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:background="#1D1427"
android:orientation="vertical" android:padding="24dp">
<!-- Navigasyon cubugu -->
<LinearLayout android:weightSum="4" android:orientation="horizontal">
<TextView android:id="@+id/back_clock" android:text="Saat"/>
<TextView android:id="@+id/go_alarm_from_log" android:text="Alarm"/>
<TextView android:id="@+id/go_stopwatch_from_log" android:text="Krono"/>
<TextView android:id="@+id/go_timer_from_log" android:text="Sayac"/>
</LinearLayout>
<!-- Log listesi -->
<LinearLayout android:layout_weight="1" android:orientation="vertical"
android:layout_marginTop="20dp">
<TextView android:text="Veritabani Kayitlari"
android:textSize="28sp" android:textStyle="bold"
android:layout_gravity="center_horizontal"/>
<ListView android:id="@+id/logListView"
android:divider="#3D324D" android:dividerHeight="1dp"/>
</LinearLayout>
<!-- Alt butonlar -->
<LinearLayout android:layout_height="64dp" android:weightSum="2">
<Button android:id="@+id/btn_back" android:text="ANA SAYFA"
android:backgroundTint="#6E647A" android:layout_weight="1.2"/>
<Button android:id="@+id/btn_clear_logs" android:text="TEMIZLE"
android:backgroundTint="#FF3D71" android:layout_weight="0.8"/>
</LinearLayout>
</LinearLayout>
DatabaseHelper.tumVerileriGetir(): Uygulama boyunca gerçekleştirilen tüm işlemler (alarm ekleme, silme, açma/kapatma, kronometre durdurmalar) tek bir listede getirilir ve ListView'e bağlanır.
ArrayAdapter (özel getView): Standart simple_list_item_1 şablonu kullanılır; ancak metin rengi Color.WHITE olarak ve boyutu 16sp olarak ezerek okunabilir bir görünüm sağlanır.
DatabaseHelper.tumLoglariSil(): 'Temizle' butonuna basılınca veritabanındaki tüm log kayıtları silinir, liste adapter üzerinden güncellenir ve Toast mesajıyla kullanıcıya bilgi verilir.
finish() + overridePendingTransition(0, 0): 'Ana Sayfa' butonu ve navigasyon sekmeleri mevcut Activity'i kapatır; animasyonsuz geçiş sayesinde uygulama akıcı çalışır.
Log Sayfası, uygulamada gerçekleştirilen işlemlerin tarih-saat damgasıyla birlikte listelendiği bir veritabanı görüntüleyicisidir. Hangi alarmın ne zaman eklendiği, silindiği, açılıp kapandığı ve kronometre durdurma kayıtları bu sayfada görülür. 'Temizle' butonuyla tüm loglar tek seferde silinebilir. Ana sayfadan 'Veritabanı Logları' butonuyla erişilir; üst navigasyondan diğer sekmelere de geçiş yapılabilir.
Abdül Azim Çoha
atp 11 a
Lütfen yorumlarınızda saygılı, yapıcı ve anlaşılır bir dil kullanın.
Küfür, hakaret ya da spam içerikler onaylanmaz.