Android中SQLite数据库解决单引号冲突

代码与范例:

tagfilter=tagfilter.replace("'", "''");
sel = "tag ='" + tagfilter + "'";
Cursor c = db.query(DB_TABLE, new String[] { "title", "tag", "deadline" }, sel, null, null, null, "id");

说明:Android 所采用的 SQLite 数据库在 query,execSQL 等操作时无法识别字符串中出现的单引号(’),而会导致 SQLiteException。比如在范例中,若 tagfilter 的值为 Harry’s personal life ,则会出现错误,因为 s 之前的单引号会被识别为语句终结符。比较简单的解决方法就是通过 replace() 将原单引号替换为连续两个的单引号(”)。注意 replaceAll() 需要提供正则表达式,用法有所不同。

此外 SQLite 对于 ContentValues 方式或是 execSQL (String sql, Object[] bindArgs) 方法不会有这一问题,也可作为一种解决方案。

Android中使用可以控制状态(开始、暂停、停止)的 ProgressBar

代码与范例:

// 通过类 ProgressBarUpdater 来控制线程的运行状态
public class ProgressBarUpdater implements Runnable {
	private volatile boolean paused = true;
	private volatile boolean finished = false;

	public void run() {
		while (!finished) {
			// wait
			try {
				Thread.sleep(500);
			} catch (InterruptedException e1) {
			}
			if (!paused) {
			// Update the progress status
			ProgressStatus = doWork();
			progressBar.setProgress(ProgressStatus);
			}
				while (paused && !finished) {
				// wait
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					}
			}
		}
	}

	public synchronized void pauseProgressBar() {
		paused = true;
	}

	public synchronized void unPauseProgressBar() {
		paused = false;
		// call notify() here when you switch to wait/notify.
	}

	public void stopProgressBar() {
		finished = true;
		// call notify() here too.
	}
}

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	setTitle(getResources().getString(R.string.number));

	ProgressStatus = 0;
	Button1 = (Button) this.findViewById(R.id.button1);
	Button1.setOnClickListener(this);
	Button2 = (Button) this.findViewById(R.id.button2);
	Button2.setOnClickListener(this);
	progressBar = (ProgressBar) findViewById(R.id.progressBar1);
	progressBar.setMax(100);
	progressBar.setProgress(0);
	// progressBar.setSecondaryProgress(70);

	// 使用 ProgressBarUpdater 来构造新的线程
	ProgressBarUpdater pbu = new ProgressBarUpdater();
	Thread t = new Thread(pbu);
	t.start();
	pbu.pauseProgressBar();
}

// 通过 ProgressBarUpdater 来控制进度条的运行状态
@Override
public void onClick(View v) {
	if (v.getId() == R.id.button1) {
		pbu.unPauseProgressBar();
	}
	if (v.getId() == R.id.button2) {
		pbu.pauseProgressBar();
	}
}

说明:可以通过一个辅助类来方便地改变控制 ProgressBar 的线程的运行状态。一个可以暂停与中断的进度条在有些情况下是很必要的。

Android中使用SeekBar

代码与范例:

// 创建并绑定 SeekBar
SeekBar seekBar = (SeekBar) this.findViewById(R.id.seekBar1);
// 设置 SeekBar 的最大值与初始位置
seekBar.setMax(10);
seekBar.setProgress(3);
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
	// 开始拖动 SeekBar 时的行为
	}

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
	// 正在拖动 SeekBar 时的行为。progress 为 SeekBar 当前所处位置
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
	// 停止拖动 SeekBar 时的行为		
	}
});

说明:SeekBar 是 Android UI 中常用的组件,在有范围的快速数值选择情况下能发挥较好的作用。

Android中判断是否支持GPS定位

代码与范例:

public boolean hasGPSDevice(Context context)
{
	final LocationManager mgr = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
	if ( mgr == null ) 
		return false;
	final List providers = mgr.getAllProviders();
	if ( providers == null ) 
		return false;
	return providers.contains(LocationManager.GPS_PROVIDER);
}

说明:通常Android设备有三种方式取得地理信息,GPS、移动网络和WiFi。GPS的表示名为”gps”,而移动网络和WiFi的表示名为”network”,它们统称为”provider”。因此,GPS_PROVIDER指的是GPS定位,而NETWORK_PROVIDER就是指后两种定位方式。

