领卓教育培训第五十七天
sqlite数据库存储
sqlite是Android系统内置的一款轻量级的关系型数据库,它的运算速度非常快,占用内存资源很少,因此特别适合在移动设备上使用。
使用一般步骤
- 继承sqliteOpenHelper实现一个数据库打开器类。
- 在其中建库,建表。
- 调用数据库打开器的getWritableDatabase()方法,得到一个sqliteDatabase对象。
- 调用该对象的execsql()方法执行sql语句或insert(),delete(),update(),query()方法完成对数据库的增、删、改、查操作。
- 使用完毕后,关闭sqliteDatabase对象。
注意:数据库文件会存放在/data/data/包名/databases/目录下。
代码示例
创建sqliteManager类继承sqliteOpenHelper
import android.content.Context;
import android.database.sqlite.sqliteDatabase;
import android.database.sqlite.sqliteOpenHelper;
/** * Created by Administrator on 2015/9/7. */
public class sqliteManager extends sqliteOpenHelper{
public sqliteManager(Context context,String name,sqliteDatabase.CursorFactory factory,int version) {
super(context,name,factory,version);
}
public sqliteManager(Context context,String name){
this(context,null,1);
}
@Override
public void onCreate(sqliteDatabase db) {
//创建表,语句跟基本的sql语句一样
db.execsql("create table if not exists userInformation(id Integer primary key autoincrement,username varchar(20),password varchar(20))");
}
@Override
public void onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) {
}
}
修改activity_main.xml中的代码
添加5个按钮,设置对数据库的操作
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<Button android:id="@+id/button_createdb" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="创建数据库"/>
<Button android:id="@+id/button_insert" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="插入数据库"/>
<Button android:id="@+id/button_update" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="更改数据库"/>
<Button android:id="@+id/button_delete" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="删除数据库"/>
<Button android:id="@+id/button_select" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="查询数据库"/>
</LinearLayout>
MainActivity.java
mport android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.sqliteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.example.administrator.MysqLite.db.sqliteManager;
public class MainActivity extends AppCompatActivity {
private sqliteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sqliteManager manager=new sqliteManager(MainActivity.this,"MyFistDatabase.db");
db=manager.getWritableDatabase();//创建数据库,并且调用sqliteManager中的onCreate()方法创建表
Button button_createdb= (Button) findViewById(R.id.button_createdb);
button_createdb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"您已成功创建数据库!",Toast.LENGTH_SHORT).show();
}
});
Button button_insert= (Button) findViewById(R.id.button_insert);
button_insert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values=new ContentValues();
values.put("username","张三");
values.put("password","123456");
//向表userInformation中插入数据
db.insert("userInformation",values);
}
});
Button button_update= (Button) findViewById(R.id.button_update);
button_update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values=new ContentValues();
values.put("password","abcdef");
//将表userInformation中name=张三的数据的password改为abcdef
db.update("userInformation",values,"username=?",new String[]{"张三"});
}
});
Button button_delete= (Button) findViewById(R.id.button_delete);
button_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//删除表userInformation中username=张三的数据
db.delete("userInformation",new String[]{"张三"});
}
});
Button button_select= (Button) findViewById(R.id.button_select);
button_select.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//查询表userInformation,返回Cursor对象
//Cursor cursor=db.rawQuery("select * from userInformation",null);
Cursor cursor=db.query("userInformation","id DESC","0,1");//0是offset偏移量,1是查询的数量
cursor.moveToFirst();
while (!cursor.isAfterLast()){
String username=cursor.getString(cursor.getColumnIndex("username"));
String password=cursor.getString(cursor.getColumnIndex("password"));
Log.d("数据库信息","用户名:"+username+" 密码:"+password);
cursor.moveToNext();
}
}
});
}
}
@H_933_403@四大组件之Content Provider
Content Provider是内容提供器,主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性,是Android目前实现跨程序共享数据的标准方式。
用法
内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内容提供器给我们程序的数据提供外部访问接口。
现有的内容提供器
对于每个应用程序来说,如果要访问内容提供器中共享的数据,就要借助ContentResolver类,可以通过Context中的getContentResolver()方法来获取该类的实例。
ContentResolver中的增删改查方法与sqliteDatabase中类似,不过接收的参数用一个Uri参数代替,这个参数称为内容URI。内容URI由两部分组成,权限和路径。权限是用于对不同的应用程序做区分的,一般为了避免冲突,都会采用程序包名的方式来命名。路径则是用于对同一应用程序中不同的表做区分,通常都会添加在权限的后边。最后我们还要在头部加上协议声明。所以内容URI的最标准格式写法为:
content://com.example.app.provider/table1
调用Uri.parse()方法,就可以将内容URI字符串解析为Uri对象。
读取系统联系人
首先读取系统联系人需要在manifest.xml中声明权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>
然后查询联系人数据
Cursor cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONYRNY_URI,null);
cursor.moveToFirst();
while (!cursor.isAfterLast()){
String name=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.d("联系人信息","姓名:"+name+" 电话:"+number);
cursor.moveToNext();
}
注意:这里传入的Uri参数,是ContactsContract.CommonDataKinds.Phone类封装好的,CONYRNY_URI常量就是使用Uri.parse()方法解析出来的结果。
四大组件之Broadcast Receiver
Android的广播机制非常灵活,Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就之后接收到自己所关心的广播内容,这些广播可能是来自系统的,也可能是来自其他应用程序的。而接收广播的方法则需要引入Broadcast Receiver,广播接收器。
Broadcast Receiver的使用
首先我们要新建一个类MyBroadcastReceiver继承BroadcastReceiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/** * Created by Administrator on 2015/9/8. */
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent) {
Toast.makeText(context,"您收到了一个广播!",Toast.LENGTH_SHORT).show();
}
}
我们在布局中加入一个按钮,点击按钮,发送这条广播!
然后我们要注册我们的广播,有两种方式可以注册广播,一种为静态注册,一种为动态注册。
静态注册
静态注册需要我们在manifest.xml的application标签中添加如下内容:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="com.lingzhuo.broadcast"></action>
</intent-filter>
</receiver>
Button button_send= (Button) findViewById(R.id.button_send);
button_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.lingzhuo.broadcast");//传入的参数要与注册的name相同
sendBroadcast(intent);
}
});
这样运行程序,点击按钮,即可发送广播!
动态注册
动态注册就不需要我们在manifest.xml中注册广播,需要我们在主活动中修改代码:
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private MyBroadcastReceiver myBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBroadcastReceiver=new MyBroadcastReceiver();
IntentFilter intentFilter=new IntentFilter("com.lingzhuo.broadcast");
registerReceiver(myBroadcastReceiver,intentFilter);
Button button_send= (Button) findViewById(R.id.button_send);
button_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.lingzhuo.broadcast");
sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadcastReceiver);
}
}
注意:一定要重写onDestroy()方法,当该活动销毁时,为广播解除注册!
用广播简单实现闹钟的功能
为我们的布局中再添加两个按钮,一个显示闹钟广播,一个取消广播!
在主活动中修改我们的代码:
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private MyBroadcastReceiver myBroadcastReceiver;
private AlarmManager alarmManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBroadcastReceiver=new MyBroadcastReceiver();
alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
IntentFilter intentFilter=new IntentFilter("com.lingzhuo.broadcast");
registerReceiver(myBroadcastReceiver,intentFilter);
Button button_sendalarm= (Button) findViewById(R.id.button_sendalarm);
button_sendalarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.lingzhuo.broadcast");
PendingIntent pendingIntent=PendingIntent.getBroadcast(getApplicationContext(),0x23,intent,PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+2000,5000,pendingIntent);
}
});
Button button_cancelalarm= (Button) findViewById(R.id.button_cancelalarm);
button_cancelalarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.lingzhuo.broadcast");
PendingIntent pendingIntent=PendingIntent.getBroadcast(getApplicationContext(),PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(pendingIntent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadcastReceiver);
}
}
这样就简单实现了一个闹钟的功能,在点击显示闹钟广播按钮两秒后会发送广播,每隔5秒发送一次,点击取消广播后,则不再显示!
四大组件之Service
服务Service,是Android中实现程序后台运行的解决方案,它非常适合用于执行那些不需要和用户交互而且还要求长期执行的任务。服务的运行不依赖于任何用户界面,即使当程序被切换到后台,或者用户打开了另外一个程序,服务仍然能够保持正常运行。
基本用法
新建一个类MyService继承Service
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
/** * Created by Administrator on 2015/9/9. */
public class MyService extends Service{
private int count=0;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService","onCreate");
}
@Override
public int onStartCommand(final Intent intent,int flags,int startId) {
Log.d("MyService","onStartCommand");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService","onDestroy");
}
}
我们在布局中添加两个按钮,用来启动服务和停止服务
MainActivity.java
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button_start= (Button) findViewById(R.id.button_start);
button_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(getApplicationContext(),MyService.class);
startService(intent);//启动服务
}
});
Button button_stop= (Button) findViewById(R.id.button_stop);
button_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(getApplicationContext(),MyService.class);
stopService(intent);//停止服务
}
});
}
}
最后别忘了在manifest.xml中application标签下注册服务。
<service android:name=".MyService"></service>
运行结果:
点击启动服务按钮,打印”onCreate”和”onStartCommand”
点击停止服务按钮,打印”onDestroy”
注意:onCreate()方法只是在服务第一次创建时调用,onStartCommand()方法每次启动服务都会调用。
活动与服务的通信
这里在我们的布局中添加一个ProgressBar,和一个按钮,点击按钮模拟下载服务。启动服务发送广播,在活动中注册广播,接收广播设置进度条。
首先要修改MyServer类中onStartCommand()方法中的内容
@Override
public int onStartCommand(final Intent intent,int startId) {
new Thread(new Runnable() {
@Override
public void run() {
while (true){
if (count>100){
count=0;
}
Intent intent=new Intent("com.lingzhuo.download");
intent.putExtra("count",count);
sendBroadcast(intent);//启动线程,发送广播
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
}).start();
return super.onStartCommand(intent,flags,startId);
}
然后在主活动中用一个内部类新建一个广播,然后在活动中动态注册广播,然后点击按钮启动下载服务。
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
private ProgressBar progressBar;
private MyServiceBroadcast myServiceBroadcast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar= (ProgressBar) findViewById(R.id.progressbar);
IntentFilter filter=new IntentFilter("com.lingzhuo.download");
myServiceBroadcast=new MyServiceBroadcast();
registerReceiver(myServiceBroadcast,filter);//注册广播
Button button_download= (Button) findViewById(R.id.button_download);
button_download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(getApplicationContext(),MyService.class);
startService(intent);//启动下载服务
}
});
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myServiceBroadcast);
}
class MyServiceBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent) {
int count=intent.getIntExtra("count",0);
progressBar.setProgress(count);//接收广播,设置进度条
}
}
}
运行结果:当我们点击开始下载按钮后,进度条会隔200毫秒前进
IntentService
服务中的代码都是默认运行在主线程中的,如果直接在服务中去处理一些耗时的逻辑,就会出现ANR(Application Not Responding)的情况。所以我们就在每个服务的具体的方法里开启一个子线程来处理这些耗时的逻辑,但是服务一旦启动就会一直处于运行状态,除非我们调用stopService()方法或者stopSelf()方法才能让服务停止。
为了更简单地创建一个异步的,会自动停止的服务,就需要我们使用IntentService。
首先我们新建MyIntentService继承IntentService
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
/** * Created by Administrator on 2015/9/9. */
public class MyIntentService extends IntentService{
public MyIntentService() {
super("");//调用父类有参构造方法
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d("MyIntentService","线程ID:"+Thread.currentThread().getId());
}
@Override
public void onDestroy() {//服务停止
super.onDestroy();
Log.d("MyIntentService","执行到onDestroy");
}
}
注意:在创建类的时候必须提供一个无参的构造方法,并且必须在其内部调用父类的有参构造方法。
然后我们在布局中添加一个按钮,用于点击启动IntentService,修改我们主活动中的代码
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button_startIntentService= (Button) findViewById(R.id.button_intentservice);
button_startIntentService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("MainActivity","线程ID:"+Thread.currentThread().getId());
Intent intent=new Intent(getApplicationContext(),MyIntentService.class);
startService(intent);
}
});
}
最后也不要忘了注册服务!
<service android:name=".MyIntentService"></service>
运行结果:点击按钮
可以看出MainActivity和MyIntentService所在的线程ID不一样,而且执行到了onDestroy()方法,说明MyIntentService在运行完毕后确实自动停止了!