0

我的应用程序将不会从wakefulbroadcastreceiverWakefulBroadcastReceiver startWakefulService未能继续

清单调用intentservice要求:

 <service 
     android:name=".MyWearableListenerService"> 
     <intent-filter> 
      <action android:name="com.google.android.gms.wearable.DATA_CHANGED" /> 
      <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/> 
      <data android:scheme="wear" android:host="*"/> 
     </intent-filter> 
    </service> 

    <service 
     android:name=".CounterActivity$WearableReceiverService" 
     android:exported="false"> 
    </service> 

    <receiver 
     android:name=".CounterActivity$WearableReceiver" 
     android:enabled="true"> 
    </receiver> 

所以我注册所有接收机和服务。

我的主要活动中,我有这些作为主类中的子类,所以我可以调用主类msgReqAction()方法

public class WearableReceiver extends WakefulBroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Intent service = new Intent(context, WearableReceiverService.class); 
     startWakefulService(context, service); 
    } 
} 

public class WearableReceiverService extends IntentService { 

    public WearableReceiverService(){ 
     super("WearableReceiverService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0)); 
     WearableReceiver.completeWakefulIntent(intent); 
    } 
} 

我不认为有这些作为子类应该阻碍但情况可能。如果我必须在主要班级以外进行手术,请告诉我。

终于我开始从一个听众,从可穿戴

@Override 
public void onMessageReceived(final MessageEvent messageEvent) { 
    nodeId = messageEvent.getSourceNodeId(); 
    String incomingPath = messageEvent.getPath(); 
    int incomingReq = Integer.parseInt(new String(messageEvent.getData())); 

    if(incomingPath.equalsIgnoreCase(MyConstants.MSG_COUNTER_REQ_PATH)) { 
     Intent broadcastIntent = new Intent(); 
     broadcastIntent.setAction(MyConstants.BROADCAST_ACTION_RESP); 
     broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
     broadcastIntent.putExtra(MyConstants.BROADCAST_DATA_REQ, incomingReq); 
     sendBroadcast(broadcastIntent); 

    }else if(incomingPath.equalsIgnoreCase(MyConstants.MSG_DEFAULT_PATH)){ 

    } 
} 

public static final String BROADCAST_ACTION_RESP = "com.example.johnbravado.zionwork.MESSAGE_PROCESSED"; 

我的项目侦听消息的主要活动外,整个过程com.example.johnbravado.zionwork - 也在一个侧面说明有一种方法来改变和重构在android工作室很容易,所以我可以摆脱例子或完全改变它?

当我运行调试器系统得到一路

startWakefulService(context, service); 

然后崩溃,而无需输入意图的服务。是否有一些简单的问题,我在所有这些方面失踪,这阻止了它进入服务和工作。最好的我可以告诉它它并没有进入服务。我添加了一些服务的介绍线

@Override 
protected void onHandleIntent(Intent intent) { 
    int data; 
    data = 0; 
    data++; 
    msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0)); 
    WearableReceiver.completeWakefulIntent(intent); 
} 

并试图在这些行上运行调试点,并没有达到那里。

回答

0

您不能将Service定义为非静态内部类。

非静态内部类包含对其外部类的引用。这意味着为了创建一个新的内部类的实例,你需要有一个外部类的实例。

当Android尝试启动Service时,它会尝试创建内部类的新实例。这会失败,因为Android没有在创建中使用外部类的实例。

同样的规则适用于BroadcastReceiver

解决方案:将所有内部类移到完整的类(在它们自己的源文件中)。

+0

反正我有可以调用msgReqAction()从外部服务。在设备进入睡眠模式时使用主要活动的服务点。或者,只有真正的方法是使服务可以引用的一些静态变量,然后在主要活动中调用onResume()时,执行睡眠时发生的事情所需的东西。 –

+0

您可以作弊并让'Activity'在'static'变量中存储对自身的引用,以便'Service'可以调用它的方法。但是,这是不好的做法。通常,一个'Service'通过发送广播'Intent'(Activity'正在监听)或者通过'Activity'绑定到'Service'并且从'Service'向''Service' Activity'使用AIDL或使用类似EventBus(这是一个发布/订阅框架) –

+0

我认为这就是我的广播接收机正在做的事情。如果我将wakefulbroadcast与普通广播进行交换并删除次要服务的使用,并只处理广播接收器中的msgReqaction(),那么它就可以工作。或者,如果不是其中的一部分,我将如何让广播接收器与主要活动一起工作。 –

0

解决方案是消除WakefulfulBroadcastReceiver和辅助IntentService。相反,我使用了BroadcastReceiever并直接从Wearable监听器函数发送广播,并使用它直接在活动内处理数据。

public class WearableReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     //Intent service = new Intent(context, WearableReceiverService.class); 
     //startWakefulService(context, service); 
     PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); 
     PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 
       "com.example.johnbravado.zionwork"); 
     wakeLock.acquire(); 
     // Do Work 
     msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0)); 

     wakeLock.release(); 
    } 
} 

即使我没有做太多的事情,这肯定需要一个唤醒锁。如果我以后决定做更多的工作,我已经准备好了。我不确定这是否是这个唤醒锁的最佳位置,要么从未真正使用它们,但这是另一个话题。

我删除参考在manifest文件还额外业务和接收器。做工不错,现在