Android中通过Intent调用其他应用的方法

启动浏览器

代码与范例:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));  
startActivity(intent);

说明:启动浏览器并前往http://www.google.com 。

启动拨号程序

代码与范例:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("tel:138"));
startActivity(intent);

说明:启动拨号程序并输入号码138。

通话

代码与范例:

Uri uri=Uri.parse("tel:138");
Intent intent=new Intent(Intent.ACTION_CALL,uri);
startActivity(intent);

说明:拨打号码138。需要为程序申请权限<uses-permission android:name=”android.permission.CALL_PHONE”/>。

发送短信

代码与范例:

Uri smsUri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, smsUri);
intent.setType("vnd.android-dir/mms-sms");
startActivity(intent);

说明:启动短信程序。

启动通讯录

代码与范例:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("content://contacts/people/1"));
startActivity(intent);

说明:启动同学录的某一条目。

启动地图程序(Google Maps等)

代码与范例:

Uri mapUri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, mapUri);
startActivity(intent);

说明:启动地图程序。

搜索路线

代码与范例:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setClassName("com.google.android.apps.maps","com.google.android.maps.MapsActivity");
intent.setData(Uri.parse("http://maps.google.com/maps?myl=saddr&daddr=&dirflg=d"));
startActivity(intent);

说明:启动Google Maps并搜索路线,具体的方法另外补充。

启动邮件程序

代码与范例:

Uri uri =Uri.parse("mailto:xxx@example.com");
Intent intent = newIntent(Intent.ACTION_SENDTO, uri);
intent.putExtra(Intent.EXTRA_SUBJECT, "Hello world");
intent.putExtra(Intent.EXTRA_TEXT, "Ganbarimasu");
startActivity(intent);

说明:启动邮件程序并将收件人设为xxx@example.com,邮件主题设为Hello world,内容设为Ganbarimasu。

启动邮件程序并添加多个收件人

代码与范例:

Intent intent=new Intent(Intent.ACTION_SEND);     
String[] tos={"me@example.com"};     
String[]ccs={"you@example.com"};     
intent.putExtra(Intent.EXTRA_EMAIL, tos);     
intent.putExtra(Intent.EXTRA_CC, ccs);     
intent.putExtra(Intent.EXTRA_TEXT, "The email body text");     
intent.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");     
intent.setType("message/rfc822");     
startActivity(Intent.createChooser(intent,"Choose Email Client"));

说明:启动邮件程序并设置为发送给多个收件人。

启动邮件程序并添加附件

代码与范例:

Intent intent = newIntent(Intent.ACTION_SEND);   
intent.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");    
intent.putExtra(Intent.EXTRA_STREAM,"file:///sdcard/mysong.mp3);   
sendIntent.setType("audio/mp3");   
startActivity(Intent.createChooser(intent,"Choose Email Client"));

说明:启动邮件程序并添加附件。

播放MP3文件

代码与范例:

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri =Uri.parse("file:///sdcard/song.mp3");
intent.setDataAndType(uri,"audio/mp3");
startActivity(intent);

说明:启动音乐程序并播放MP3歌曲。

卸载程序

代码与范例:

Uri uri =Uri.fromParts("package", strPackageName, null);   
Intent intent = newIntent(Intent.ACTION_DELETE, uri);   
startActivity(intent);

说明:卸载包名为strPackageName的程序。

安装程序

代码与范例:

Uri installUri = Uri.fromParts("package",strPackageName, null);
returnIt = newIntent(Intent.ACTION_PACKAGE_ADDED, installUri);

说明:安装包名为strPackageName的程序。

启动设置

代码与范例:

Intent intent=new Intent("android.settings.SETTINGS");
startActivity(intent);

说明:进入设定程序。

启动电子市场

代码与范例:

Uri uri=Uri.parse("market://search?q=pname:org.breezesoft.techolite");
Intent intent=new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);

说明:以包名org.breezesoft.techolite为条件启动Android Market。

启动电子市场并进入程序信息界面

代码与范例:

Uri uri = Uri.parse("market://details?id=org.breezesoft.techolite");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

