摘要:

这一篇主要使用系统为我们提供的一个服务AlarmManager来制作一个Android小闹钟,同时还涉及到了自定义主题、判断第一次启动应用、自定义动画、对话框、制作指导滑动页面等方面。最后形成一个可以直接在手机上面使用的小闹钟。

开始启动界面AppStart.java

package com.example.alarmtest;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.LinearLayout; public class AppStart extends Activity{
public static final String PACKAGE_NAME = "com.example.alarmtest";
public static final String VERSION_KEY = "versionCode";
SharedPreferences preferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState); //判断是否是首次安装
/** 判断应用首次运行 **/ preferences = getSharedPreferences("count",MODE_WORLD_READABLE); int count = preferences.getInt("start_count", 0);
if(count == 0){
Editor editor = preferences.edit();
//存入数据
editor.putInt("start_count", ++count);
//提交修改
editor.commit(); Intent intent = new Intent(AppStart.this, GuideActivity.class);
startActivity(intent);
AppStart.this.finish(); }else{
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setLayoutParams(params);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setBackgroundResource(R.drawable.main_bg_default_img_2); new Handler().postDelayed(new Runnable(){
@Override
public void run(){
Intent intent = new Intent (AppStart.this, MainActivity.class);
startActivity(intent);
AppStart.this.finish();
}
}, 1000);
setContentView(linearLayout);
}
}
}

上面使用sharedPreference中的默认设值来判断该应用是否是第一次启动,如果是第一次启动则启动GuidActivity进入指导页面,如果不是第一次启动则启动MainActivity进入主界面。

先看看GuidActivity的实现

package com.example.alarmtest;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView; /**
* 第一次安装引导用户的Activity
* @author lixq
*
*/
public class GuideActivity extends Activity{ private ViewPager viewPager;
private ArrayList<View> pageViews;
private ImageView imageView;
private ImageView[] imageViews;
// 包裹滑动图片LinearLayout
private ViewGroup main;
// 包裹小圆点的LinearLayout
private ViewGroup group;
//左箭头按钮
private ImageView imageViewLeft;
//右箭头按钮
private ImageView imageViewRight;
//当前页码
private int currentIndex; //ImageView的alpha值
private int mAlpha = 0;
private boolean isHide; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//将要显示的图片放到ArrayList当中,存到适配器中
LayoutInflater inflater = getLayoutInflater();
pageViews = new ArrayList<View>();
pageViews.add(inflater.inflate(R.layout.guide_item1, null));
pageViews.add(inflater.inflate(R.layout.guide_item2, null));
pageViews.add(inflater.inflate(R.layout.guide_item3, null));
pageViews.add(inflater.inflate(R.layout.guide_item4, null));
//将图片存放到ImageView集合中
imageViews = new ImageView[pageViews.size()];
main = (ViewGroup)inflater.inflate(R.layout.guide, null);
//获取存放底部导航点ViewGroup
group = (ViewGroup)main.findViewById(R.id.guide_point_ll);
viewPager = (ViewPager)main.findViewById(R.id.guide_viewpager);
imageViewLeft = (ImageView)main.findViewById(R.id.imageView1);
imageViewRight = (ImageView)main.findViewById(R.id.imageView2);
imageViewLeft.setAlpha(0);
imageViewRight.setAlpha(0); //将小圆点放到imageView数组当中
for (int i = 0; i < pageViews.size(); i++) {
System.out.println("pageViews.size() = " + pageViews.size());
imageView = new ImageView(GuideActivity.this);
imageView.setLayoutParams(new LayoutParams(20,20));
imageView.setPadding(20, 0, 20, 0);
imageViews[i] = imageView; if (i == 0) {
//默认选中第一张图片
imageViews[i].setBackgroundResource(R.drawable.green_point);
} else {
imageViews[i].setBackgroundResource(R.drawable.gray_point);
} group.addView(imageViews[i]);
} setContentView(main); viewPager.setAdapter(new GuidePageAdapter());
viewPager.setOnPageChangeListener(new GuidePageChangeListener());
imageViewLeft.setOnClickListener(new ButtonListener());
imageViewRight.setOnClickListener(new ButtonListener());
} //左右切换屏幕的按钮监听器
class ButtonListener implements OnClickListener{ @Override
public void onClick(View v) {
// TODO Auto-generated method stub
int showNext=0;
if(v.getId() == R.id.imageView1) {
System.out.println("点击了向左的按钮");
if(currentIndex ==0 )
showNext = currentIndex;
else
showNext = currentIndex-1;
viewPager.setCurrentItem(showNext);
}
if(v.getId() == R.id.imageView2){
System.out.println("点击了向右的按钮");
if(currentIndex == imageViews.length)
showNext = currentIndex;
else
showNext = currentIndex+1;
viewPager.setCurrentItem(showNext);
}
System.out.println("当前页码:"+showNext); } } /**
* 设置按钮渐显效果
*/
private Handler mHandler = new Handler()
{
public void handleMessage(Message msg) {
if(msg.what==1 && mAlpha<255){
//通过设置不透明度设置按钮的渐显效果
mAlpha += 50; if(mAlpha>255)
mAlpha=255; imageViewLeft.setAlpha(mAlpha);
imageViewLeft.invalidate();
imageViewRight.setAlpha(mAlpha);
imageViewRight.invalidate(); if(!isHide && mAlpha<255)
mHandler.sendEmptyMessageDelayed(1, 100);
}else if(msg.what==0 && mAlpha>0){
mAlpha -= 3; if(mAlpha<0)
mAlpha=0;
imageViewLeft.setAlpha(mAlpha);
imageViewLeft.invalidate();
imageViewRight.setAlpha(mAlpha);
imageViewRight.invalidate(); if(isHide && mAlpha>0)
mHandler.sendEmptyMessageDelayed(0, 2);
}
}
}; private void showImageButtonView(){
isHide = false;
mHandler.sendEmptyMessage(1);
} private void hideImageButtonView(){
new Thread(){
public void run() {
try {
isHide = true;
mHandler.sendEmptyMessage(0);
} catch (Exception e) {
;
}
}
}.start();
} @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
System.out.println("this is dispatch");
System.out.println("触碰屏幕");
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_DOWN:
showImageButtonView();
break;
case MotionEvent.ACTION_UP:
hideImageButtonView();
break;
} return super.dispatchTouchEvent(ev);
} // 指引页面数据适配器,实现适配器方法
class GuidePageAdapter extends PagerAdapter { @Override
public int getCount() {
return pageViews.size();
} @Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
} @Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return super.getItemPosition(object);
} @Override
public void destroyItem(View arg0, int arg1, Object arg2) {
// TODO Auto-generated method stub
((ViewPager) arg0).removeView(pageViews.get(arg1));
} @Override
public Object instantiateItem(View arg0, int arg1) {
// TODO Auto-generated method stub
((ViewPager) arg0).addView(pageViews.get(arg1));
return pageViews.get(arg1);
} @Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
// TODO Auto-generated method stub } @Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
} @Override
public void startUpdate(View arg0) {
// TODO Auto-generated method stub } @Override
public void finishUpdate(View arg0) {
// TODO Auto-generated method stub }
} // 指引页面更改事件监听器,左右滑动图片时候,小圆点变换显示当前图片位置
class GuidePageChangeListener implements OnPageChangeListener { @Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub } @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub } @Override
public void onPageSelected(int arg0) {
currentIndex = arg0;
for (int i = 0; i < imageViews.length; i++) {
imageViews[arg0].setBackgroundResource(R.drawable.green_point); if (arg0 != i) {
imageViews[i].setBackgroundResource(R.drawable.gray_point);
}
}
}
}
}

