1.0 Version
AndroidStudio 3.3.1
JDK 1.8
minSdkVersion 21 TargetSdkVersion 28
模拟机API 23
(1)在布局文件中增加一个TextView来显示时间戳
(2)数据库中已有文本创建时间和修改时间连个字段,在NodeEditor.java中,找到updateNode()这个函数,选取修改时间这一字段,并将其格式化存入数据库
Date nowTime = new Date(System.currentTimeMillis());
SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String retStrFormatNowDate = sdFormatter.format(nowTime);
values.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, retStrFormatNowDate);
(3)在NoteList.java的PROJECTION数组中增加该字段的描述,并在SimpleCursorAdapter中的参数viewsIDs和dataColumns增加子段描述,以达到将其读出和显示的目的
//The columns needed by the cursor adapter
private static final String[] PROJECTION = new String[] {
NotePad.Notes._ID, // 0
NotePad.Notes.COLUMN_NAME_TITLE, // 1
NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE,
};
// The names of the cursor columns to display in the view, initialized to the title column
private String[] dataColumns = { NotePad.Notes.COLUMN_NAME_TITLE ,NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE} ;
// The view IDs that will display the cursor columns, initialized to the TextView in
private int[] viewIDs = { R.id.text1,R.id.text2 };
(1)在NodeList.java的布局文件中新增SearchView控件(备注:引用的是support.v7的包,如未找到,需在build.gradle(Module.app)中添加依赖
(2)在NodeList.java中创建一个函数专门来配置SeachView,实现查询的基本思想是新创建一个Cursor来通过SeacrhView搜索的字段在数据库中进行模糊搜索从而装配数据,并在ListView中即时显示,无需点击搜索按键,最后在onCreate()中调用
private void SearchView(){
searchView=findViewById(R.id.sv);
// a display model
searchView.onActionViewExpanded();
//default display
searchView.setQueryHint("搜索笔记");
//display submit button
searchView.setSubmitButtonEnabled(true);
//implement SearchView TextListener
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
// when text has been submitted
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
// when text is changing
@Override
public boolean onQueryTextChange(String s) {
if(!s.equals("")){
String selection=NotePad.Notes.COLUMN_NAME_TITLE+" GLOB '*"+s+"*'";//query selection condition
updatecursor = getContentResolver().query(
getIntent().getData(), // Use the default content URI for the provider.
PROJECTION, // Return the note ID and title for each note.
selection, // No where clause, return all records.
null, // No where clause, therefore no where column values.
NotePad.Notes.DEFAULT_SORT_ORDER // Use the default sort order.
);
}
else {
updatecursor = getContentResolver().query(
getIntent().getData(), // Use the default content URI for the provider.
PROJECTION, // Return the note ID and title for each note.
null, // No where clause, return all records.
null, // No where clause, therefore no where column values.
NotePad.Notes.DEFAULT_SORT_ORDER // Use the default sort order.
);
}
// change adapter from SimpleCursorAdapter cursor
adapter.swapCursor(updatecursor);
// adapter.notifyDataSetChanged();
return false;
}
});
}
(1)在OptionMenu中添加修改颜色这一选项,并划分为两类,修改背景颜色和修改字体颜色
-
(2)采用AlertDialog来实现界面交互效果,并采用自定义布局定义UI界面,因为两种修改颜色调用的是同一个函数showColor(),因此定义一个boolean变量flag来判断
private void showColor(){
AlertDialog alertDialog=new AlertDialog.Builder(this).setTitle("请选择颜色").
setIcon(R.mipmap.ic_launcher).setView(R.layout.color_layout)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create();
alertDialog.show();
}
AlertDialog布局文件
布局文件按钮的点击事件
public void onClick(View v) {
switch (v.getId()){
case R.id.orange:
if(isFlag){
mText.setBackgroundColor(Color.parseColor("#FF8C00"));
colorBack="#FF8C00";
}else{
mText.setTextColor(Color.parseColor("#FF8C00"));
colorText="#FF8C00";
}
break;
case R.id.chocolate:
if(isFlag){
mText.setBackgroundColor(Color.parseColor("#D2691E"));
colorBack="#D2691E";
}else{
mText.setTextColor(Color.parseColor("#D2691E"));
colorText="#D2691E";
}
break;
case R.id.aqua:
if(isFlag){
mText.setBackgroundColor(Color.parseColor("#00FFFF"));
colorBack="#00FFFF";
}else{
mText.setTextColor(Color.parseColor("#00FFFF"));
colorText="#00FFFF";
}
break;
case R.id.gray:
if(isFlag){
mText.setBackgroundColor(Color.parseColor("#696969"));
colorBack="#696969";
}else{
mText.setTextColor(Color.parseColor("#696969"));
colorText="#696969";
}
break;
case R.id.pink:
if(isFlag){
mText.setBackgroundColor(Color.parseColor("#D81B60"));
colorBack="#D81B60";
}else{
mText.setTextColor(Color.parseColor("#D81B60"));
colorText="#D81B60";
}
break;
case R.id.green:
if(isFlag){
mText.setBackgroundColor(Color.parseColor("#00FF7F"));
colorBack="#00FF7F";
}else{
mText.setTextColor(Color.parseColor("#00FF7F"));
colorText="#00FF7F";
}
break;
}
}
(3)在onOptionItemSelected()中添加点击事件
case R.id.background_color:
isFlag=true;
showColor();
break;
case R.id.text_color:
isFlag=false;
showColor();
break;
(4)点击保存之后将颜色的16进制保存到数据库,也是通过updateNote()函数,具体实现与时间戳功能类似,这里说明一下数据库新增字段的实现
1.在NotePad.java中的内部类Notes添加契约
/*
* NoteEditor.java EditText setBackGroundColor
* */
public static final String COLUMN_BACKGROUND_COLOR="bColor";
/*
* NoteEditor.java EditText setTextColor
* */
public static final String COLUMN_TEXT_COLOR="tColor";
2.在NotePadProvider.java的静态构造块往sNotesProjectionMap添加相应的键值对
//Maps "bColor" to "bColor"
sNotesProjectionMap.put(
NotePad.Notes.COLUMN_BACKGROUND_COLOR,
NotePad.Notes.COLUMN_BACKGROUND_COLOR
);
//Maps "tColor" to "tColor"
sNotesProjectionMap.put(
NotePad.Notes.COLUMN_TEXT_COLOR,
NotePad.Notes.COLUMN_TEXT_COLOR
);
备注:如果已经在手机中安装app之后要新增或删减字段,需要在onUpgrade()中更换版本号,或者卸载重装。
(1)在数据库中添加标签字段,与修改颜色功能类似,不作相应代码显示
(2)在NodeEditor.java布局文件中添加Button控件,点击弹出AlertDialog显示类别选项,设置按钮文本
//tag selection defined
private final String items[]={"Default","Travel","Work","Study","Life"};
public void tagSelect(View v){
AlertDialog.Builder tagbuilder;
AlertDialog alertDialog;
tagbuilder=new AlertDialog.Builder(this);
tagbuilder.setTitle("Tag Selection:");
tagbuilder.setIcon(R.mipmap.ic_launcher);
tagbuilder.setSingleChoiceItems(items, checkItem, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
checkItem=which;
button.setText(items[checkItem]);
}
});
tagbuilder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog=tagbuilder.create();
alertDialog.show();
}
(3)点击保存之后会将按钮文本保存到数据库,与时间戳功能类似,不再作具体演示
(4)在NoteList.java添加抽屉布局,以显示侧滑菜单栏的效果
1.在AndroidManifest.xml中更改主题,禁用ActionBar,查看引用,在styles.xml中进行修改
android:theme="@style/AppTheme"
style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"
2.在布局文件中使用DrawerLayout布局和toolbar,还有NavigationView,与之前同理,导入的分别是v4和v7的包,如果没有,需要添加依赖(注:CoordinatorLayout是之前想做一个浮动布局加的,但后来放弃了,所以这个布局是可以删除的,只要修改号里面控件的width和height就可以)
3.NavigationView的菜单编写
(3)编写toolbar的监听事件和NavigationView的监听事件
1.toolbar
setSupportActionBar(toolbar); //set support toolbar in this Activity
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawerLayout.openDrawer(Gravity.START);// set from left open NavigationView Menu
}
});
2.NavigationView
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.notepad:
tagCursor = getContentResolver().query(
getIntent().getData(), // Use the default content URI for the provider.
PROJECTION, // Return the note ID and title for each note.
null, // No where clause, return all records.
null, // No where clause, therefore no where column values.
NotePad.Notes.DEFAULT_SORT_ORDER // Use the default sort order.
);
adapter.swapCursor(tagCursor);//swap cursor from SimpleCursorAdapter
toolbar.setTitle("MyNotePad");
drawerLayout.closeDrawer(navigationView);//close NavigationView menu
break;
case R.id.travel:
tagSelection=NotePad.Notes.COLUMN_TAG_SELECTION_INDEX+" = 'Travel'";
tagCursor = getContentResolver().query(
getIntent().getData(), // Use the default content URI for the provider.
PROJECTION, // Return the note ID and title for each note.
tagSelection, // No where clause, return all records.
null, // No where clause, therefore no where column values.
NotePad.Notes.DEFAULT_SORT_ORDER // Use the default sort order.
);
adapter.swapCursor(tagCursor);//swap cursor from SimpleCursorAdapter
toolbar.setTitle("Travel");
drawerLayout.closeDrawer(navigationView);//close NavigationView menu
break;
case R.id.work:
tagSelection=NotePad.Notes.COLUMN_TAG_SELECTION_INDEX+" = 'Work'";
tagCursor = getContentResolver().query(
getIntent().getData(), // Use the default content URI for the provider.
PROJECTION, // Return the note ID and title for each note.
tagSelection, // No where clause, return all records.
null, // No where clause, therefore no where column values.
NotePad.Notes.DEFAULT_SORT_ORDER // Use the default sort order.
);
adapter.swapCursor(tagCursor);//swap cursor from SimpleCursorAdapter
toolbar.setTitle("Work");
drawerLayout.closeDrawer(navigationView);//close NavigationView menu
break;
case R.id.study:
tagSelection=NotePad.Notes.COLUMN_TAG_SELECTION_INDEX+" = 'Study'";
tagCursor = getContentResolver().query(
getIntent().getData(), // Use the default content URI for the provider.
PROJECTION, // Return the note ID and title for each note.
tagSelection, // No where clause, return all records.
null, // No where clause, therefore no where column values.
NotePad.Notes.DEFAULT_SORT_ORDER // Use the default sort order.
);
adapter.swapCursor(tagCursor);//swap cursor from SimpleCursorAdapter
toolbar.setTitle("Study");
drawerLayout.closeDrawer(navigationView);//close NavigationView menu
break;
case R.id.life:
tagSelection=NotePad.Notes.COLUMN_TAG_SELECTION_INDEX+" = 'Life'";
tagCursor = getContentResolver().query(
getIntent().getData(), // Use the default content URI for the provider.
PROJECTION, // Return the note ID and title for each note.
tagSelection, // No where clause, return all records.
null, // No where clause, therefore no where column values.
NotePad.Notes.DEFAULT_SORT_ORDER // Use the default sort order.
);
adapter.swapCursor(tagCursor);//swap cursor from SimpleCursorAdapter
toolbar.setTitle("Life");
drawerLayout.closeDrawer(navigationView);//close NavigationView menu
break;
case R.id.def:
tagSelection=NotePad.Notes.COLUMN_TAG_SELECTION_INDEX+" = 'Default'";
tagCursor = getContentResolver().query(
getIntent().getData(), // Use the default content URI for the provider.
PROJECTION, // Return the note ID and title for each note.
tagSelection, // No where clause, return all records.
null, // No where clause, therefore no where column values.
NotePad.Notes.DEFAULT_SORT_ORDER // Use the default sort order.
);
adapter.swapCursor(tagCursor);//swap cursor from SimpleCursorAdapter
toolbar.setTitle("Default");
drawerLayout.closeDrawer(navigationView);//close NavigationView menu
break;
}
return true;
}
});
(1)在NodeEditor.java的optionmenu中添加选项
-
-
-
(2)拍照要在AndroidManifest.xml中设置权限,API23以上还要在代码中设置动态权限,API28以上权限设置更为严格,本功能并不适用。而从图库中选取照片权限要求较低.
//从相册取图片
public void getPhoto() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
startActivityForResult(intent, PHOTO_FROM_GALLERY);
}
//拍照取照片
public void takeCamera() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions( this, new String[] { Manifest.permission.CAMERA }, PHOTO_FROM_CAMERA);
}
else {
File file=new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
try {
if(file.exists()){
file.delete();
}
file.createNewFile();
}catch (IOException e){
e.printStackTrace();
}
imageUri=Uri.fromFile(file);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
startActivityForResult(intent, PHOTO_FROM_CAMERA);
}
}
(3)编写onActivityResult定义返回动作
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
ContentResolver resolver = getContentResolver();
super.onActivityResult(requestCode, resultCode, data);
//第一层switch
switch (requestCode) {
case PHOTO_FROM_GALLERY:
//第二层switch
switch (resultCode) {
case RESULT_OK:
if (data != null) {
Uri uri = data.getData();//获取Intent uri
Bitmap bitmap = null;
//判断该路径是否存在
try {
Bitmap originalBitmap = BitmapFactory.decodeStream(resolver.openInputStream(uri));
bitmap = resizeImage(originalBitmap, 200, 200);//图片缩放
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if(bitmap != null){//如果图片存在
//将选择的图片追加到EditText中光标所在位置
int index = mText.getSelectionStart(); //获取光标所在位置
Editable edit_text = mText.getEditableText();//编辑文本框
if(index <0 || index >= edit_text.length()){
edit_text.append(uri.toString());
updateNoteText(mText.getText().toString());//更新到数据库
}else{
edit_text.insert(index,uri.toString());
updateNoteText(mText.getText().toString());//更新到数据库
}
}else{
Toast.makeText(NoteEditor.this, "获取图片失败", Toast.LENGTH_SHORT).show();
}
}
break;
case RESULT_CANCELED:
break;
}
break;
case PHOTO_FROM_CAMERA:
if (resultCode == RESULT_OK) {
Bitmap originalBitmap1=null;
//判断图片是否存在
try{
originalBitmap1=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
}catch (FileNotFoundException e){
e.printStackTrace();
}
if(originalBitmap1 != null){//如果图片存在保存URI
//将选择的图片追加到EditText中光标所在位置
int index = mText.getSelectionStart(); //获取光标所在位置
Editable edit_text = mText.getEditableText();//编辑文本框
if(index <0 || index >= edit_text.length()){
edit_text.append(imageUri.toString());
updateNoteText(mText.getText().toString());//更新到数据库
}else{
edit_text.insert(index, imageUri.toString());
updateNoteText(mText.getText().toString());//更新到数据库
}
}else{
Toast.makeText(NoteEditor.this, "获取图片失败", Toast.LENGTH_SHORT).show();
}
} else {
Log.e("result", "is not ok" + resultCode);
}
break;
default:
break;
}
}
(4)定义两个正则表达式,提取文本的图片路径,用SpannableString进行图片文字替换,从而实现图片的插入
private static final String regex="content://com.android.providers.media.documents/"
+"document/image%\\w{4}";
private static final String reg="file:///storage/emulated/0/\\d+.jpg";
onResumn()和cancelNote()中编写
int colNoteIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE);//提取数据库中的文本
String note = mCursor.getString(colNoteIndex);
ArrayList contentList=new ArrayList<>();//存放图片路径
ArrayList startList=new ArrayList<>();//存放图片路径起点位置
ArrayList endList=new ArrayList<>();//存放图片路径终点位置
Pattern p=Pattern.compile(regex);
Matcher m=p.matcher(note);
//当匹配到图库相应资源地址,将对应信息存入List
while(m.find()){
contentList.add(m.group());
startList.add(m.start());
endList.add(m.end());
flag=true;
}
p=Pattern.compile(reg);
m=p.matcher(note);
//当匹配到拍照的图片相应资源地址,将对应信息存入List
while(m.find()){
contentList.add(m.group());
startList.add(m.start());
endList.add(m.end());
flag=true;
}
//判断文本中是否有图片资源地址
if(!flag){
mText.setText(note);
}else{
pushPicture(note,contentList,startList,endList);
}
图片处理
private void pushPicture(String note,ArrayList contentList,ArrayList startList,ArrayList endList) {
//创建一个SpannableString对象,以便插入用ImageSpan对象封装的图像
SpannableString spannableString = new SpannableString(note);
for(int i=0;i
(1)在NoteEditor.java中添加控件,我是选用Button,比较方便通过监听来处理事件,比较简单,就不作代码演示
(2)在NoteEditor.java中的OptionMenu中添加相应的选项,和选择事件的触发,也比较简单和上述功能类似,也不做代码演示
(3)创建DatePickerDialog和TimePickerDialog来进行时间与日期的选择
1.DatePickerDialog
private void createDateDialog(){
final Calendar calendar=Calendar.getInstance();
DatePickerDialog dialog = new DatePickerDialog(this, AlertDialog.THEME_HOLO_DARK,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
date=year+"-"+(month+1)+"-"+dayOfMonth;
if(time!=null){
dateButton.setText(date+time);
}else{
String text=calendar.get(Calendar.HOUR_OF_DAY)+":"+(calendar.get(Calendar.MINUTE)+5);
time=" "+text;//如果时间未指定,则默认为当前时间的5分钟后提醒
dateButton.setText(date+" "+text);
}
dateButton.setVisibility(View.VISIBLE);
}
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH));
dialog.getDatePicker().setMinDate(System.currentTimeMillis()-1000);//选择以当前时间开始,避免无效时间的选择
dialog.setTitle("选择日期:");
dialog.show();
}
2.TimePickerDialog
private void createTimeDialog(){
final Calendar calendar=Calendar.getInstance();
TimePickerDialog dialog=new TimePickerDialog(this, AlertDialog.THEME_HOLO_DARK,new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
String text=calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)+"-"+calendar.get(Calendar.DAY_OF_MONTH);
/*
* 判断时间的选择是否为无效时间,在当前的时间之前
* */
if(text.equals(date)||date==null){
if(hourOfDay<=calendar.get(Calendar.HOUR_OF_DAY))
if(minute-5<=calendar.get(Calendar.MINUTE)){
//为无效时间的话就将时间设为五分钟之后
time=" "+calendar.get(Calendar.HOUR_OF_DAY)+":"+(calendar.get(Calendar.MINUTE)+5);
}
else{
time=" "+calendar.get(Calendar.HOUR_OF_DAY)+":"+minute;
}
else{
time=" "+hourOfDay+":"+minute;
}
}else{
time=" "+hourOfDay+":"+minute;
}
if(date!=null){
dateButton.setText(date+time);
}else{
date=text;
dateButton.setText(text+time);
}
dateButton.setVisibility(View.VISIBLE);
}
},
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE), true);
dialog.setTitle("选择时间:");
dialog.show();
}
(4)当保存笔记之后,将需要提醒的信息封装进PendingIntent,以广播的形式发送出去
private void notifyMessage(){
if(time!=null&&date!=null){
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm");
long t=System.currentTimeMillis()+5000;
try {
t=simpleDateFormat.parse(date+time).getTime();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
//是Intent跳转到指定的广播处理
Intent intent=new Intent(NoteEditor.this, RemindActionBroadcast.class);
/*
* 把文本的内容和标题存入Intent
* */
intent.putExtra("title",mCursor.getString(mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE)));
intent.putExtra("context",mCursor.getString(mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE)));
//将requestCode设为每个文本的ID以实现能够发送不同的信息,不会被覆盖
PendingIntent pendingIntent=PendingIntent.getBroadcast(NoteEditor.this,mCursor.getInt(mCursor.getColumnIndex(NotePad.Notes._ID)),intent,PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar=Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND,(int)((t-System.currentTimeMillis())/1000));
//使用AlarmManager实现定时功能
AlarmManager alarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),pendingIntent);
}
}
(5)在广播接受类中进行处理和通知
public class RemindActionBroadcast extends BroadcastReceiver {
public static int id=0;
@Override
public void onReceive(Context context, Intent intent) {
PendingIntent pendingIntent=PendingIntent.getActivity(context,0,intent,0);
NotificationManager notificationManager=(NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
Notification.Builder mbuilder=new Notification.Builder(context);
mbuilder.setContentTitle(intent.getStringExtra("title"));//设置通知栏标题
mbuilder.setContentText(intent.getStringExtra("context"));//设置通知栏内容
mbuilder.setSmallIcon(R.mipmap.ic_launcher);//设置小图标
mbuilder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher));//设置大图标
mbuilder.setContentIntent(pendingIntent);//设置点击跳转的Intent,因为没有设置uri,所以跳转为空
mbuilder.setAutoCancel(true);//点击之后消失
Notification notification=mbuilder.build();
notificationManager.notify(id++,notification);//能够传送多条消息
}
}
(6)点击设置时间按钮取消设置通知时间
public void dateClick(View view){
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setMessage("请确认是否删除提醒时间:").setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
date=null;
time=null;
dateButton.setVisibility(View.GONE);
dialog.dismiss();
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}