说明:启动Android Market并进入包名为org.breezesoft.techolite的程序的详细信息界面。

从图库(Gallery)中选择并获取一张图片

代码与范例:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, 11);

说明:启动图库并中选择并获取一张图片,返回原程序。

Android中动态调整选项菜单(Options Menu)内容

代码与范例:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	super.onCreateOptionsMenu(menu);
	return true;
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
	super.onCreateOptionsMenu(menu);
	// 清除菜单内容后由条件判断语句决定如何生成选项菜单
	menu.clear();
	if (condition == 0) {
		MenuItem item0 = menu.add(0, 0, 0, R.string.text1a);
		item0.setIcon(android.R.drawable.icon1a);
	} else {
		MenuItem item0 = menu.add(0, 0, 0, R.string.text1b);
		item0.setIcon(android.R.drawable.icon1b);
	}
	MenuItem item1 = menu.add(0, 1, 0, R.string.text2);
	item1.setIcon(android.R.drawable.icon2);
	return true;
}

说明:有的时候需要选项菜单(Options Menu)的内容根据情况调整,这时只要覆写onPrepareOptionsMenu方法即可。注意不要忘记清除菜单中的原有内容。

Android中各种类型对话框的使用

只有标题和文本内容简单对话框

代码与范例:

AlertDialog.Builder dlg;
dlg = new AlertDialog.Builder(AlertDialogSample.this);
dlg.setTitle("简单对话框");
dlg.setMessage("Hello, AlertDialog!");
dlg.show();

说明:生成一个只有标题与内容的简单对话框。

含有一个按钮的对话框

代码与范例:

AlertDialog.Builder dlg;
dlg = new AlertDialog.Builder(AlertDialogSample.this);
dlg.setTitle("但按钮对话框");
dlg.setMessage("Hello, AlertDialog!");
dlg.setPositiveButton("OK", null)
dlg.show();

说明:生成一个含有一个按钮的简单对话框,点击该按钮将关闭对话框。

含有两个按钮的对话框

代码与范例:

new AlertDialog.Builder(AlertDialogSample.this)
.setTitle("提示")
.setMessage("确定退出?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int id) {
		AlertDialogSample.this.finish();
      }
  })
  .setNegativeButton("No", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int id) {
           dialog.cancel();
      }
  })
  .show();

说明:生成一个含有两个按钮的简单对话框。

含有三个按钮的对话框

代码与范例:

new AlertDialog.Builder(this)
.setIcon(R.drawable.icon)
.setTitle("YES/NO Dialog")
.setMessage("Is this a pen ?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
        /* 这里是YES的处理 */
    }
})
.setNeutralButton("No", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
        /* 这里是NO的处理 */
    }
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
        /* 这里是Cancel的处理 */
    }
})
.show();

说明:生成一个含有三个按钮的对话框。

含有一个单选列表的对话框

代码与范例:

final CharSequence[] items = {"红", "绿", "蓝"};
new AlertDialog.Builder(AlertDialogSample.this)
.setTitle("选择颜色")
.setItems(items, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int item) {
    	button.setText(String.format("选择了%s。",items[item]));
    }
})
.show();

说明:生成一个含有一个单选列表的对话框。

含有一个多选列表的对话框

代码与范例:

final CharSequence[] items = {"红", "绿", "蓝"};
final boolean[] checkedItems = {true, false, true};
new AlertDialog.Builder(AlertDialogSample.this)
.setTitle("Pick a color")
.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
	public void onClick(DialogInterface dialog, int which,boolean isChecked) {
		checkedItems[which]=isChecked;
	}
})
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int id) {
		for(int i=0;i

说明:生成一个含有一个多选列表的对话框。

含有Radio Button的对话框

代码与范例:

String[] str_items = {"红","绿","蓝"};
String result_item = "";

int def_index = 2;
result_item = str_items[def_index];

new AlertDialog.Builder(this)
.setIcon(R.drawable.icon)
.setTitle("选择颜色")
.setSingleChoiceItems(str_items, def_index,
new DialogInterface.OnClickListener(){
	public void onClick(DialogInterface dialog, int which) {
		result_item = str_items[which];
	}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int whichButton) {
		new AlertDialog.Builder(AlertDialogText.this)
        		.setTitle("color=" + result_item)
        		.show();
	}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int whichButton) {
		new AlertDialog.Builder(AlertDialogText.this)
        		.setTitle("Canceled")
        		.show();
	}
})
.show();
}

