项目下载
首先新建一个数据库工具类继承自SQLiteOpenHelper,然后在构造方法中指定数据库名称
和版本号进行初始化。代码如下:
MyDataBase.java
package chzu.csci.pwn.androidquiz;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDataBase extends SQLiteOpenHelper {
private static final String DB_NAME="2017211808.db";
private static final int DB_VERSION=1;
MyDataBase(Context context){
super(context,DB_NAME,null,DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(//第一次运行时新建一个BANK表,并且插入初始数据
"CREATE TABLE BANK (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+"TYPE TEXT,"
+"QUESTION TEXT,"
+"ANSWER TEXT);"
);
insertBank(db,"架构","Android系统架构自底向上第二层是?");
insertBank(db,"编程","Android App开发支持编程语言包括?");
insertBank(db,"服务","绑定服务使用什么方法?");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
private static void insertBank(SQLiteDatabase db,String type,String question){
ContentValues value=new ContentValues();
value.put("TYPE",type);
value.put("QUESTION",question);
long result=db.insert("BANK",null,value);
}
}
调用SQLiteDatabase类的insert方法即可,代码如下,具体调用可以看上面的MyDataBase.java:
ContentValues value=new ContentValues();
value.put("TYPE",type);//字段名和值
value.put("QUESTION",question);//字段名和值
long result=db.insert("BANK",null,value);
调用SQLiteDatabase类的delete方法即可,代码如下:
SQLiteOpenHelper helper=new MyDataBase(this);
try{
SQLiteDatabase db=helper.getWritableDatabase();
//删除TYPE字段为"架构"的行
db.delete("BANK","TYPE=?",new String[]{"架构"});
}catch (SQLException e){
Toast.makeText(this,"DataBase unavalibale",Toast.LENGTH_SHORT).show();
}
调用SQLiteDatabase类的update方法,传入ContentValues对象即可,代码如下:
SQLiteDatabase db=helper.getWritableDatabase();
ContentValues bankvalues=new ContentValues();
bankvalues.put("ANSWER",answer);//ANSWER为想要修改的字段名,answer为想要修改成的值
db.update("BANK",bankvalues,"_id=?",new String[]{Integer.toString(ID)});
调用SQLiteDatabase类的query方法,返回一个Cursor对象,类似于ResultSet结果集,
代码如下:
SQLiteDatabase db=helper.getReadableDatabase();
cursor= db.query("BANK",new String[]{"_id","TYPE"},null,null,null,null,null);//相当于执行SQL语句SELECT _id,TYPE FROM BANK
加上查询条件,代码如下:
SQLiteDatabase db=helper.getReadableDatabase();
cursor=db.query("BANK",new String[]{"QUESTION","ANSWER"},"_id=?",
new String[]{Integer.toString(ID)},null,null,null);
/*相当于执行SQL语句SELECT QUESTION,ANSWER FROM BANK WHERE _id=ID*/
public void onClickSave(View view){
/*此处填写点击后的响应事件逻辑代码,另外在视图层对应的xml文件中相应按钮的属性设置android:onClick="onClickSave"*/
}
通过findViewById方法获取ListView组件,然后再调用db的query方法获取数据库中的内容,
返回值是一个Cursor游标对象,对SimpleCursorAdapter类进行构造后生成对象后,调用
ListView对象的setAdapter方法,进行适配器设置,即可在页面中显示数据库内容。
/*listView为响应的ListView组件对象,cursor为查询出的的游标对象,new String{"TYPE"}是在ListView中展示的内容
*/
SimpleCursorAdapter listAdapter=new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1,
cursor,new String[]{"TYPE"},new int[]{android.R.id.text1},0);
listView.setAdapter(listAdapter);
通过构造一个Intent对象,然后调用intent对象的putExtra方法存入数据,最后调
用startActivity方法启动。
/*MainActivity是跳转前的界面Activity,SecondActivity是跳转的目标界面的Activity*/
Intent intent=new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("ID",(int)id);
startActivity(intent);
/*"DataBase unavalibale为显示的内容,Toast.LENGTH_SHORT为会话持续时间,改为Toast.LENGTH_LONG可以延长会话持续时间*/
Toast.makeText(this,"DataBase unavalibale",Toast.LENGTH_SHORT).show();
通过绑定式服务即可实现,在res目录下新建一个raw目录,然后将音乐文件粘贴进该目录,具体代码如下:
MusicService.java
package chzu.csci.pwn.androidquiz;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class MusicService extends Service{
private MediaPlayer mediaPlayer;
//Service初始化时调用
public void onCreate(){
super.onCreate();
mediaPlayer = MediaPlayer.create(this, R.raw.notice);//这里注意将音乐文件修改成自己的
}
public class MusicBinder extends Binder{
MusicService getMusic(){
return MusicService.this;
}
}
private IBinder binder=new MusicBinder();
@Override
public IBinder onBind(Intent intent) {
if(!mediaPlayer.isPlaying()){
// 开始播放
mediaPlayer.start();
// 允许循环播放
mediaPlayer.setLooping(true);
}
return binder;
}
public boolean onUnbind(Intent intent) {
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//先停止 再释放
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
mediaPlayer.release();
}
public MusicService() {
}
}
onClickStart方法调用后播放音乐,onClickStop方法调用后停止播放,可以将方法与按钮的onClick进行绑定,从而通过按钮控制音乐开关。
MainActivity.java
/*导入类代码省略*/
public class MainActivity extends AppCompatActivity {
/*无关代码省略*/
private MusicService musicService;
private ServiceConnection connection;
@Override
protected void onCreate(Bundle savedInstanceState) {
/*无关代码省略*/
connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder=(MusicService.MusicBinder)service;
musicService=binder.getMusic();
}
@Override
public void onServiceDisconnected(ComponentName name) { }
};
/*无关代码省略*/
}
/*无关代码省略*/
public void onClickStart(View view){
/*无关代码省略*/
Intent intent = new Intent(this,MusicService.class);
bindService(intent,connection,BIND_AUTO_CREATE);
}
public void onClickStop(View view){
/*无关代码省略*/
unbindService(connection);
}
}
主要就是将Activity的某些变量在Activity退出调用onSaveInstanceState时进行值储存,然后在载入Activity调用onCreate方法时进行值读取,相关代码如下:
MainActivity.java
/*无关代码已省略*/
public class MainActivity extends AppCompatActivity {
private boolean running=false;
private int seconds=0;
private boolean wasRunning=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState!=null){
seconds=savedInstanceState.getInt("seconds");
running=savedInstanceState.getBoolean("running");
wasRunning=savedInstanceState.getBoolean("wasRunning");
}
}
@Override
protected void onStop() {
super.onStop();
wasRunning=running;
running=false;
}
@Override
protected void onStart() {
super.onStart();
if(wasRunning){
running=true;
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("running",running);
outState.putInt("seconds",seconds);
outState.putBoolean("running",wasRunning);
}
}
一些耗时操作可以用线程操作,以免堵塞。可以声明一个内部类继承自AsyncTask,然后
重写其onPreExecute、doInBackground、onPostExecute方法。调用时调用该内部类对象
的execute方法即可,注意drinkId与AsyncTask中的Integer相对应。
/*无关代码已省略*/
public class DrinkActivity extends AppCompatActivity {
public void onFavoriteClicked(View view){
int drinkId=getIntent().getIntExtra(EXTRA_DRINKID,0);
new UpdateDrinkTask().execute(drinkId);
}
private class UpdateDrinkTask extends AsyncTask<Integer,Void,Boolean>{
private ContentValues drinkvalues;
@Override
protected void onPreExecute() {
/*执行初始化任务,可以在此进行一些变量的值的初始化*/
CheckBox favorite=(CheckBox)findViewById(R.id.favorite);
drinkvalues=new ContentValues();
drinkvalues.put("FAVORITE",favorite.isChecked());
}
@Override
protected Boolean doInBackground(Integer... integers) {
/*执行费时任务,返回一个boolean值,可以在此执行一些数据库等费时操作*/
int drinkId=integers[0];
SQLiteOpenHelper helper=new StarbuzzDatabaseHelper(DrinkActivity.this);
try{
SQLiteDatabase db=helper.getWritableDatabase();
db.update("DRINK",drinkvalues,"_id=?",new String[]{Integer.toString(drinkId)});
return true;
}catch (SQLException e){
return false;
}
}
@Override
protected void onPostExecute(Boolean aBoolean) {
/*代码*/
}
}
}