android kotlin学习

android 四大组件
参考教程

Activity: 负责用户界面展示和交互,学习Activity就要学习Fragment,且必须要和Activity一起使用,常用于模块开发, 一个APP有多个Activity

Service服务: 不需要交互,负责后台任务,如播放音乐,socket长连接

BroadcastReceiver广播接收者: 负责页面间通信,系统和APP通信,APP间通信,如网络变化监听

ContentProvier 内容提供者: 负责数据存取,常用于APP进程数据共享, 跨进程数据存取,如读取相册联系人

1.1 Activity生命周期

7个方法:
onCreate() 第一次创建时调用, 用于初始化操作
OnStart() 不可见变可见时调用,还不可以交互
onResume() 已经启动完成,可以交互
onPause() 系统准备去启动另一个Activity时调用, 可以释放系统资源,停止动画,不宜做耗时操作
onStop() Activity不可见时回调,可以释放用户用不到的资源
onDestroy() Activity即将被销毁,需要主动释放所有资源
onRestart() Activity由停止变为运行状态前调用[先onStop,再onRestart]

1.2 组件注册
四大组件需要在AndroidManifest注册才能使用

<activityandroid:name=".MainActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />intent-filter>
activity>

android:name是对应Activity的类名称
android:label是Activity标题栏显示的内容. 现已不推荐使用
intent-filter 是意图过滤器. 常用语隐式跳转
action 是动作名称,是指intent要执行的动作
category 是过滤器的类别 一般情况下,每个 中都要显示指定一个默认的类别名称,即

1.3 Activity启动与参数传递
1 显示启动, 通过包名启动
携带参数启动新Activity

val intent = Intent(MainActivity.this,SecondActivity.class)
intent.putExtra("extra_data", "extra_data")
intent.putExtra("extra_int_data", 100)
startActivity(intent);

2 隐式启动
通过指定 action 和 category 的信息,让系统去分析这个 Intent,并找出合适的 Activity 去启动。

1.4 系统给我们提供的一些常见的Activtiy
如拨打电话,发送短信,打开浏览器, 多媒体播放,拍照, 选图剪切,进入无线设置

1.5 Activity四种启动模式
standard 默认值, 多实例模式, 每启动一次, 会创建一个Activity实例
启动周期:
onCreate() - onStart() - onResume()

singleTop 栈顶复用模式
栈顶有需要启动的目标Activity ?
直接启动【onPause() ->onNewIntent()->onResume()】 :
创建新实例 【onCreate()->onStart()->onResume()】

singleTask 栈内复用模式: 一个任务栈只能有一个实例
启动的Activity目标任务栈存在 ?
切换到Activity所在的任务栈:
启动Activity为根Activity创建目标任务栈,并切换到前面

singleInstance 单例模式
单例模式的“保护措施”是将其单独放到一个任务栈中

1.6 Intent FLag设定启动模式
可以在manifest中设置Activity的启动模式,也可以通过设置Intent的flag标识来设定Activity的启动模式。
Intent的flag标识 如:
FLAG_ACTIVITY_NEW_TASK: 启动Activity时,如果不存在Activity的实例,则会以此Activity为根Activity创建新的任务栈,如果存在的话则直接切换到对应的Activity实例,并回调onNewIntent()方法。相当于“singleTask”启动模式。

FLAG_ACTIVITY_SINGLE_TOP:相当于“singleTop”模式
FLAG_ACTIVITY_CLEAR_TOP:设置此标识的Activity在启动时,如果当前的任务栈内存在此Activity实例,则跳转到此实例,并清除掉在此实例上面的所有Activity实例,此时此Activity实例位于任务栈的栈顶

2 Fragment必知必会
2.1 Fragment出现的背景

初衷: Fragment是Android3.0后引入的一个新的API,他出现的初衷是为了适应大屏幕的平板电脑, 当然现在他仍然是平板APP UI设计的宠儿。

现状:现在我们普通APP开发也经常会用到Fragment,如果一个界面很复杂,我们把所有代码都写在一个Activity里面,页面布局都写在同一个xml文件中。过不了多久我们就会发现写不动了,一个Activity上万行代码,非常难以维护,后续如果有变动,更是无从下手。而使用Fragment 我们可以把页面结构划分成几块,每块使用一个Fragment来管理。这样我们可以更加方便的在运行过程中动态地更新Activity中的用户界面,日后迭代更新、维护也是更加方便。

注意: Fragment并不能单独使用,他需要嵌套在Activity 中使用

2.2 生命周期
①Activity加载Fragment的时候,依次调用下面的方法: onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume

②当我们启动一个新的页面, 此时Fragment所在的Activity不可见,会执行 onPause

③当新页面返回后,当前Activity和Fragment又可见了,会再次执行onStart和 onResume

⑥退出了Activity的话,那么Fragment将会被完全结束, Fragment会进入销毁状态 onPause -> onStop -> onDestoryView -> onDestory -> onDetach

2.3 Fragment的动态添加与数据传递
2.3.1 动态添加Fragment

// 定义StudyFragment需要继承自Fragment,并且绑定布局文件
class StudyFragment : Fragment(R.layout.fragment_study,container) {}// 在Activity中使用supportFragmentManager管理Fragment,添加到界面上
class MainActivity:AppCompactActivity{override fun onCreate(savedInstanceState: Bundle?) {val studyFragment =  StudyFragment();val bundle = Bundle()bundle.putInt()studyFragment.argments= BundlesupportFragmentManager.beginTransaction().add(R.id.container, studyFragment).commitAllowingStateLoss()}
}

2.3.2 Fragment常见的操作

val fragment = StudyFragment()
val ft = supportFragmentManager.beginTransaction()if(!fragment.isAdded()){ft.add(R.id.container,fragment) //把fragment添加到事务中,当且仅当该fragment未被添加过
}
ft.show(fragment) //显示出fragment的视图
ft.hide(fragment) //隐藏fragment,使得它的视图不可见
ft.remove(fragment)//移除fragment
ft.replace(R.id.container,fragment)//替换fragment,之前添加过的fragment都会被暂时移除,把当前这个fragment添加到事务中ft.commitAllowingStateLoss()提交事务,执行对fragment的add、replace、show、hide操作

2.3.3给Fragment传递数据

