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文件還額外業務和接收器。做工不錯,現在