使用ViewPage来显示各个布局文件,在四个布局文件中分别放四张图片。

详情请看:http://blog.csdn.net/dawanganban/article/details/17305769

进入主界面后就是我们设置闹钟的界面了,实现如下:

package com.example.alarmtest;

import java.util.Calendar;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast; public class MainActivity extends Activity {
Button button;
AlarmManager alarmManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button1); //获取AlarmManager对象
alarmManager = (AlarmManager) getSystemService(Service.ALARM_SERVICE); button.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
Calendar currentTime = Calendar.getInstance();
//创建一个TimePickerDialog实例,并显示
new TimePickerDialog(MainActivity.this, 0,
new TimePickerDialog.OnTimeSetListener() { @Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
//指定启动AlarmActivity组件
Intent intent = new Intent(MainActivity.this, AlarmActivity.class);
//创建PendingIntent对象
/*
* PendingIntent与Intent的区别是PendingIntent处理即将发生的事情
* 比如:在通知栏Notification中跳转页面,不是立即跳转
* 通常通过 getActivity、getBroadcast、getService得到PendingIntent的实例
*
*/
PendingIntent pi = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
c.set(Calendar.HOUR, hourOfDay);
c.set(Calendar.MINUTE, minute); alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);
Toast.makeText(MainActivity.this, "设置闹钟成功", Toast.LENGTH_SHORT).show();
}
}, currentTime.get(Calendar.HOUR_OF_DAY), currentTime.get(Calendar.MINUTE), false).show();
}
});
}
}

上面使用了一个时间设置组件TimePickDialog来设置时间,设置完时间后使用AlarmManager的set方法设置闹钟,值得注意的是上面有一个PendingIntent,这个和Intent的区别是PendIntent表示即将发生的意图,常和AlarmManager与Notifycation同时使用。另外,AlarmManager.RTC_WAKEUP表示一个定时器且会发出警报。

闹钟到时间后启动AlarmActivity来播放音乐

package com.example.alarmtest;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.media.MediaPlayer;
import android.os.Bundle; public class AlarmActivity extends Activity{
MediaPlayer alarmMusic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//加载指定音乐,并为之创建MediaPlayer对象
alarmMusic = MediaPlayer.create(this, R.raw.nswdy);
alarmMusic.setLooping(true);
//播放闹钟
alarmMusic.start();
//创建一个对话框
new AlertDialog.Builder(AlarmActivity.this).setTitle("闹钟")
.setMessage("闹钟响了,快起床啦!")
.setPositiveButton("确定", new OnClickListener() { @Override
public void onClick(DialogInterface dialog, int which) {
//停止音乐
alarmMusic.stop();
AlarmActivity.this.finish();
}
}).show();
}
}

