Điện thoại android có đồng hồ báo thức mặc định, nhưng ta muốn tự
làm để có âm chuông báo theo ý muốn.
Tạo một file chuong.xml trong thư mục layout.
<?xml version="1.0"
encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="13dp"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
>
<TextView
android:layout_width="40dp"
android:layout_height="wrap_content"
android:gravity="right"
android:singleLine="true"
android:textColor="#0C090A"
android:textSize="13sp"
/>
<Spinner
android:id="@+id/spin"
android:layout_width="98dp"
android:layout_height="43dp"
android:background="@drawable/bu3"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<Spinner
android:id="@+id/spin2"
android:layout_width="98dp"
android:layout_height="43dp"
android:layout_marginLeft="1dp"
android:background="@drawable/bu3"
android:lineSpacingExtra="4dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/t"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:gravity="center"
android:clickable="true"
android:onClick="tatchuong"
android:layout_marginLeft="1dp"
android:singleLine="true"
android:textColor="#0C090A"
android:textSize="18sp"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="43dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_gravity="center_horizontal"
>
<Button
android:id="@+id/b1"
android:layout_width="75dp"
android:layout_height="42dp"
android:background="@drawable/bu"
android:text="OK"
android:textColor="#0000cd"
android:textSize="15sp"
/>
<Button
android:id="@+id/b2"
android:layout_width="75dp"
android:layout_height="42dp"
android:layout_marginLeft="4dp"
android:background="@drawable/bu"
android:text="Cancel"
android:textColor="#0000cd"
android:textSize="15sp"
/>
</LinearLayout>
</LinearLayout>
Thêm quyền vào file manifest.xml.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
/>
<uses-permission android:name="android.permission.WAKE_LOCK"
/>
<uses-permission android:name="android.permission.GET_TASKS"
/>
Khai báo service lên trên dòng </application> cuối cùng.
<service
android:name=".service"
android:enabled="true"
android:exported="false"
/>
Khai báo class chuong nếu nó không phải là main(là main nó sẽ được
tự động khai báo, chỉ thêm dòng Theme.Holo.Light vào)
<activity
android:name=".chuong" android:theme="@android:style/Theme.Holo.Light.Dialog.NoActionBar"
android:screenOrientation="portrait">
</activity>
Khai báo vào file dimens.xml trong thẻ values.
<dimen name="he3">150dip</dimen>
<dimen name="he4">50dip</dimen>
Class service sẽ như sau.
public class service extends Service {
String d = "Đang
đặt chuông";
private WindowManager wm;
TextView mView;
int
til = 0;
private MediaPlayer mediaPlayer;
WindowManager.LayoutParams myParams;
static IntentFilter s_intentFilter = new IntentFilter();
static {
s_intentFilter.addAction(Intent.ACTION_SCREEN_ON);
s_intentFilter.addAction(Intent.ACTION_USER_PRESENT);
}
int
dem = 0;
int
dachay = 0;
int
dachay2 = 0;
private PowerManager pm;
WakeLock wakeLock=null;
public void onCreate() {
super.onCreate();
registerReceiver(ti, s_intentFilter);
mediaPlayer = new MediaPlayer();
mediaPlayer = MediaPlayer.create(this, R.raw.d);
mediaPlayer.setLooping(true);
}
int
con = 0;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO
int ki = intent.getIntExtra("to", 0);
int ki2 = intent.getIntExtra("to2", 0);
til =
ki * 60 * 60 + ki2 * 60;
String p = new Date().toString();
p = p.trim();
String a[] = p.split(" ");
String a1[] = a[3].split(":");
int ho = Integer.parseInt(a1[0]);
int mi = Integer.parseInt(a1[1]);
int se = Integer.parseInt(a1[2]);
int pu2 = ho * 60 * 60 + mi *
60 + se;
pu2 =
pu2 * 1000;
con =
86400000 - pu2;
til =
til * 1000;
if (til>pu2) {
con = til - pu2;
} else {
con = con + til;
}
set();
mView
= new TextView(this);
//mView.setBackgroundResource(R.drawable.bu4);
mView.setTextColor(Color.parseColor("#ffffff"));
mView.setGravity(Gravity.CENTER);
if(ki2==0){
mView.setText(d+"\n"+ki+":"+ki2+"0");
}
else{
mView.setText(d+"\n"+ki+":"+ki2);
}
mView.setTextSize(android.util.TypedValue.COMPLEX_UNIT_DIP,
(float) 14.5);
mView.setTypeface(null, Typeface.BOLD);
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
int ro = (int)
getResources().getDimension(R.dimen.he3);
int ro2 = (int)
getResources().getDimension(R.dimen.he4);
myParams = new WindowManager.LayoutParams(ro, ro2,
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
/* |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON */,
PixelFormat.RGBA_8888);
myParams.gravity = Gravity.CENTER | Gravity.CENTER_VERTICAL;
myParams.setTitle("Load Average");
mView.setClickable(true);
mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(),service.class);
stopService(i);
}
});
return Service.START_STICKY;
}
private final BroadcastReceiver ti = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
KeyguardManager
myKM = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if
(action.equals(Intent.ACTION_USER_PRESENT)) {
if (dem == 1) {
wm.removeView(mView);
dem = 0;
dachay=0;
}
}
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
if
(myKM.inKeyguardRestrictedInputMode())
{
if (dem == 0) {
wm.addView(mView, myParams);
dem =
1;
dachay=1;
}
}
}
}
};
@SuppressWarnings("deprecation")
public void set() {
BroadcastReceiver
receiver = new BroadcastReceiver() {
@SuppressLint("Wakelock")
@Override
public void onReceive(Context co, Intent i) {
pm = (PowerManager)
getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
|PowerManager.ACQUIRE_CAUSES_WAKEUP| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
wakeLock.acquire();
mediaPlayer.start();
dachay2=1;
co.unregisterReceiver(this); }
};
this.registerReceiver(receiver, new IntentFilter("com.e.vidu"));
PendingIntent
pintent = PendingIntent.getBroadcast(this, 0, new Intent("com.e.vidu"), 0);
AlarmManager
manager = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime()
+ con, pintent);
}
@Override
public void onDestroy() {
super.onDestroy();
if
(mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer = null;
}
if(dachay==1){
if (mView != null) {
((WindowManager)
getSystemService(WINDOW_SERVICE))
.removeView(mView);
mView
= null;
}
}
if(dachay2==1){
wakeLock.release();
}
unregisterReceiver(ti);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Trong class này ta nhận thời gian chuyển sang và tính thời gian
còn lại đến lúc bật chuông. Tạo một view nổi ở ngoài màn hình khóa, trên đó ghi
thông báo đặt chuông và giờ đặt. Dùng broadcast để chờ, đến thời gian đặt thì
bật màn hình lên, phát nhạc. Ta cũng set để nếu người dùng chạm vào view sẽ hủy
chuông báo thức đi. Trong onDestroy() ta hủy các tác vụ tùy theo nó đã xảy ra chưa, xảy ra thì có biến
đếm để xác định. Nếu ta không dùng cách này, khi mới đặt chuông xong mà hủy
ngay, chưa gọi wakeLock
mà
đã hủy sẽ khiến app bị crash.
Tại class chính, khai báo lên trên Override onCreate()
Button
b1,b2;
private ArrayAdapter<String> adapter,adap2;
private Spinner sp,sp2;
String[]
data = {"1", "2","3","4", "5","6","7", "8","9","10","11","12", "13","14","15","16","17", "18","19","20","21","22", "23"};
String[] data2 = {"00","10","20","30","40","50"};
int[] t = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
int[] t2 = {0,10,20,30,40,50};
int gio=6;
int pu=0;
TextView on;
String van2="";
String van="";
Intent mIntent;
Thêm
vào bên dưới setContentView(R.layout.chuong);
on =
(TextView) findViewById(R.id.t);
sp =
(Spinner) findViewById(R.id.spin);
sp2 =
(Spinner) findViewById(R.id.spin2);
adapter=new customadapter(this, data,3);
adap2=new customadapter(this, data2,3);
final SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
int
vn = prefs.getInt("vi", 0);
int
vn2 = prefs.getInt("vi2", 0);
int
vit=0;
for
(int i = 0; i <t2.length; i++) {
if(vn2==t2[i]){
vit=i;
}
}
chay=isRunning(this);
if(chay==true){
on.setText("ON");
on.setBackgroundColor(Color.GREEN);
on.setTextColor(Color.WHITE);
on.setTypeface(null, Typeface.BOLD);
}
else{
on.setText("OFF");
on.setTextColor(Color.RED);
on.setBackgroundColor(Color.LTGRAY);
}
sp.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
@Override
public void
onItemSelected(AdapterView<?> parent,
View view,
int
position, long id) {
van=sp.getSelectedItem().toString();
for
(int i = 0; i <data.length; i++) {
if(van.equals(data[i])){
gio=t[i];
}
}
final SharedPreferences.Editor edit = prefs.edit();
edit.putInt("vi", gio);
edit.putInt("vi2", pu);
edit.commit();
chay=isRunning(getApplicationContext());
if(chay==true){
Bundle mBundle = new Bundle();
mBundle.putInt("to", gio);
mBundle.putInt("to2", pu);
mIntent.putExtras(mBundle);
startService(mIntent);
}
}
@Override
public void
onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
sp.setAdapter(adapter);
sp.setSelection(vn-1);
sp2.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
@Override
public void
onItemSelected(AdapterView<?> parent,
View view,
int
position, long id) {
van2=sp2.getSelectedItem().toString();
for
(int i = 0; i <data2.length; i++) {
if(van2.equals(data2[i])){
pu=t2[i];
}
}
final SharedPreferences.Editor edit = prefs.edit();
edit.putInt("vi", gio);
edit.putInt("vi2", pu);
edit.commit();
chay=isRunning(getApplicationContext());
if(chay==true){
Bundle mBundle = new Bundle();
mBundle.putInt("to", gio);
mBundle.putInt("to2", pu);
mIntent.putExtras(mBundle);
startService(mIntent);
}
}
@Override
public void
onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
sp2.setAdapter(adap2);
sp2.setSelection(vit);
mIntent
= new Intent(chuong.this, service.class);
b1 =
(Button) findViewById(R.id.b1);
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final SharedPreferences.Editor edit = prefs.edit();
edit.putInt("vi", gio);
edit.putInt("vi2", pu);
edit.commit();
Bundle mBundle = new Bundle();
mBundle.putInt("to", gio);
mBundle.putInt("to2", pu);
mIntent.putExtras(mBundle);
startService(mIntent);
chay=isRunning(chuong.this);
if(chay==true){
on.setText("ON");
on.setBackgroundColor(Color.GREEN);
on.setTextColor(Color.WHITE);
on.setTypeface(null, Typeface.BOLD);
}
}
});
b2 =
(Button) findViewById(R.id.b2);
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
b1.setTextSize(android.util.TypedValue.COMPLEX_UNIT_DIP, 15);
b2.setTextSize(android.util.TypedValue.COMPLEX_UNIT_DIP, 15);
Copy lên trên ngoặc đóng cuối cùng.
public static boolean isRunning(Context context) {
ActivityManager
manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for
(ActivityManager.RunningServiceInfo service
: manager.getRunningServices(Integer.MAX_VALUE)) {
if (service.class.getName().equals(service.service.getClassName())){
return true;
}
}
return false;
}
Thêm hàm khi ấn textview để tắt chuông đi.
public void tatchuong(View v) {
on.setText("OFF");
on.setTextColor(Color.RED);
on.setBackgroundColor(Color.LTGRAY);
on.setTypeface(null, Typeface.NORMAL);
stopService(new Intent(chuong.this, service.class));
}
Trong class này ta lấy giá trị giờ chọn, lưu lại để lần sau mở ra
nó giữ nguyên như cũ. Khi ấn OK sẽ truyền dữ liệu vào service để set ra ngoài
màn hình. Nếu đã đặt chuông mà lại ấn vào textView ON thì sẽ chuyển sang OFF,
tắt chuông đi.
Để mở vào class này nếu nó không phải là class main.
Intent
in = new Intent(MainActivity.this, chuong.class);
startActivity(in); Để tạo customadapter bạn xem ở bài này.
No comments:
Post a Comment