说明:生成一个含有Radio Button的对话框。

自定义对话框

代码与范例:

LayoutInflater inflater = LayoutInflater.from(AlertDialogSample.this);
View layout = inflater.inflate(R.layout.custom_dialog,(ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("这是一个自定义对话框!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.icon);
new AlertDialog.Builder(AlertDialogSample.this)
.setView(layout)
.show();

其中代码的第一行也可以用以下两种之一替换来展开布局:

LayoutInflater inflater = (LayoutInflater) getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater inflater = SampleDialog1.this.getLayoutInflater();

直接通过代码生成布局也可以,虽然不是太推荐这种做法:

LinearLayout layout = new LinearLayout(AlertDialogSample.this);

ImageView image = new ImageView(AlertDialogSample.this);
image.setImageResource(R.drawable.icon);
layout.addView(image);

TextView text = new TextView(AlertDialogSample.this);
text.setText("这是一个自定义对话框!");
layout.addView(text);

new AlertDialog.Builder(AlertDialogSample.this)
	.setView(layout)
	.show();

说明:生成一个含有自定义视图的对话框,其中用到了自定义的xml布局文件custom_dialog.xml。

综合对话框

代码与范例:

final CharSequence[] items = {"红", "绿", "蓝"};
final boolean[] checkedItems = {true, false, true};
TextView tv=new TextView(AlertDialogSample.this);
tv.setText("setView");
new AlertDialog.Builder(AlertDialogSample.this)
.setIcon(R.drawable.icon)
.setTitle("综合对话框")
.setView(tv)
.setMessage("Hello, World!")
.setItems(items, new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int item) { }
})
.setSingleChoiceItems(items, 1, new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int item) { }
})
.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
	public void onClick(DialogInterface dialog, int which,
			boolean isChecked) { }
        	})
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int id) {
		AlertDialogSample.this.finish();
      }
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int id) {
           dialog.cancel();
      }
})
.show();

说明:综合使用上述几种对话框。

含有文本框的对话框

代码与范例:

et = new EditText(this);
new AlertDialog.Builder(this)
.setIcon(R.drawable.icon)
.setTitle("吃什么?")
.setView(et)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int whichButton) {
		new AlertDialog.Builder(AlertDialogText.this)
			.setTitle("吃: " + edtInput.getText().toString())
			.show();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int whichButton) {
}
})
.show();

说明:生成一个能够输入文本的对话框。

含有进度条的对话框

代码与范例:

public class AlertDialogText extends Activity {
	public ProgressDialog progDlg;
	public Handler progHandler;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 生成对话框
        progDlg = new ProgressDialog(this);
        progDlg.setIcon(R.drawable.icon);
        progDlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progDlg.setMax(100);
        progDlg.setButton("Cancel", new DialogInterface.OnClickListener(){
        	public void onClick(DialogInterface dialog, int whichButton) {
        		progDlg.cancel();
        	}
        });
        // 使进度条前进
        progHandler = new Handler() {
        	public void handleMessage(Message msg) {
        		super.handleMessage(msg);
        		int v = progDlg.getProgress();
        		if (v >= 100) {
        			progDlg.dismiss();
        		} else {
        			progDlg.incrementProgressBy(1);
        			progHandler.sendEmptyMessageDelayed(0, 100);
        		}
        	}
        };
        // 按下Ok按钮的反应
        new AlertDialog.Builder(this)
        .setTitle("PUSH START BUTTON")
        .setPositiveButton("START", new DialogInterface.OnClickListener() {
        	public void onClick(DialogInterface dialog, int whichButton) {
        		progDlg.show();
        		progHandler.sendEmptyMessage(0);
        	}
        })
        .show();
   }
}

说明:生成一个含有进度条的对话框。

含有正在运行标识的对话框

代码与范例:

ProgressDialog dialog = ProgressDialog.show(AlertDialogSample.this, "","载入中,请稍候", true);