最后的运行结果:

                   

                  

源代码下载:http://download.csdn.net/detail/lxq_xsyu/6963763

Android菜鸟的成长笔记(25)——可爱的小闹钟的更多相关文章

  1. Android菜鸟的成长笔记(3)——给QQ登录界面说So Easy

    原文:Android菜鸟的成长笔记(3)--给QQ登录界面说So Easy 上一篇:Android菜鸟的成长笔记(2)--第一个Android应用 我们前面已经做了第一个Android应用程序,虽然有 ...

  2. Android菜鸟的成长笔记(2)——第一个Android应用

    原文:Android菜鸟的成长笔记(2)--第一个Android应用 上一篇:Android菜鸟的成长笔记(1)--Anddroid环境搭建从入门到精通 在上一篇Android菜鸟的成长笔记(1)中我 ...

  3. Android菜鸟的成长笔记(1)——Android开发环境搭建从入门到精通

    原文:Android菜鸟的成长笔记(1)--Android开发环境搭建从入门到精通 今天在博客中看到好多Android的初学者对Android的开发环境的搭建不熟悉而导致不能进行学习,所以我决定自己写 ...

  4. Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)

    原文:[置顶] Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上) 我们在用手机的时候可能会发现,即使应用被放到后台再返回到前台数据依然保留(比如说我们正在玩游戏,突然电话 ...

  5. Android菜鸟的成长笔记(13)——异步任务(Async Task)

    原文:[置顶] Android菜鸟的成长笔记(13)——异步任务(Async Task) Android的UI线程主要负责处理用户的事件及图形显示,因此主线程UI不能阻塞,否则会弹出一个ANR(App ...

  6. Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

    原文:[置顶] Android菜鸟的成长笔记(12)——Handler.Loop.MessageQueue 当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要 ...

  7. Android菜鸟的成长笔记(11)——Android中的事件处理

    原文:[置顶] Android菜鸟的成长笔记(11)——Android中的事件处理 Android提供了两种方式来处理事件,一个是基于回调的事件处理,另一个是基于监听的事件处理,举个例子: 基于回调的 ...

  8. Android菜鸟的成长笔记(10)——使用Bundle在Activity之间传值

    原文:[置顶] Android菜鸟的成长笔记(10)——使用Bundle在Activity之间传值 前面我们了解了如何启动一个Activity,一个Activity在启动另外一个Activity的时候 ...

  9. Android菜鸟的成长笔记(9)——Intent与Intent Filter(下)

    原文:[置顶] Android菜鸟的成长笔记(9)——Intent与Intent Filter(下) 接着上一篇的内容,下面我们再来看看Intent的Data与Type属性. 一.Data属性与Typ ...

  10. Android菜鸟的成长笔记(8)——Intent与Intent Filter(上)

    原文:[置顶] Android菜鸟的成长笔记(8)——Intent与Intent Filter(上) Intent代表了Android应用的启动“意图”,Android应用将会根据Intent来启动指 ...

随机推荐

  1. C 字符/字符串经常使用函数

    string.h中经常使用函数 char * strchr(char * str ,char ch); 从字符串str中查找首次出现字符ch的位置,若存在返回查找后的地址.若不存在则返回NULL vo ...

  2. nuxt.js配置BASE_URL(基本域名)和NODE_ENV(环境变量)

    一直以来,开发环境和生产环境的数据接口域名不一样总是困扰着我 每次打测试包或者线上包,我都得手动切换域名,我相信很多人的做法跟这差不多,类似下面这样: (你已经注意到,这个文件已经被我无情的删除了,因 ...

  3. css实现背景半透明文字不透明的效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. maven 详细描述

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  5. 洛古——P1433 吃奶酪

    https://www.luogu.org/problem/show?pid=1433 题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输 ...

  6. 洛谷 P1097 统计数字

    P1097 统计数字 题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自 ...

  7. HTTP网络协议(一)

    1.了解Web及网络基础 TCP/IP协议族按层次可以分为下面四层: 应用层:决定了向用户提供应用服务时通信的活动,TCP/IP协议族内预存了各类通用的应用服务,比如:FTP(文件传输协议)和DNS( ...

  8. 云服务器搭建 Nginx 静态网站

    第一步:安装 Nginx 在 CentOS 上,可直接使用 yum 来安装 Nginx(当然也可以通过下载压缩包.解压.编译的方式安装,不过太麻烦了) yum install nginx -y 第二步 ...

  9. IIS7配置PHP图解

    IIS6整合PHP详解:http://zhidao.zgsj.com/article/8/2011118142648.shtml PHP5.2.17 官方下载: http://windows.php. ...

  10. Android多线程研究(9)——读写锁

    一.什么是锁 在Java的util.concurrent.locks包下有关于锁的接口和类如下: 先看一段代码: package com.codeing.snail.test; public clas ...