Service 开机接受广播,启动服务的问题

简介: Service 开机接受广播,启动服务的问题

概述


Android 4.0 (其实在3.1的版本中Google已经给出了说明)无法接收开机广播的问题本身是因为,如果应用程序安装上始终没有被打开过,那么在Android启动时,该应用无法接收到开机时的系统广播android.permission.RECEIVE_BOOT_COMPLETED。


2.3+系列的版本是可以的,不过太老了,就不提了.


Launch controls on stoppedapplications


Starting from Android 3.1, the system’s package manager keeps track ofapplications that are in a

stopped state and provides a means of controllingtheir launch from

background processes and other applications.


Note that an application’s stopped state is not the same as an

Activity’sstopped state. The system manages those two stopped states

separately.


The platform defines two new intent flags that let a sender

specifywhether the Intent should be allowed to activate components in

stoppedapplication.


FLAG_INCLUDE_STOPPED_PACKAGES —Include intent filters of stopped

applications in the list of potential targetsto resolve against.

FLAG_EXCLUDE_STOPPED_PACKAGES —Exclude intent filters of stopped

applications from the list of potentialtargets. When neither or both

of these flags is defined in an intent, the defaultbehavior is to

include filters of stopped applications in the list ofpotential

targets.


Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGESto all

broadcastintents. It does this to prevent broadcasts from background

services frominadvertently or unnecessarily launching components of

stoppped applications.A background service or application can override

this behavior by adding theFLAG_INCLUDE_STOPPED_PACKAGES flag to

broadcastintents that should be allowed to activate stopped

applications.


Applications are in a stopped state when they are first installed but

are notyet launched and when they are manually stopped by the user (in

ManageApplications).


对应翻译


启动停止程序控制


从Android 3.1开始,系统的软件包管理器跟踪处于停止状态(stopped state)的应用程序,控制其启动后台进程和其他应用程序提供了一种手段。


需要注意的是应用程序的停止状态(stopped state)和Activity的停止状态是不一样的。该系统可以分别管理这两种停止状态。


该平台定义了两个新的Intent的Flag,控制发送者指定的Intent是否应该被允许激活停止的应用程序的组件。


FLAG_INCLUDE_STOPPED_PACKAGES -包括在停止的应用程序列表中。

FLAG_EXCLUDE_STOPPED_PACKAGES -排除在停止的应用程序列表中。


当两个Flag都不设置或都设置的时候,默认操作是FLAG_INCLUDE_STOPPED_PACKAGES。


请注意,系统会将FLAG_EXCLUDE_STOPPED_PACKAGES添加到所有的广播Intent中去。它这样做是为了防止广播无意中的或不必要地开展组件的stoppped应用程序的后台服务。后台服务或应用程序可以通过向广播Intent添加FLAG_INCLUDE_STOPPED_PACKAGES标志来唤醒处于停止状态(stopped state)的应用程序。


应用程序处于停止状态情况有两种:一种是他们是第一次安装,但尚未启动 ;另一种是在管理应用程序中由用户手动停止。


在4.0中android取消了无主activity运行的线程。所以开机启动的服务必须依赖于activiy。

应用程序中必须有:

       <intent-filter >
                <action android:name="android.intent.action.MAIN"></action>
                <category android:name="android.intent.category.LAUNCHER"></category>
            </intent-filter>


程序才能正常的接收开机广播。否则无法启动服务。

开机启动的服务,需要有个一Activity,单独无Activity的Service貌似行不通。


需要在真机中测试,genymotion等模拟器经验证不行。


Code


在BroadcastReceiver中,启动service和显示一个对话框主题的Activity提示服务启动成功。 真机验证,OK。

StartupReceiver

package com.turing.base.activity.service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.apkfuns.logutils.LogUtils;
/**
 * 只要完成两项工作: 启动服务 和 显示一个Activity提示服务启动成功(主题设置为Dialog的形式)
 */
public class StartupReceiver extends BroadcastReceiver {
    public StartupReceiver() {
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        LogUtils.e("StartupReceiver  onReceive");
        // 如果是开机启动的Action
        if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
            // 启动Activity
            Intent activityIntent = new Intent(context,BootCompletedMessageAct.class);
            // 想要在Service中启动Activity,必须设置如下标志
            activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(activityIntent);
            //启动服务
            Intent serviceIntent = new Intent(context,StartupService.class);
            context.startService(serviceIntent);
        }
    }
}

StartupService

package com.turing.base.activity.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class StartupService extends Service {
    public StartupService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        return  null ;
    }
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}


package com.turing.base.activity.service;
import android.app.Activity;
import android.os.Bundle;
import com.turing.base.R;
public class BootCompletedMessageAct extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_boot_completed_message);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.turing.base.activity.service.BootCompletedMessageAct">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="MyService已启动"
        />
</RelativeLayout>


AnroidManifest.xml (权限,主题为对话框的Act, Receiver,Service)

   <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  <activity
            android:name=".activity.service.BootCompletedMessageAct"
            android:theme="@android:style/Theme.Dialog">
            <intent-filter>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
  <!-- 开机广播 -->
        <receiver android:name=".activity.service.StartupReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <service
            android:name=".activity.service.StartupService"
            android:enabled="true"
            android:exported="true"></service>


验证


部署到真机上, 第一次先运行一次,然后关机重启,再次开机,就可以看到 这个服务启动成功后,弹出的 对话框主题样式的Act了。


如果是android4.0及以上,还是需要安装并运行一次,下次开机的时候才能实现接受广播,启动服务。而像2.3之类相对低的版本安装好了之后下次启动,就能直接获取并处理系统的开机广播,不需要先运行一次。

相关文章
|
9月前
|
Linux Shell 网络安全
服务停止后,自启动的service怎么写
当服务停止后,你可以通过在特定目录中创建一个.service文件来实现自启动。下面是一个示例: 1. 打开终端或者SSH连接到CentOS服务器上。 2. 进入`/etc/systemd/system/`目录。这是存放系统服务的位置,你可以将你的自启动服务文件放在这里。 3. 使用文本编辑器(如vi或nano)创建一个新的.service文件,文件名可以是任意的以`.service`结尾。 ```bash sudo vi myservice.service ``` 在文件中添加以下内容: ``` [Unit] Description=My
|
9月前
|
Java 应用服务中间件
本地启动 Hybris 服务器调试模式后,监听在 8000 端口
本地启动 Hybris 服务器调试模式后,监听在 8000 端口
59 0
|
Android开发
深入剖析Android四大组件(二)——Service服务之启动与绑定(一)
深入剖析Android四大组件(二)——Service服务之启动与绑定(一)
175 0
深入剖析Android四大组件(二)——Service服务之启动与绑定(一)
|
Android开发
深入剖析Android四大组件(二)——Service服务之启动与绑定(二)
深入剖析Android四大组件(二)——Service服务之启动与绑定(二)
228 1
深入剖析Android四大组件(二)——Service服务之启动与绑定(二)
Service的两种启动方式与区别
分享一下Service的启动知识
409 0
|
算法 Android开发
Android Service重启恢复(Service进程重启)原理解析(二)
Android Service重启恢复(Service进程重启)原理解析(二)
1331 0
Android Service重启恢复(Service进程重启)原理解析(二)
|
存储 Android开发
Android Service重启恢复(Service进程重启)原理解析(一)
Android Service重启恢复(Service进程重启)原理解析(一)
950 0
Android Service重启恢复(Service进程重启)原理解析(一)
|
Android开发
Android源码分析--Service的启动和绑定
Android源码分析--Service的启动和绑定
279 0
Android源码分析--Service的启动和绑定

热门文章

最新文章