class MainActivity:AppcompactActivity{override fun onCreate(savedInstanceState: Bundle?){val studyFragment =  StudyFragment();// 创建bundle对象、并填充数据赋值给fragment的argments字段val bundle = Bundle()bundle.putInt("key_int",100)bundle.putString("key_string","key_string_value")studyFragment.argments= BundlesupportFragmentManager.beginTransaction().add(R.id.container,    studyFragment).commitAllowingStateLoss()}
}
class StudyFragment : Fragment(R.layout.fragment_study) {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {// 取出参数val intArgument = argments?.getInt("key_int")val stringArgument = argments?.getInt("key_string") }
}

2.4 实践:设计并实现底部导航栏页面结构

2.4.1 Activity 布局
2.4.2 监听选中事件
2.4.3 导航栏切换动态切换显示的fragment

3 Service 必会必知

Service服务是Android四大组件之一,是Android提供的一种的 不需要和用户交互,且需要长期运行任务的解决方案。

Service启动后默认是运行在主线程中,在执行具体耗时任务过程中要手动开启子线程,应用程序进程被杀死,所有依赖该进程的Service服务也会停止运行。

3.1启动方式与生命周期:

android 四大组件
参考教程

Activity: 负责用户界面展示和交互,学习Activity就要学习Fragment,且必须要和Activity一起使用,常用于模块开发, 一个APP有多个Activity

Service服务: 不需要交互,负责后台任务,如播放音乐,socket长连接

BroadcastReceiver广播接收者: 负责页面间通信,系统和APP通信,APP间通信,如网络变化监听

ContentProvier 内容提供者: 负责数据存取,常用于APP进程数据共享, 跨进程数据存取,如读取相册联系人

1.1 Activity生命周期

7个方法:
onCreate() 第一次创建时调用, 用于初始化操作
OnStart() 不可见变可见时调用,还不可以交互
onResume() 已经启动完成,可以交互
onPause() 系统准备去启动另一个Activity时调用, 可以释放系统资源,停止动画,不宜做耗时操作
onStop() Activity不可见时回调,可以释放用户用不到的资源
onDestroy() Activity即将被销毁,需要主动释放所有资源
onRestart() Activity由停止变为运行状态前调用[先onStop,再onRestart]

1.2 组件注册
四大组件需要在AndroidManifest注册才能使用

<activityandroid:name=".MainActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />intent-filter>
activity>

android:name是对应Activity的类名称
android:label是Activity标题栏显示的内容. 现已不推荐使用
是意图过滤器. 常用语隐式跳转
是动作名称,是指intent要执行的动作
是过滤器的类别 一般情况下,每个 中都要显示指定一个默认的类别名称,即

1.3 Activity启动与参数传递
1 显示启动, 通过包名启动
携带参数启动新Activity

val intent = Intent(MainActivity.this,SecondActivity.class)
intent.putExtra("extra_data", "extra_data")
intent.putExtra("extra_int_data", 100)
startActivity(intent);

2 隐式启动
通过指定 action 和 category 的信息,让系统去分析这个 Intent,并找出合适的 Activity 去启动。

1.4 系统给我们提供的一些常见的Activtiy
如拨打电话,发送短信,打开浏览器, 多媒体播放,拍照, 选图剪切,进入无线设置

1.5 Activity四种启动模式
standard 默认值, 多实例模式, 每启动一次, 会创建一个Activity实例
启动周期:
onCreate() - onStart() - onResume()

singleTop 栈顶复用模式
栈顶有需要启动的目标Activity ?
直接启动【onPause() ->onNewIntent()->onResume()】 :
创建新实例 【onCreate()->onStart()->onResume()】

singleTask 栈内复用模式: 一个任务栈只能有一个实例
启动的Activity目标任务栈存在 ?
切换到Activity所在的任务栈:
启动Activity为根Activity创建目标任务栈,并切换到前面

singleInstance 单例模式
单例模式的“保护措施”是将其单独放到一个任务栈中

1.6 Intent FLag设定启动模式
可以在manifest中设置Activity的启动模式,也可以通过设置Intent的flag标识来设定Activity的启动模式。
Intent的flag标识 如:
FLAG_ACTIVITY_NEW_TASK: 启动Activity时,如果不存在Activity的实例,则会以此Activity为根Activity创建新的任务栈,如果存在的话则直接切换到对应的Activity实例,并回调onNewIntent()方法。相当于“singleTask”启动模式。

FLAG_ACTIVITY_SINGLE_TOP:相当于“singleTop”模式
FLAG_ACTIVITY_CLEAR_TOP:设置此标识的Activity在启动时,如果当前的任务栈内存在此Activity实例,则跳转到此实例,并清除掉在此实例上面的所有Activity实例,此时此Activity实例位于任务栈的栈顶

2 Fragment必知必会
2.1 Fragment出现的背景

初衷: Fragment是Android3.0后引入的一个新的API,他出现的初衷是为了适应大屏幕的平板电脑, 当然现在他仍然是平板APP UI设计的宠儿。

现状:现在我们普通APP开发也经常会用到Fragment,如果一个界面很复杂,我们把所有代码都写在一个Activity里面,页面布局都写在同一个xml文件中。过不了多久我们就会发现写不动了,一个Activity上万行代码,非常难以维护,后续如果有变动,更是无从下手。而使用Fragment 我们可以把页面结构划分成几块,每块使用一个Fragment来管理。这样我们可以更加方便的在运行过程中动态地更新Activity中的用户界面,日后迭代更新、维护也是更加方便。

注意: Fragment并不能单独使用,他需要嵌套在Activity 中使用

2.2 生命周期
①Activity加载Fragment的时候,依次调用下面的方法: onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume

②当我们启动一个新的页面, 此时Fragment所在的Activity不可见,会执行 onPause

③当新页面返回后,当前Activity和Fragment又可见了,会再次执行onStart和 onResume

⑥退出了Activity的话,那么Fragment将会被完全结束, Fragment会进入销毁状态 onPause -> onStop -> onDestoryView -> onDestory -> onDetach

2.3 Fragment的动态添加与数据传递
2.3.1 动态添加Fragment

// 定义StudyFragment需要继承自Fragment,并且绑定布局文件
class StudyFragment : Fragment(R.layout.fragment_study,container) {}// 在Activity中使用supportFragmentManager管理Fragment,添加到界面上
class MainActivity:AppCompactActivity{override fun onCreate(savedInstanceState: Bundle?) {val studyFragment =  StudyFragment();val bundle = Bundle()bundle.putInt()studyFragment.argments= BundlesupportFragmentManager.beginTransaction().add(R.id.container, studyFragment).commitAllowingStateLoss()}
}

2.3.2 Fragment常见的操作

val fragment = StudyFragment()
val ft = supportFragmentManager.beginTransaction()if(!fragment.isAdded()){ft.add(R.id.container,fragment) //把fragment添加到事务中,当且仅当该fragment未被添加过
}
ft.show(fragment) //显示出fragment的视图
ft.hide(fragment) //隐藏fragment,使得它的视图不可见
ft.remove(fragment)//移除fragment
ft.replace(R.id.container,fragment)//替换fragment,之前添加过的fragment都会被暂时移除,把当前这个fragment添加到事务中ft.commitAllowingStateLoss()提交事务,执行对fragment的add、replace、show、hide操作

2.3.3给Fragment传递数据

class MainActivity:AppcompactActivity{override fun onCreate(savedInstanceState: Bundle?){val studyFragment =  StudyFragment();// 创建bundle对象、并填充数据赋值给fragment的argments字段val bundle = Bundle()bundle.putInt("key_int",100)bundle.putString("key_string","key_string_value")studyFragment.argments= BundlesupportFragmentManager.beginTransaction().add(R.id.container,    studyFragment).commitAllowingStateLoss()}
}
class StudyFragment : Fragment(R.layout.fragment_study) {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {// 取出参数val intArgument = argments?.getInt("key_int")val stringArgument = argments?.getInt("key_string") }
}

2.4 实践:设计并实现底部导航栏页面结构

2.4.1 Activity 布局
2.4.2 监听选中事件
2.4.3 导航栏切换动态切换显示的fragment

3 Service 必会必知

Service服务是Android四大组件之一,是Android提供的一种的 不需要和用户交互,且需要长期运行任务的解决方案。

Service启动后默认是运行在主线程中,在执行具体耗时任务过程中要手动开启子线程,应用程序进程被杀死,所有依赖该进程的Service服务也会停止运行。

3.1启动方式与生命周期:

[外链图片转存中…(img-laW4nE7d-166781128261.272)]
android 四大组件
参考教程

Activity: 负责用户界面展示和交互,学习Activity就要学习Fragment,且必须要和Activity一起使用,常用于模块开发, 一个APP有多个Activity

Service服务: 不需要交互,负责后台任务,如播放音乐,socket长连接

BroadcastReceiver广播接收者: 负责页面间通信,系统和APP通信,APP间通信,如网络变化监听

ContentProvier 内容提供者: 负责数据存取,常用于APP进程数据共享, 跨进程数据存取,如读取相册联系人

1.1 Activity生命周期

7个方法:
onCreate() 第一次创建时调用, 用于初始化操作
OnStart() 不可见变可见时调用,还不可以交互
onResume() 已经启动完成,可以交互
onPause() 系统准备去启动另一个Activity时调用, 可以释放系统资源,停止动画,不宜做耗时操作
onStop() Activity不可见时回调,可以释放用户用不到的资源
onDestroy() Activity即将被销毁,需要主动释放所有资源
onRestart() Activity由停止变为运行状态前调用[先onStop,再onRestart]

1.2 组件注册
四大组件需要在AndroidManifest注册才能使用

<activityandroid:name=".MainActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />intent-filter>
activity>

android:name是对应Activity的类名称
android:label是Activity标题栏显示的内容. 现已不推荐使用
是意图过滤器. 常用语隐式跳转
是动作名称,是指intent要执行的动作
是过滤器的类别 一般情况下,每个 中都要显示指定一个默认的类别名称,即

1.3 Activity启动与参数传递
1 显示启动, 通过包名启动
携带参数启动新Activity

val intent = Intent(MainActivity.this,SecondActivity.class)
intent.putExtra("extra_data", "extra_data")
intent.putExtra("extra_int_data", 100)
startActivity(intent);

2 隐式启动
通过指定 action 和 category 的信息,让系统去分析这个 Intent,并找出合适的 Activity 去启动。

1.4 系统给我们提供的一些常见的Activtiy
如拨打电话,发送短信,打开浏览器, 多媒体播放,拍照, 选图剪切,进入无线设置

1.5 Activity四种启动模式
standard 默认值, 多实例模式, 每启动一次, 会创建一个Activity实例
启动周期:
onCreate() - onStart() - onResume()

singleTop 栈顶复用模式
栈顶有需要启动的目标Activity ?
直接启动【onPause() ->onNewIntent()->onResume()】 :
创建新实例 【onCreate()->onStart()->onResume()】

singleTask 栈内复用模式: 一个任务栈只能有一个实例
启动的Activity目标任务栈存在 ?
切换到Activity所在的任务栈:
启动Activity为根Activity创建目标任务栈,并切换到前面

singleInstance 单例模式
单例模式的“保护措施”是将其单独放到一个任务栈中

1.6 Intent FLag设定启动模式
可以在manifest中设置Activity的启动模式,也可以通过设置Intent的flag标识来设定Activity的启动模式。
Intent的flag标识 如:
FLAG_ACTIVITY_NEW_TASK: 启动Activity时,如果不存在Activity的实例,则会以此Activity为根Activity创建新的任务栈,如果存在的话则直接切换到对应的Activity实例,并回调onNewIntent()方法。相当于“singleTask”启动模式。

FLAG_ACTIVITY_SINGLE_TOP:相当于“singleTop”模式
FLAG_ACTIVITY_CLEAR_TOP:设置此标识的Activity在启动时,如果当前的任务栈内存在此Activity实例,则跳转到此实例,并清除掉在此实例上面的所有Activity实例,此时此Activity实例位于任务栈的栈顶

2 Fragment必知必会
2.1 Fragment出现的背景

初衷: Fragment是Android3.0后引入的一个新的API,他出现的初衷是为了适应大屏幕的平板电脑, 当然现在他仍然是平板APP UI设计的宠儿。

现状:现在我们普通APP开发也经常会用到Fragment,如果一个界面很复杂,我们把所有代码都写在一个Activity里面,页面布局都写在同一个xml文件中。过不了多久我们就会发现写不动了,一个Activity上万行代码,非常难以维护,后续如果有变动,更是无从下手。而使用Fragment 我们可以把页面结构划分成几块,每块使用一个Fragment来管理。这样我们可以更加方便的在运行过程中动态地更新Activity中的用户界面,日后迭代更新、维护也是更加方便。

注意: Fragment并不能单独使用,他需要嵌套在Activity 中使用

2.2 生命周期
①Activity加载Fragment的时候,依次调用下面的方法: onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume

②当我们启动一个新的页面, 此时Fragment所在的Activity不可见,会执行 onPause

③当新页面返回后,当前Activity和Fragment又可见了,会再次执行onStart和 onResume

⑥退出了Activity的话,那么Fragment将会被完全结束, Fragment会进入销毁状态 onPause -> onStop -> onDestoryView -> onDestory -> onDetach

2.3 Fragment的动态添加与数据传递
2.3.1 动态添加Fragment

// 定义StudyFragment需要继承自Fragment,并且绑定布局文件
class StudyFragment : Fragment(R.layout.fragment_study,container) {}// 在Activity中使用supportFragmentManager管理Fragment,添加到界面上
class MainActivity:AppCompactActivity{override fun onCreate(savedInstanceState: Bundle?) {val studyFragment =  StudyFragment();val bundle = Bundle()bundle.putInt()studyFragment.argments= BundlesupportFragmentManager.beginTransaction().add(R.id.container, studyFragment).commitAllowingStateLoss()}
}

2.3.2 Fragment常见的操作

val fragment = StudyFragment()
val ft = supportFragmentManager.beginTransaction()if(!fragment.isAdded()){ft.add(R.id.container,fragment) //把fragment添加到事务中,当且仅当该fragment未被添加过
}
ft.show(fragment) //显示出fragment的视图
ft.hide(fragment) //隐藏fragment,使得它的视图不可见
ft.remove(fragment)//移除fragment
ft.replace(R.id.container,fragment)//替换fragment,之前添加过的fragment都会被暂时移除,把当前这个fragment添加到事务中ft.commitAllowingStateLoss()提交事务,执行对fragment的add、replace、show、hide操作

2.3.3给Fragment传递数据

class MainActivity:AppcompactActivity{override fun onCreate(savedInstanceState: Bundle?){val studyFragment =  StudyFragment();// 创建bundle对象、并填充数据赋值给fragment的argments字段val bundle = Bundle()bundle.putInt("key_int",100)bundle.putString("key_string","key_string_value")studyFragment.argments= BundlesupportFragmentManager.beginTransaction().add(R.id.container,    studyFragment).commitAllowingStateLoss()}
}
class StudyFragment : Fragment(R.layout.fragment_study) {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {// 取出参数val intArgument = argments?.getInt("key_int")val stringArgument = argments?.getInt("key_string") }
}

2.4 实践:设计并实现底部导航栏页面结构

2.4.1 Activity 布局
2.4.2 监听选中事件
2.4.3 导航栏切换动态切换显示的fragment

3 Service 必会必知

Service服务是Android四大组件之一,是Android提供的一种的 不需要和用户交互,且需要长期运行任务的解决方案。

Service启动后默认是运行在主线程中,在执行具体耗时任务过程中要手动开启子线程,应用程序进程被杀死,所有依赖该进程的Service服务也会停止运行。

3.1启动方式与生命周期:

在这里插入图片描述

3.1.1 普通启动 startService

1 Service实例,依次调用onCreate()和onStartCommand()方法,此时Service 进入运行状态

2 再次调用StartService启动Service,将不会再创建新的Service对象, 系统会直接复用前面创建的Service对象,调用它的onStartCommand()方法!

3 这样的Service与它的调用者无必然的联系,就是说当调用者结束了自己的生命周期, 但是只要不调用stopService,那么Service还是会继续运行的!

4 无论启动了多少次Service,只需调用一次StopService即可停掉Service

3.1.2 定义Service服务

class TestService : Service() {private val TAG = "TestService1 "// 必须实现的方法override fun onBind(intent: Intent?): IBinder? {Log.e(TAG, "onBind方法被调用")return null}//Service被创建时调用  override fun onCreate() {Log.e(TAG, "onCreate方法被调用!")super.onCreate()}//Service被启动时调用  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {Log.e(TAG, "onStartCommand方法被调用!")return super.onStartCommand(intent, flags, startId)}//Service被关闭之前回调  override fun onDestroy() {Log.e(TAG, "onDestory方法被调用!")super.onDestroy()}
}
  • AndroidManifest.xml完成Service注册
<application><service android:name=".components.TestService1">        service>
application>
  • 在Avtivity中StartService启动服务
val intent = Intent(this.TestService::class.java);
startService(intent)

onBind()方法并没有被调用,另外多次点击启动Service,只会重复地调用onStartCommand 方法!无论我们启动多少次Service,一个stopService就会停止Service!

3.1.2 绑定启动 bindService

①当首次使用bindService()启动一个Service时,系统会实例化一个Service实例,并调用其onCreate()和onBind()方法,然后调用者就可以通过返回的IBinder对象和Service进行交互了,此后如果我们再次使用bindService绑定Service,系统不会创建新的Sevice实例,也不会再调用onBind()方法,只会直接把IBinder对象返回给调用方

②如果我们解除与服务的绑定,只需调用unbindService(),此时onUnbind和onDestory方法将会被调用

③bindService启动的Service服务是与调用者(Activity)相互关联的,可以理解为 “一条绳子上的蚂蚱”,要死一起死,在bindService后,一旦调用者(Activity)销毁,那么Service也立即终止

