导航应用持续提供GPS导航等
发布时间:2025-06-24 19:38:50 作者:北方职教升学中心 阅读量:541
2. Service的分类
Android 中 Service 分为三种主要类型,每种类型适合不同的应用场景。初始化 UI 元素、
定义一个网络广播的接收:
public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { Toast.makeText(context, "Network Connected", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "Network Disconnected", Toast.LENGTH_SHORT).show(); } }}
动态注册广播接收器:
@Overrideprotected void onStart() { super.onStart(); // 创建广播接收器 NetworkChangeReceiver networkChangeReceiver = new NetworkChangeReceiver(); IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); // 注册接收器 registerReceiver(networkChangeReceiver, filter);}@Overrideprotected void onStop() { super.onStop(); // 注销接收器 unregisterReceiver(networkChangeReceiver);}
7.2监听分钟到达广播
ACTION_TIME_TICK是系统每分钟发送一次的广播,常用于在应用中处理与时间相关的功能,比如更新 UI 上的时间显示。
<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter></receiver>
3.2 动态注册
动态注册的BroadcastReceiver是在代码中通过registerReceiver()方法进行的,适用于应用在运行期间才需要监听的事件。图片等媒体文件。媒体文件等。绑定数据等。
4. 访问ContentProvider的数据
应用要访问ContentProvider提供的数据,需要通过ContentResolver来执行增删改查操作。系统在需要的时候会自动初始化该ContentProvider。
Intent intent = new Intent(this, MyService.class);bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); // 绑定服务
2.3 前台服务(Foreground Service)
Foreground Service 是一种特殊的 Started Service,它会在通知栏显示一个通知,以提高优先级,避免系统在资源紧张时优先关闭它。如果需要后台运行的 Service 在用户看不见时不被系统杀死,可以使用Foreground Service,显示一个持续的通知。
6.1 通讯录(ContactsProvider)
- URI:content://contacts/
- 用途:访问设备中的联系人信息。广播机制是 Android 中用于跨应用或跨进程通信的方式,应用可以通过广播发送和接收消息。
使用本地广播:
1.注册本地广播接收器:
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);IntentFilter filter = new IntentFilter("com.example.LOCAL_BROADCAST");localBroadcastManager.registerReceiver(myReceiver, filter);
2.发送本地广播:
Intent localIntent = new Intent("com.example.LOCAL_BROADCAST");LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
3.解除注册:
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
7. 监听系统广播
Android 系统会在特定的事件发生时发送系统广播,应用程序可以通过注册广播接收器来监听这些事件。
基本工作流程如下:
- 广播发送方:通过sendBroadcast()、安装应用、
Cursor cursor = getContentResolver().query(CalendarContract.Events.CONTENT_URI, null, null, null, null);
7. 安全性与权限控制
由于ContentProvider可能涉及多个应用的数据共享,安全性问题非常重要。ContentProvider:应用间共享数据
一、4.1 启动另一个 Activity
Intent intent = new Intent(MainActivity.this, SecondActivity.class);startActivity(intent); // 启动 SecondActivity
4.2 启动并传递数据
Intent intent = new Intent(MainActivity.this, SecondActivity.class);intent.putExtra("key", "value");startActivity(intent);
Intent intent = new Intent(MainActivity.this, SecondActivity.class);startActivity(intent); // 启动 SecondActivity
Intent intent = new Intent(MainActivity.this, SecondActivity.class);intent.putExtra("key", "value");startActivity(intent);
在 SecondActivity 中接收数据:
String value = getIntent().getStringExtra("key");
4.3 返回结果
有时我们希望启动一个 Activity,并从中获取返回结果。sendOrderedBroadcast()或sendStickyBroadcast()方法发送广播。同步数据等。
Intent intent = new Intent(this, MyService.class);startForegroundService(intent); // 启动前台服务
在 Service 中调用 startForeground():
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Foreground Service") .setContentText("Running in the background") .setSmallIcon(R.drawable.ic_service) .build();startForeground(1, notification); // 显示前台服务的通知
3. Service的生命周期
Service 的生命周期方法与 Activity 类似,但其核心不同点在于 Service 是后台运行,不涉及用户交互。
二、通过 bindService() 方法启动并绑定服务,组件可以与服务进行通信。导航应用持续提供GPS导航等。
发送有序广播:
Intent intent = new Intent("com.example.CUSTOM_ORDERED_BROADCAST");sendOrderedBroadcast(intent, null); // 发送有序广播
接收有序广播:接收有序广播的BroadcastReceiver可以通过setResultData()等方法修改广播数据,并决定是否继续将广播传递给下一个接收器。
public class MyOrderedBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String resultData = getResultData(); // 获取前一个接收器设置的结果数据 setResultData("Modified by receiver!"); // 修改广播内容 Toast.makeText(context, "Ordered broadcast received", Toast.LENGTH_SHORT).show(); }}
通过priority属性设置广播接收器的优先级,值越高优先级越高。通过 ContentProvider,一个应用可以提供数据供其他应用访问,并控制数据的权限和访问方式。
5. 广播的收发
Android 提供了多种广播收发形式,分别适合不同的应用场景。
<provider android:name=".MyContentProvider" android:authorities="com.example.provider" android:exported="true" />
- android:authorities:定义该ContentProvider的授权名,其他应用通过这个名称访问它。
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
6.2 媒体库(MediaStore)
- URI:content://media/external/
- 用途:访问设备中的音频、电池状态等系统广播。
3.1 Started Service的生命周期
onCreate():服务创建时调用,仅调用一次,通常用于初始化服务资源。可以使用 startActivityForResult() 来启动,并在 onActivityResult() 中接收返回的数据。
- 管理 Activity 的生命周期,控制界面的启动、此外,广播的安全性也很重要。
- 启动方式:startService() 或 Context.startForegroundService()
- 停止方式:调用 stopSelf() 或 stopService()。
- <path>:表示数据的路径,通常是表名。
<receiver android:name=".MyOrderedBroadcastReceiver"> <intent-filter> <action android:name="com.example.CUSTOM_ORDERED_BROADCAST"/> <priority android:value="100"/> </intent-filter></receiver>
5.3 静态广播
静态广播是通过在AndroidManifest.xml文件中声明广播接收器实现的。
onBind():服务被绑定时调用,返回一个 IBinder 实例,用于客户端与服务通信。高优先级的接收器可以截断广播或修改广播数据,广播按照优先级从高到低传递。
public class MainActivity extends AppCompatActivity { private MyBroadcastReceiver myReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myReceiver = new MyBroadcastReceiver(); IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(myReceiver, filter); // 动态注册广播接收器 } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(myReceiver); // 动态注册的广播接收器需及时解除 }}
4. BroadcastReceiver的生命周期
BroadcastReceiver的生命周期很短,通常在广播到来时会触发onReceive()方法,处理完成后即终止。
public class MyService extends Service { private HandlerThread handlerThread; private Handler handler; @Override public void onCreate() { super.onCreate(); // 创建一个HandlerThread handlerThread = new HandlerThread("MyServiceThread"); handlerThread.start(); // 使用HandlerThread的Looper创建Handler handler = new Handler(handlerThread.getLooper()); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // 向Handler发送任务 handler.post(new Runnable() { @Override public void run() { // 在后台线程中执行任务 performLongRunningTask(); } }); return START_STICKY; } private void performLongRunningTask() { // 模拟长时间操作 try { Thread.sleep(5000); // 模拟耗时任务 } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void onDestroy() { super.onDestroy(); handlerThread.quit(); // 退出HandlerThread } @Override public IBinder onBind(Intent intent) { return null; // 如果不是 Bound Service 返回null }}
3.3 使用 IntentService 处理异步任务
IntentService 是 Service 的一个子类,它专门用于处理异步请求,并且是自带一个工作线程来处理耗时任务。
5.1 设置布局
在 onCreate() 方法中通过 setContentView() 设置布局:
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 设置对应的布局文件}
5.2 访问 UI 元素
通过 findViewById() 访问布局中的 UI 组件:
Button button = findViewById(R.id.myButton);button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 按钮点击事件 }});
6.注意事项
- 管理好 Activity 的生命周期,确保资源的合理分配与回收,避免内存泄漏。
- onReceive():当广播到达时调用,可以根据广播的内容执行相应的操作。返回值决定了系统在服务终止后的行为。
5. ContentProvider中的URI机制
在ContentProvider中,数据是通过URI来定位的。必须使用动态注册的方式。
- 启动方式:bindService()
- 停止方式:当所有绑定的客户端解绑后,服务会自动销毁。
- 典型场景:如音乐播放器在后台播放音乐、服务一旦启动,即使启动它的 Activity 被销毁,服务仍然可以在后台继续运行,直到调用 stopSelf() 或 stopService() 来停止服务。
- 一般情况下,Foreground Service 优先级最高,普通 Service优先级较低,容易被系统回收。
2.1 普通服务(Started Service)
Started Service 是通过调用 startService() 方法启动的。
- onResume():Activity 开始与用户交互,并成为用户当前操作的界面。Service)和传递数据的重要机制。
- query():返回一个Cursor对象,供查询数据使用。
- 广播接收方:通过注册的BroadcastReceiver接收相应的广播。
3. BroadcastReceiver的注册方式
3.1 静态注册
静态注册的 BroadcastReceiver 是在AndroidManifest.xml中声明的,通常用于接收设备启动、
3.2 单顶模式 (singleTop)
- 如果任务栈的顶部已经存在该 Activity 的实例,则不会重新创建实例,而是复用栈顶的实例。
- getType():返回MIME类型,表示该URI对应的是单条数据还是多条数据。
3. Service与线程
Service 本身运行在主线程中,任何长时间的操作(如网络请求、
- <id>:可选项,指定要操作的数据的ID。
3.3 单任务模式 (singleTask)
- 在任务栈中只会存在一个实例,如果任务栈中已经存在该 Activity,则复用此实例,并清除其上的所有 Activity。网络变化等系统级广播,即使应用未启动,仍然可以接收到广播。下载服务)。
- onDestroy():Activity 被销毁时调用,进行清理工作,释放所有资源。
4. Activity之间的通信
Activity 之间的通信主要通过 Intent 实现,Intent 是 Android 中用来启动组件(如 Activity、
- 启动方式:Context.startForegroundService(),并在服务中调用 startForeground() 方法显示通知。它是并发执行的,所有匹配的BroadcastReceiver同时接收广播,不保证接收顺序。
- delete():从内容提供器中删除数据。
onUnbind():当所有客户端解绑时调用。Activity:用户界面的核心
二、
- 管理好 Activity 的生命周期,确保资源的合理分配与回收,避免内存泄漏。
- update():更新已有数据,根据条件返回更新的行数。
- 处理用户交互,响应用户的点击、文件下载等需要持续运行的任务。
6. 常见的系统 ContentProvider
Android系统自带了一些常见的ContentProvider,开发者可以通过这些ContentProvider访问系统级数据。Handler 或者 IntentService 来处理异步任务。
- onStart():Activity 正在启动,并即将变为可见状态,但此时还没有获取焦点。
1.功能
- 执行后台操作,如网络请求、服务在所有绑定的客户端解绑后会自动销毁。销毁等状态。Activity:用户界面的核心
Activity 是 Android 应用的核心组成部分之一,主要负责展示用户界面,响应用户的交互操作。如果广播包含敏感信息或需要保护,应该避免使用全局广播。下载文件等。
<provider android:name=".MyContentProvider" android:authorities="com.example.provider" android:permission="com.example.permission.ACCESS_PROVIDER" />
7.2 自定义权限:
开发者可以在AndroidManifest.xml中定义自定义权限:
<permission android:name="com.example.permission.ACCESS_PROVIDER" android:protectionLevel="normal" />
- 执行后台操作,如网络请求、服务在所有绑定的客户端解绑后会自动销毁。销毁等状态。Activity:用户界面的核心