如何让应用程序的广播接收器继续监听,而无需在后台运行服务

时间:2014-11-26 10:05:42

标签: android android-intent android-broadcast

我正在尝试创建一个监听wifi改变广播并执行某些操作的Android应用程序。但问题是当进程被杀死时它无法正常工作。我发现这个问题说没有活动就行不通 How to create BroadcastReceiver without Activity/Service?

所以这不是另类。因此我创建了一个空的活动。我不想创建一个在后台运行的服务。如果应用程序被杀死,我怎样才能让我的应用程序继续听。我已在清单中注册了广播。

<activity
        android: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>

    <receiver android:name="com.background.service.BroadCastReceiver">  
        <intent-filter>
            <action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>  
    </receiver>

这是我的班级

public class BroadCastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    //do some action
   }
}

5 个答案:

答案 0 :(得分:3)

看起来你在清单中有正确的定义,只有一个例外。如果广播接收器在10秒内没有完成,它将触发ANR。 http://developer.android.com/training/articles/perf-anr.html

在您的广播接收器中只需启动一项服务。

public class ReceiverUpload extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    context.startService(new Intent(context, ServiceUploader.class));
}
}

然后在您的服务中启动asynctask,因为您不想进入UI线程,例如您从应用中的活动启动相同的服务。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // start asynctask to get off this thread
    new MyBackGround().execute(startId);
    return Service.START_REDELIVER_INTENT;
}

在asynctask中要做的第一件事就是检查wifi

以下摘录自我调用检查网络的函数,如果它返回false,asynctask刚刚结束,如果它确实是网络的东西,嘿必须在后台,所以asynctask更有意义。< / p>

// check for network connection
        ConnectivityManager connMgr = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connMgr == null) {
            return false;
        }

        // check ok to process
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo == null || !networkInfo.isConnected()) {
            return false;
        }

        boolean isWifi = networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
        if (!isWifi) {

                return false;

        }

        return true;

请注意,在此示例中,传递给asynctask的startId用于取消重新传递意图的操作系统。

 @Override
    public void onPostExecute(Integer startId) {
        if (startId != null) {
            stopSelfResult(startId);
        }
    }

答案 1 :(得分:2)

最适合我的方式:

AndroidManifest

<receiver android:name="com.AEDesign.communication.WifiReceiver" >
  <intent-filter android:priority="100">
    <action android:name="android.net.wifi.STATE_CHANGE" />
  </intent-filter>
</receiver>

BroadcastReceiver类

public class WifiReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

  NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
  if(info != null) {
     if(info.isConnected()) {
        // Do your work. 

        // e.g. To check the Network Name or other info:
   WifiManager wifiManager=(WifiManager)context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        String ssid = wifiInfo.getSSID();
     }
  }
 }
 }           

权限

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

答案 2 :(得分:1)

通常情况下,如果应用程序被杀死并且广播到来,您的应用程序进程将由系统为您启动。绝对没有必要保留一些东西或进行任何额外的操作(否则,如果你只能使用BroadcastReceiver,为什么还需要Service?)

答案 3 :(得分:1)

最好的解决方案是制作广播接收器,它会起作用

public class NetworkChangeReceiver extends BroadcastReceiver {

@Override
public void onReceive(final Context context, final Intent intent) {
    final ConnectivityManager connMgr = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);

    final android.net.NetworkInfo wifi = connMgr
            .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

    final android.net.NetworkInfo mobile = connMgr
            .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

    if (wifi.isAvailable() || mobile.isAvailable()) {
        // Enjoy coding here 

        Log.d("Netowk Available ", "Flag No 1");
    }
}}
manifest.xml中的

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastreceiverforinternetconnection"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <receiver android:name=".NetworkChangeReceiver" >
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
        </intent-filter>
    </receiver>
</application>

答案 4 :(得分:1)

您已经正确使用广播接收器并将其声明为Manifest。这就是你需要做的一切。不需要在后台运行服务。

请确保您至少安装并运行该应用一次,否则广播收到的广告将无法注册