  • 定义Service服务
  • AndroidManifest.xml中注册服务
  • 在Activity中bindService启动服务
  • 日志输出与结果分析

使用BindService绑定Service,依次调用onCreate(),onBind()方法, 我们可以在onBind()方法中返回自定义的IBinder对象;再接着调用的是 ServiceConnection的onServiceConnected()方法该方法中可以获得 IBinder对象,从而进行相关操作;当Service解除绑定后会自动调用 onUnbind和onDestroyed方法,当然绑定多客户端情况需要解除所有 的绑定才会调用onDestoryed方法进行销毁哦

3.2 Android 8.0及以上不允许后台启动Service服务

8.0系统杀服务杀的很频繁
为了保活,我们使用了俩Service互保的方式

AndroidManifest.xml声明权限

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

服务兼容写法

if (Build.VERSION.SDK_INT >= 26) {context.startForegroundService(intent);
} else {// Pre-O behavior.context.startService(intent);
}class TestService:Service(){// 发送一个前台通知override fun onCreate(){val notification: Notification =Notification.Builder(applicationContext, "channel_id").build()startForeground( 1, notification)}
}

4 BroadcastReceiver广播接收者

BroadcastReceiver广播接收者Android四大组件之一,是Android系统提供的一种通讯方式。
类似于村口大喇叭
涉及到两个角色,一个是广播发送者,一个是广播接收者。

应用场景:
Android不同组件间的通信(含 :应用内 / 不同应用之间)
多线程通信
与 Android 系统在特定情况下的通信

4.1 两种广播类型

标准广播:发出广播后,该广播事件的接收者,几乎会在同一时刻收到通知,都可以响应或不响应该事件

有序广播:发出广播后,同一时刻,只有一个广播接收者能收到、一个接收者处理完后之后,可以选择继续向下传递给其它接收者,也可以拦截掉广播。[不常用、不推荐使用了]

4.2 监听系统网络连接变化

4.2.1 定义一个接受者:

class TestBroadcastReceiver : BroadcastReceiver() {override fun onReceive(context: Conext>, intent: Intent?) {if (intent?.action?.equals(ConnectivityManager.CONNECTIVITY_ACTION) == true) {val connectivityManager: ConnectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerval info = connectivityManager.activeNetworkInfoif (info != null && info.isAvailable) {val typeName = info.typeNameToast.makeText(context, "当前网络名称:${typeName}", Toast.LENGTH_LONG).show()} else {Toast.makeText(context, "当前无网络连接", Toast.LENGTH_LONG).show()}}}
}

4.2.2 运行时动态注册广播接收事件

class TestBroadcastRecevierActivity :AppCompatActivity(){private lateinit var myReceiver: TestBroadcastReceiveroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)myReceiver = TestBroadcastReceiver()// 创建广播过滤器,指定只接收android.net.conn.CONNECTIVITY_CHANGE的广播事件val intentFilter = IntentFilter() intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED)registerReceiver(myReceiver, intentFilter)}override fun onDestroy() {super.onDestroy()unregisterReceiver(myReceiver)   // 必须要在onDestroy时反注册,否则会内存泄漏}
}

不要在广播后进行耗时操作,因为广播不允许开辟线程

onReceiver 运行超过10秒会报错(ANR)

4.2.3 静态注册广播

从android 8.0(API26)开始,对清单文件中静态注册广播接收者增加了限制,建议大家不要在清单文件中静态注册广播接收者。

AndroidManifest.xml 注册广播

<receiver android:name=".components.TestBroadcastReceiver"><intent-filter ><action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>intent-filter>
receiver>

4.2.4 解决静态注册广播接收者收不到事件的问题

4.3 发送自定义事件广播

4.3.1 全局发送广播

全局发送广播,如果别人家App也注册了该事件监听,也能收到,比较不合理。

sendBroadcast(new Intent(“com.example.firstapp.component.TEST_BROADCAST_RECEVIER”));

4.3.2 应用内发送广播

1 局部广播,发送和接受同属于一个APP
2 优势: 安全, 高效

使用LocalBroadcastManager 注册应用内广播

LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, itFilter)

使用LocalBoardcastManager 来发送应用内广播

LocalBroadcastManager.getInstance(this).sendBroadcast(intent)

4.3.2 系统广播(system boardcast)

只要涉及到手机基本操作: (网络变化, 拍照,开机等), 会发出相应广播

每个广播有特定的intent-filter


系统操作action
监听网络变化android.net.conn.CONNECTIVITY_CHANGE
关闭或打开飞行模式Intent.ACTION_AIRPLANE_MODE_CHANGED
充电时或电量发生变化Intent.ACTION_BATTERY_CHANGED
电池电量低Intent.ACTION_BATTERY_LOW
电池电量充足(即从电量低变化到饱满时会发出广播Intent.ACTION_BATTERY_OKAY
系统启动完成后(仅广播一次)Intent.ACTION_BOOT_COMPLETED
按下照相时的拍照按键(硬件按键)时Intent.ACTION_CAMERA_BUTTON
屏幕锁屏Intent.ACTION_CLOSE_SYSTEM_DIALOGS
设备当前设置被改变时(界面语言、设备方向等)Intent.ACTION_CONFIGURATION_CHANGED
插入耳机时Intent.ACTION_HEADSET_PLUG
未正确移除SD卡但已取出来时(正确移除方法:设置–SD卡和设备内存–卸载SD卡)Intent.ACTION_MEDIA_BAD_REMOVAL
插入外部储存装置(如SD卡)Intent.ACTION_MEDIA_CHECKING
成功安装APKIntent.ACTION_PACKAGE_ADDED
成功删除APKIntent.ACTION_PACKAGE_REMOVED
重启设备Intent.ACTION_REBOOT
屏幕被关闭Intent.ACTION_SCREEN_OFF
屏幕被打开Intent.ACTION_SCREEN_ON
关闭系统时Intent.ACTION_SHUTDOWN
重启设备Intent.ACTION_REBOOT

5.ContentProvider(内容提供者)

应用:

  1. 我们想在自己的应用中访问别的程序, 或者说一些ContentProvider暴露给我们一些数据,如手机联系人,短信,相册,对数据读写
  2. 我们自己的应用, 想暴露出去,避免私有数据泄露

5.1 权限申请

6.0开始,凡是涉及隐私的权限(短信, 联系人,相片,录音等)运行时申请,不授权无法工作

5.1.1 在Androidmanifest.xml 声明读取短信权限

<uses-permission android:name="android.permission.READ_CONTACTS"/>

运行时动态申请权限,请求用户授权

  • ActivityCompat.checkSelfPremission(): 检查权限是否已授权,如果没有则需要向用户申请
  • ActivityCompat.requestPremissions(): 发起权限申请,弹出对话框
  • ActivityCompat.shouldShowRequsetPremissionRationale(): 检查用户是否永久拒绝,如果是,需要自己弹窗引导用户开启
  • onRequestPermissionRequset: 处理授权结果

example:

class PermissionActivity:AppCompatActivity() {}

通信录读取联系人
content://com.android.contacts/data/phones

display_name: 用户名
Data1:手机号

通信录插入联系人

  • AndroidManifest.xml声明权限
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>

content://com.android.contacts/data/data 插入联系人的表的名字
content://com.android.contacts/data/raw_contacts 插入联系人的原始表的名字

更新联系人信息
删除联系人

  • 根据姓名删除联系人
  • 根据手机号删除联系人

读取收件箱所有短信

字段 说明
address 发件人地址,即手机号,如+8613811810000
person 发件人地址,即手机号,如+8613811810000
date 日期,long型,如1256539465022,可以对日期显示格式进行设置
protocol 协议0 :SMS_RPOTO短信,1:MMS_PROTO彩信
read 是否阅读0:未读,1:已读
type 短信类型1: 接收到的短信,2:发出的短信
body 短信具体内容

3.1 普通启动 startService

1 Service实例,依次调用onCreate()和onStartCommand()方法,此时Service 进入运行状态

2 再次调用StartService启动Service,将不会再创建新的Service对象, 系统会直接复用前面创建的Service对象,调用它的onStartCommand()方法!

3 这样的Service与它的调用者无必然的联系,就是说当调用者结束了自己的生命周期, 但是只要不调用stopService,那么Service还是会继续运行的!

4 无论启动了多少次Service,只需调用一次StopService即可停掉Service

.1.2 定义Service服务

class TestService : Service() {private val TAG = "TestService1 "// 必须实现的方法override fun onBind(intent: Intent?): IBinder? {Log.e(TAG, "onBind方法被调用")return null}//Service被创建时调用  override fun onCreate() {Log.e(TAG, "onCreate方法被调用!")super.onCreate()}//Service被启动时调用  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int6: Int {Log.e1TAG, "onStartCommand方法被调用!")return super8onStartCommand(intent, flags, startId)}./Service被关闭之前回调  override fun onDe0troy() {Log.e(TAG, "onDestory方法被调用!")super.onDestroy()}
}
  • AndroidManifest.xml完成S6/s8rviceeg)]

3.1738)(./service注册

<application><service android:name=".components.TestService1">        service>
application>
  • 在Avtivity中StartService启动服务
val intent = Intent(this.TestService::class.java);
startService(intent)

onBind()方法并没有被调用,另外多次点击启动Service,只会重复地调用onStartCommand 方法!无论我们启动多少次Service,一个stopService就会停止Service!

3.1.2 绑定启动 bindService

①当首次使用bindService()启动一个Service时,系统会实例化一个Service实例,并调用其onCreate()和onBind()方法,然后调用者就可以通过返回的IBinder对象和Service进行交互了,此后如果我们再次使用bindService绑定Service,系统不会创建新的Sevice实例,也不会再调用onBind()方法,只会直接把IBinder对象返回给调用方

②如果我们解除与服务的绑定,只需调用unbindService(),此时onUnbind和onDestory方法将会被调用

③bindService启动的Service服务是与调用者(Activity)相互关联的,可以理解为 “一条绳子上的蚂蚱”,要死一起死,在bindService后,一旦调用者(Activity)销毁,那么Service也立即终止

  • 定义Service服务
  • AndroidManifest.xml中注册服务
  • 在Activity中bindService启动服务
  • 日志输出与结果分析

使用BindService绑定Service,依次调用onCreate(),onBind()方法, 我们可以在onBind()方法中返回自定义的IBinder对象;再接着调用的是 ServiceConnection的onServiceConnected()方法该方法中可以获得 IBinder对象,从而进行相关操作;当Service解除绑定后会自动调用 onUnbind和onDestroyed方法,当然绑定多客户端情况需要解除所有 的绑定才会调用onDestoryed方法进行销毁哦

3.2 Android 8.0及以上不允许后台启动Service服务

8.0系统杀服务杀的很频繁
为了保活,我们使用了俩Service互保的方式

AndroidManifest.xml声明权限

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

服务兼容写法

if (Build.VERSION.SDK_INT >= 26) {context.startForegroundService(intent);
} else {// Pre-O behavior.context.startService(intent);
}class TestService:Service(){// 发送一个前台通知override fun onCreate(){val notification: Notification =Notification.Builder(applicationContext, "channel_id").build()startForeground( 1, notification)}
}

4 BroadcastReceiver广播接收者

BroadcastReceiver广播接收者Android四大组件之一,是Android系统提供的一种通讯方式。
类似于村口大喇叭
涉及到两个角色,一个是广播发送者,一个是广播接收者。

应用场景:
Android不同组件间的通信(含 :应用内 / 不同应用之间)
多线程通信
与 Android 系统在特定情况下的通信

4.1 两种广播类型

标准广播:发出广播后,该广播事件的接收者,几乎会在同一时刻收到通知,都可以响应或不响应该事件

有序广播:发出广播后,同一时刻,只有一个广播接收者能收到、一个接收者处理完后之后,可以选择继续向下传递给其它接收者,也可以拦截掉广播。[不常用、不推荐使用了]

4.2 监听系统网络连接变化

4.2.1 定义一个接受者:

class TestBroadcastReceiver : BroadcastReceiver() {override fun onReceive(context: Conext>, intent: Intent?) {if (intent?.action?.equals(ConnectivityManager.CONNECTIVITY_ACTION) == true) {val connectivityManager: ConnectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerval info = connectivityManager.activeNetworkInfoif (info != null && info.isAvailable) {val typeName = info.typeNameToast.makeText(context, "当前网络名称:${typeName}", Toast.LENGTH_LONG).show()} else {Toast.makeText(context, "当前无网络连接", Toast.LENGTH_LONG).show()}}}
}

4.2.2 运行时动态注册广播接收事件

class TestBroadcastRecevierActivity :AppCompatActivity(){private lateinit var myReceiver: TestBroadcastReceiveroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)myReceiver = TestBroadcastReceiver()// 创建广播过滤器,指定只接收android.net.conn.CONNECTIVITY_CHANGE的广播事件val intentFilter = IntentFilter() intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED)registerReceiver(myReceiver, intentFilter)}override fun onDestroy() {super.onDestroy()unregisterReceiver(myReceiver)   // 必须要在onDestroy时反注册,否则会内存泄漏}
}

不要在广播后进行耗时操作,因为广播不允许开辟线程

onReceiver 运行超过10秒会报错(ANR)

4.2.3 静态注册广播

从android 8.0(API26)开始,对清单文件中静态注册广播接收者增加了限制,建议大家不要在清单文件中静态注册广播接收者。

AndroidManifest.xml 注册广播

<receiver android:name=".components.TestBroadcastReceiver"><intent-filter ><action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>intent-filter>
receiver>

4.2.4 解决静态注册广播接收者收不到事件的问题

4.3 发送自定义事件广播

4.3.1 全局发送广播

全局发送广播,如果别人家App也注册了该事件监听,也能收到,比较不合理。

sendBroadcast(new Intent(“com.example.firstapp.component.TEST_BROADCAST_RECEVIER”));

4.3.2 应用内发送广播

1 局部广播,发送和接受同属于一个APP
2 优势: 安全, 高效

使用LocalBroadcastManager 注册应用内广播

LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, itFilter)

使用LocalBoardcastManager 来发送应用内广播

LocalBroadcastManager.getInstance(this).sendBroadcast(intent)

4.3.2 系统广播(system boardcast)

只要涉及到手机基本操作: (网络变化, 拍照,开机等), 会发出相应广播

每个广播有特定的intent-filter


系统操作action
监听网络变化android.net.conn.CONNECTIVITY_CHANGE
关闭或打开飞行模式Intent.ACTION_AIRPLANE_MODE_CHANGED
充电时或电量发生变化Intent.ACTION_BATTERY_CHANGED
电池电量低Intent.ACTION_BATTERY_LOW
电池电量充足(即从电量低变化到饱满时会发出广播Intent.ACTION_BATTERY_OKAY
系统启动完成后(仅广播一次)Intent.ACTION_BOOT_COMPLETED
按下照相时的拍照按键(硬件按键)时Intent.ACTION_CAMERA_BUTTON
屏幕锁屏Intent.ACTION_CLOSE_SYSTEM_DIALOGS
设备当前设置被改变时(界面语言、设备方向等)Intent.ACTION_CONFIGURATION_CHANGED
插入耳机时Intent.ACTION_HEADSET_PLUG
未正确移除SD卡但已取出来时(正确移除方法:设置–SD卡和设备内存–卸载SD卡)Intent.ACTION_MEDIA_BAD_REMOVAL
插入外部储存装置(如SD卡)Intent.ACTION_MEDIA_CHECKING
成功安装APKIntent.ACTION_PACKAGE_ADDED
成功删除APKIntent.ACTION_PACKAGE_REMOVED
重启设备Intent.ACTION_REBOOT
屏幕被关闭Intent.ACTION_SCREEN_OFF
屏幕被打开Intent.ACTION_SCREEN_ON
关闭系统时Intent.ACTION_SHUTDOWN
重启设备Intent.ACTION_REBOOT

5.ContentProvider(内容提供者)

应用:

  1. 我们想在自己的应用中访问别的程序, 或者说一些ContentProvider暴露给我们一些数据,如手机联系人,短信,相册,对数据读写
  2. 我们自己的应用, 想暴露出去,避免私有数据泄露

5.1 权限申请

6.0开始,凡是涉及隐私的权限(短信, 联系人,相片,录音等)运行时申请,不授权无法工作

5.1.1 在Androidmanifest.xml 声明读取短信权限

<uses-permission android:name="android.permission.READ_CONTACTS"/>

运行时动态申请权限,请求用户授权

  • ActivityCompat.checkSelfPremission(): 检查权限是否已授权,如果没有则需要向用户申请
  • ActivityCompat.requestPremissions(): 发起权限申请,弹出对话框
  • ActivityCompat.shouldShowRequsetPremissionRationale(): 检查用户是否永久拒绝,如果是,需要自己弹窗引导用户开启
  • onRequestPermissionRequset: 处理授权结果

example:

class PermissionActivity:AppCompatActivity() {}

通信录读取联系人
content://com.android.contacts/data/phones

display_name: 用户名
Data1:手机号

通信录插入联系人

  • AndroidManifest.xml声明权限
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>

content://com.android.contacts/data/data 插入联系人的表的名字
content://com.android.contacts/data/raw_contacts 插入联系人的原始表的名字

更新联系人信息
删除联系人

  • 根据姓名删除联系人
  • 根据手机号删除联系人

读取收件箱所有短信

字段 说明
address 发件人地址,即手机号,如+8613811810000
person 发件人地址,即手机号,如+8613811810000
date 日期,long型,如1256539465022,可以对日期显示格式进行设置
protocol 协议0 :SMS_RPOTO短信,1:MMS_PROTO彩信
read 是否阅读0:未读,1:已读
type 短信类型1: 接收到的短信,2:发出的短信
body 短信具体内容

3.1.1 普通启动 startService

1 Service实例,依次调用onCreate()和onStartCommand()方法,此时Service 进入运行状态

2 再次调用StartService启动Service,将不会再创建新的Service对象, 系统会直接复用前面创建的Service对象,调用它的onStartCommand()方法!

3 这样的Service与它的调用者无必然的联系,就是说当调用者结束了自己的生命周期, 但是只要不调用stopService,那么Service还是会继续运行的!

4 无论启动了多少次Service,只需调用一次StopService即可停掉Service

3.1.2 定义Service服务

class TestService : Service() {private val TAG = "TestService1 "// 必须实现的方法override fun onBind(intent: Intent?): IBinder? {Log.e(TAG, "onBind方法被调用")return null}//Service被创建时调用  override fun onCreate() {Log.e(TAG, "onCreate方法被调用!")super.onCreate()}//Service被启动时调用  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {Log.e(TAG, "onStartCommand方法被调用!")return super.onStartCommand(intent, flags, startId)}//Service被关闭之前回调  override fun onDestroy() {Log.e(TAG, "onDestory方法被调用!")super.onDestroy()}
}
  • AndroidManifest.xml完成Service注册
<application><service android:name=".components.TestService1">        service>
application>
  • 在Avtivity中StartService启动服务
val intent = Intent(this.TestService::class.java);
startService(intent)

onBind()方法并没有被调用,另外多次点击启动Service,只会重复地调用onStartCommand 方法!无论我们启动多少次Service,一个stopService就会停止Service!

3.1.2 绑定启动 bindService

①当首次使用bindService()启动一个Service时,系统会实例化一个Service实例,并调用其onCreate()和onBind()方法,然后调用者就可以通过返回的IBinder对象和Service进行交互了,此后如果我们再次使用bindService绑定Service,系统不会创建新的Sevice实例,也不会再调用onBind()方法,只会直接把IBinder对象返回给调用方

②如果我们解除与服务的绑定,只需调用unbindService(),此时onUnbind和onDestory方法将会被调用

③bindService启动的Service服务是与调用者(Activity)相互关联的,可以理解为 “一条绳子上的蚂蚱”,要死一起死,在bindService后,一旦调用者(Activity)销毁,那么Service也立即终止

  • 定义Service服务
  • AndroidManifest.xml中注册服务
  • 在Activity中bindService启动服务
  • 日志输出与结果分析

使用BindService绑定Service,依次调用onCreate(),onBind()方法, 我们可以在onBind()方法中返回自定义的IBinder对象;再接着调用的是 ServiceConnection的onServiceConnected()方法该方法中可以获得 IBinder对象,从而进行相关操作;当Service解除绑定后会自动调用 onUnbind和onDestroyed方法,当然绑定多客户端情况需要解除所有 的绑定才会调用onDestoryed方法进行销毁哦

3.2 Android 8.0及以上不允许后台启动Service服务

8.0系统杀服务杀的很频繁
为了保活,我们使用了俩Service互保的方式

AndroidManifest.xml声明权限

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

服务兼容写法

if (Build.VERSION.SDK_INT >= 26) {context.startForegroundService(intent);
} else {// Pre-O behavior.context.startService(intent);
}class TestService:Service(){// 发送一个前台通知override fun onCreate(){val notification: Notification =Notification.Builder(applicationContext, "channel_id").build()startForeground( 1, notification)}
}

4 BroadcastReceiver广播接收者

BroadcastReceiver广播接收者Android四大组件之一,是Android系统提供的一种通讯方式。
类似于村口大喇叭
涉及到两个角色,一个是广播发送者,一个是广播接收者。

应用场景:
Android不同组件间的通信(含 :应用内 / 不同应用之间)
多线程通信
与 Android 系统在特定情况下的通信

4.1 两种广播类型

标准广播:发出广播后,该广播事件的接收者,几乎会在同一时刻收到通知,都可以响应或不响应该事件

有序广播:发出广播后,同一时刻,只有一个广播接收者能收到、一个接收者处理完后之后,可以选择继续向下传递给其它接收者,也可以拦截掉广播。[不常用、不推荐使用了]

4.2 监听系统网络连接变化

4.2.1 定义一个接受者:

class TestBroadcastReceiver : BroadcastReceiver() {override fun onReceive(context: Conext>, intent: Intent?) {if (intent?.action?.equals(ConnectivityManager.CONNECTIVITY_ACTION) == true) {val connectivityManager: ConnectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerval info = connectivityManager.activeNetworkInfoif (info != null && info.isAvailable) {val typeName = info.typeNameToast.makeText(context, "当前网络名称:${typeName}", Toast.LENGTH_LONG).show()} else {Toast.makeText(context, "当前无网络连接", Toast.LENGTH_LONG).show()}}}
}

4.2.2 运行时动态注册广播接收事件

class TestBroadcastRecevierActivity :AppCompatActivity(){private lateinit var myReceiver: TestBroadcastReceiveroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)myReceiver = TestBroadcastReceiver()// 创建广播过滤器,指定只接收android.net.conn.CONNECTIVITY_CHANGE的广播事件val intentFilter = IntentFilter() intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED)registerReceiver(myReceiver, intentFilter)}override fun onDestroy() {super.onDestroy()unregisterReceiver(myReceiver)   // 必须要在onDestroy时反注册,否则会内存泄漏}
}

不要在广播后进行耗时操作,因为广播不允许开辟线程

onReceiver 运行超过10秒会报错(ANR)

4.2.3 静态注册广播

从android 8.0(API26)开始,对清单文件中静态注册广播接收者增加了限制,建议大家不要在清单文件中静态注册广播接收者。

AndroidManifest.xml 注册广播

<receiver android:name=".components.TestBroadcastReceiver"><intent-filter ><action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>intent-filter>
receiver>

4.2.4 解决静态注册广播接收者收不到事件的问题

4.3 发送自定义事件广播

4.3.1 全局发送广播

全局发送广播,如果别人家App也注册了该事件监听,也能收到,比较不合理。

sendBroadcast(new Intent(“com.example.firstapp.component.TEST_BROADCAST_RECEVIER”));

4.3.2 应用内发送广播

1 局部广播,发送和接受同属于一个APP
2 优势: 安全, 高效

使用LocalBroadcastManager 注册应用内广播

LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, itFilter)

