2017-02-17 61 views
0

我有一个BroadcastReciever和一个服务。当建立互联网连接时,它必须开始下载一些数据的服务。广播接收器不工作。声明在清单

我的广播接收器

public class NetworkStateListener extends BroadcastReceiver 
{ 

@Override 
public void onReceive(Context c, Intent intent) 
    { 
    Toast.makeText(c,"started",Toast.LENGTH_SHORT).show(); 
    c.startService(new Intent(c,DataDownloader.class)); 

    // TODO: Implement this method 
    } 

} 

这里是清单的部分代码...

<receiver android:name="com.Example.SGSN.worker.NetworkStateListener" 
     android:enabled="true"> 
     <intent-filter android:priority="999"> 
      <action android:name="android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION"/> 
      <action android:name="android.net.wifi.WIFI_STATE_CHANGED"/> 
      <action android:name="android.net.wifi.WifiManager.SUPLICANT_STATE_CHANGED_ACTION"/> 
      <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> 
     </intent-filter> 
    </receiver> 

,并要求权限...

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

甚至不是一个单一的动作得到了触发。我不知道我犯了什么错误。我也寻找答案,但我的问题没有解决。 当我在活动中动态注册它时,BroadcastReceiver将工作。我需要它在后台。有人请帮忙。

+0

为什么你使用那个 - “android:process =”:channel“'? – Divers

+0

我不知道究竟是什么,我在教程视频中看到它。 –

+1

您在接收器中输入错误=>接收器 – Jaythaking

回答

1

您应该删除:

android:process=":channel"

UPD

下面的清单的代码是100%的工作:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.andrey.test"> 

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

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity 
      android:name=".MainActivity" 
      android:label="@string/title_activity_main2"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.DEFAULT" /> 
      </intent-filter> 
     </activity> 

     <receiver 
      android:name=".MyReceiver" 
      android:enabled="true"> 
      <intent-filter> 
       <action android:name="android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION" /> 
       <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> 
       <action android:name="android.net.wifi.WifiManager.SUPLICANT_STATE_CHANGED_ACTION" /> 
       <action android:name="android.net.conn.CONNECTIVITY_ACTION" /> 
      </intent-filter> 
     </receiver> 

    </application> 

</manifest> 
+0

删除了android:process =“:channel”但结果没有改进:-( –

+0

我运行了这段代码,它正在工作,我复制了整个清单 – Divers

+0

但是这里没有显示任何Toast通知,服务没有运行 –

1

在清单中,你设定的接收器标签内的应用程序标签?

喜欢:

<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> 
+0

是的,但这里只是复制了重要的代码行 –

0

就Android牛轧糖的(API 24)。在Manifest中声明的广播接收器将不再被提醒“android.net.conn.CONNECTIVITY_CHANGE”事件。帮助节省电池:)。较旧版本的Android不受影响。

要在Nougat中收听此事件,您必须以编程方式注册广播。

1

试试这样实现:

首先你服务,这将监听在网络连接的变化:

public class SyncService extends Service { 

public static Intent getStartIntent(Context context) { 
    return new Intent(context, SyncService.class); 
} 


@Override 
public void onCreate() { 
    super.onCreate(); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, final int startId) { 
    Timber.i("Starting sync..."); 

    if (!NetworkUtil.isNetworkConnected(this)) { 
     Timber.i("Sync canceled, connection not available"); 
     stopSelf(startId); 
     return START_NOT_STICKY; 
    } 

    //Here you can define what you need to do when internet is available 
    //Can download from internet and sync to local for example 

    return START_STICKY; 
} 

@Override 
public void onDestroy() { 
    if (mSubscription != null) mSubscription.unsubscribe(); 
    super.onDestroy(); 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

public static class SyncOnConnectionAvailable extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION) 
       && NetworkUtil.isNetworkConnected(context)) { 
      Timber.i("Connection is now available, triggering sync..."); 
      context.startService(getStartIntent(context)); 
     } 
    } 
} 

广播接收器将启动该服务,然后根据你已经决定什么作用在onStartCommand();

接下来在清单申报的服务如下:

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

<service android:name=".SyncService"/> 

<receiver 
    android:name=".SyncService$SyncOnConnectionAvailable" 
    android:enabled="false"> 
    <intent-filter> 
     <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
    </intent-filter> 
</receiver> 

这将通知服务随时检测到网络的变化。

现在您需要从任何活动中启动服务,因为您希望服务在后台运行,所以我毫无疑问将成为您的主要活动。这个例子只会在主要活动按照我的例子开始时触发。你可以根据自己的喜好调整它。

主要活动:

​​

而这仅仅是一个NetworkUtil类可以派上用场:

public class NetworkUtil { 

    public static boolean isNetworkConnected(Context context) { 
     ConnectivityManager cm = 
      (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); 
     return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); 
    } 

} 

的服务都将在MainActivity的onCreate这两条线被触发() 。根据您的需求调整此示例。我从https://github.com/ribot/android-boilerplate/的Ribot样板代码示例中使用了此示例的部分内容。