说明:生成一个含有一个正在运行的循环旋转标识的简单对话框。

Android 开发笔记

作为分类目录的一个补充,在这里按照功能类别对Android开发中的一点心得和笔记作一个索引。其中部分是根据自己在查找网络资料时找到的内容的整理与演绎,在此感谢所有那些无私分享经验的人们。

基本

控件使用

资源调用

声音和图像

用户界面

活动 线程 服务

设备控制

SQLite

Android Studio

其他

Android开发入门

Android无疑是当前最为热门的移动设备操作系统之一,越来越多的开发者开始为Android开发应用。进行Android开发的目的大致可以分为商业盈利目的和业余爱好。对于后者,不少开发者在刚接触Android开发时总会有各种各样的问题,我想在这篇文章里谈谈如何入门Android。

进行Android开发所必需的素质:

做任何一件事,最重要的恐怕就是兴趣了。甚至可以说,只要有兴趣,做很多事都会顺利很多。因为有兴趣的话,就能够坚持下去,就会进行自主学习。其实这个主题不需要多说,因为要做好任何一件事,所必需的素质都是大同小异的,不是么。

进行Android开发所必需的理论知识:

Android的语法是基于Java的。因此如果对于Java有一定的掌握,开始Android的学习将是一件轻松的事。但是Java并不是学习Android前所必需的,甚至对于Java的了解有时反而会成为学习Android的障碍。毕竟,Android有许多独有的特性,以Java的思路去思考Android有时反而会产生限制。不过基础的OOP编程思想是必要的,如果仅仅学习过C语言这样的面向过程语言,恐怕需要先补充一些知识才能对Android比较顺利地上手。

此外一些基本的计算机相关知识自然也是需要的。对eclipse以及命令行的熟悉将是一种帮助。在开发某些类型的应用程序时OpenGL ES以及SQLite等的相关知识也是必需的。

进行Android开发所必需的软硬件准备:

  • 软件方面
    1. 操作系统:操作系统方面并没有太多的限制,Windows、Max OS和Linux都有对应的SDK。
    2. Java运行环境:开发Android之前需要在计算机上配置好JRE(Java运行环境,Java Runtime Environment),安装好JDK(Java开发套件,Java Development Kit )。具体的方法在开发指南中会有介绍。
    3. IDE(集成开发环境,Integrated development environment):Android的话推荐使用eclipse,这也是Android官方所推荐的。目前的最新版是3.7的Indigo。
  • 硬件方面
    1. 分辨率较高的显示器很重要。笔记本电脑的话或许没有办法,如果是台式机的话,推荐使用分辨率至少为1920×1080的显示器。
    2. 硬盘性能也对开发有着比较大的影响。有条件的话还是使用比较高速的硬盘比较好,能节省不少时间。
    3. 处理器的性能主要影响模拟器的速度。如果有实机进行开发的话,这一点就并不那么重要了。

初学Android开发的一点建议:

要开始学习Android的话,可以选择买一本好书,然后边读边实践。也可以从网络上找资料,自己摸索尝试。前者的优点是翻书比较方便,而且内容经过了作者的整理,缺点则是书的内容毕竟有限。后者的优点是免费,内容多,缺点是比较杂乱,花费时间可能会比较多。

另外自己深有体会的是,网络上的中文内容并不是很齐全,相较英语甚至是日语而言,整体水平低了不少。因此在遇到问题时,尝试通过英语搜索会是一个好主意。自己也有多次“通过中文很久无法找到答案,而通过英语/日语很快解决了问题”的经历。另外在例如Stack Overflow或是Quora这样的问答网站里几乎总是能找到高质量的答案(如果没有,就自己提问吧,得到满意回答的可能性是很高的),特别是Stack Overflow,在编程中遇到问题时应该想到它。总而言之,一定的英语能力可以大大提高自己的学习效率。

有了这些准备之后,就开始正式的Android开发之旅吧。首先可以跟着别人的代码摸索一下Android开发的大致流程,之后了解一下Android提供的各种控件。有了一定的熟悉之后,就可以开始考虑试着编写自己的程序了。

推荐书籍:

可以参见我的一些简单的笔记。

下一次将具体介绍一下Android开发环境的搭建。