使用LocalBoardcastManager 来发送应用内广播

LocalBroadcastManager.getInstance(this).sendBroadcast(intent)

4.3.2 系统广播(system boardcast)

只要涉及到手机基本操作: (网络变化, 拍照,开机等), 会发出相应广播

每个广播有特定的intent-filter


系统操作action
监听网络变化android.net.conn.CONNECTIVITY_CHANGE
关闭或打开飞行模式Intent.ACTION_AIRPLANE_MODE_CHANGED
充电时或电量发生变化Intent.ACTION_BATTERY_CHANGED
电池电量低Intent.ACTION_BATTERY_LOW
电池电量充足(即从电量低变化到饱满时会发出广播Intent.ACTION_BATTERY_OKAY
系统启动完成后(仅广播一次)Intent.ACTION_BOOT_COMPLETED
按下照相时的拍照按键(硬件按键)时Intent.ACTION_CAMERA_BUTTON
屏幕锁屏Intent.ACTION_CLOSE_SYSTEM_DIALOGS
设备当前设置被改变时(界面语言、设备方向等)Intent.ACTION_CONFIGURATION_CHANGED
插入耳机时Intent.ACTION_HEADSET_PLUG
未正确移除SD卡但已取出来时(正确移除方法:设置–SD卡和设备内存–卸载SD卡)Intent.ACTION_MEDIA_BAD_REMOVAL
插入外部储存装置(如SD卡)Intent.ACTION_MEDIA_CHECKING
成功安装APKIntent.ACTION_PACKAGE_ADDED
成功删除APKIntent.ACTION_PACKAGE_REMOVED
重启设备Intent.ACTION_REBOOT
屏幕被关闭Intent.ACTION_SCREEN_OFF
屏幕被打开Intent.ACTION_SCREEN_ON
关闭系统时Intent.ACTION_SHUTDOWN
重启设备Intent.ACTION_REBOOT

5.ContentProvider(内容提供者)

应用:

  1. 我们想在自己的应用中访问别的程序, 或者说一些ContentProvider暴露给我们一些数据,如手机联系人,短信,相册,对数据读写
  2. 我们自己的应用, 想暴露出去,避免私有数据泄露

5.1 权限申请

6.0开始,凡是涉及隐私的权限(短信, 联系人,相片,录音等)运行时申请,不授权无法工作

5.1.1 在Androidmanifest.xml 声明读取短信权限

<uses-permission android:name="android.permission.READ_CONTACTS"/>

运行时动态申请权限,请求用户授权

  • ActivityCompat.checkSelfPremission(): 检查权限是否已授权,如果没有则需要向用户申请
  • ActivityCompat.requestPremissions(): 发起权限申请,弹出对话框
  • ActivityCompat.shouldShowRequsetPremissionRationale(): 检查用户是否永久拒绝,如果是,需要自己弹窗引导用户开启
  • onRequestPermissionRequset: 处理授权结果

example:

class PermissionActivity:AppCompatActivity() {}

通信录读取联系人
content://com.android.contacts/data/phones

display_name: 用户名
Data1:手机号

通信录插入联系人

  • AndroidManifest.xml声明权限
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>

content://com.android.contacts/data/data 插入联系人的表的名字
content://com.android.contacts/data/raw_contacts 插入联系人的原始表的名字

更新联系人信息
删除联系人

  • 根据姓名删除联系人
  • 根据手机号删除联系人

读取收件箱所有短信

字段 说明
address 发件人地址,即手机号,如+8613811810000
person 发件人地址,即手机号,如+8613811810000
date 日期,long型,如1256539465022,可以对日期显示格式进行设置
protocol 协议0 :SMS_RPOTO短信,1:MMS_PROTO彩信
read 是否阅读0:未读,1:已读
type 短信类型1: 接收到的短信,2:发出的短信
body 短信具体内容


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部