2011-04-27 208 views
2

首先對不起的,我的英語。所以我正在製作一個程序,當他/她需要 來獲得他/她的藥品時會提醒用戶。我的基本想法:

1 AlarmManager給我的信號
2我趕上信號與我的廣播接收器,
3和廣播接收器開始我的服務,我的活動。啓動活動和服務從廣播接收器

服務計數10分鐘,每分鐘下來將從數據庫 檢查其它參數和活動將讓聲音和振動。因爲會有更多的藥物,我用 按鈕做了一個列表。而且由於服務和活動使用相同的遊標,因此該服務與數據庫具有連接 。所以當我的Activity開始時,它需要從Service中獲取光標(對於cursoradapter)。 如果服務或活動更改了遊標,我需要刷新該遊標,所以我在服務中進行了重新查詢。

唯一的問題是,儘管我的bindService給了我真正的結果,但我的onServiceConnected 方法沒有運行,所以當我嘗試從我的活動調用公共服務方法(對於遊標) 。我嘗試在onStartCommand之後從服務啓動我的Activity,但結果也是一個空指針。

什麼是才達到我的任務的最佳方法是什麼? 我應該刪除我的服務,並從將執行服務工作的活動中創建另一個線程(AsyncTask)?

好吧,我想抓出重要組成部分。

package elte.thesis.broadcastreceivers; 

import elte.thesis.alarmsmanager.AlarmActivity; 
import elte.thesis.alarmsmanager.WakeLockManager; 
import elte.thesis.database.Utility; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.util.Log; 

/* 
* This BroadcastReceiver will receive the ALARM from the AlarmManager 
* and it will 
* 1, start the Service and 
* 2, show the AlarmActivity 
*/ 
public class DosageAlarmReceiver extends BroadcastReceiver { 

@Override 
public void onReceive(Context context, Intent intent) { 
    Log.v("Szakbarbar", 
      "AlarmManager send me the next " + "alarm time: " + intent.getStringExtra("AlarmTime")); 

    /* 
    * It seems that the alarmmanager release the wakelock as soon as our 
    * onReceive method return, so we need to make our own wakelock 
    */ 
    WakeLockManager.acquireCpuWakeLock(context); 

    /* 
    * Start the service and give him the time what we got from alarm manager 
    */ 
    Log.v("Szakbarbar", "Elinditjuk a servicunket"); 
    Intent serviceIntent = new Intent(Utility.ALARM_SERVICE); 
    serviceIntent.putExtra("AlarmTime", intent.getStringExtra("AlarmTime")); 
    context.startService(serviceIntent); 

    /* 
    * Start the AlarmActivity where the user can sign that he got in the 
    * pills 
    */ 
    Log.v("Szakbarbar", "Elinditjuk az activitinket"); 
    Intent alarmActivity = new Intent(context, AlarmActivity.class); 
    alarmActivity.putExtra("AlarmTime", intent.getStringExtra("AlarmTime")); 
    alarmActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION); 
    context.startActivity(alarmActivity); 

} 

} 

在礦山AlarmActivity

AlarmService mService; 
... 
@Override 
public void onStart() { 
    super.onStart(); 

    Log.v("Szakbarbar", "Bind to the Service"); 
    Intent intent = new Intent(Utility.ALARM_SERVICE); 
    boolean connection = bindService(intent, mConnection,  Context.BIND_AUTO_CREATE); 
    Log.v("Szakbarbar", "Binded to the Service : " +  ((connection==true)?"kapcsolt":"nemkapcsolt")); 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    Log.v("Szakbarbar", "Need the cursor from the Service"); 
    updateDosageAdapter(); 

    //Make one private register to now when the AlarmService made change on the cursor 
    registerReceiver(mReceiver, new IntentFilter(Utility.ALARMS_CHANGED)); 

    if (!mute) { 
     if (volume < 1) 
      incAlarmVolume(); 
     mVibrator.vibrate(sVibratePattern, 0); 
     player.start(); 
    } 
} 

/** Defines callbacks for service binding, passed to bindService() */ 
private ServiceConnection mConnection = new ServiceConnection() { 

    @Override 
    public void onServiceConnected(ComponentName className, IBinder service) { 
     // We've bound to LocalService, cast the IBinder and get LocalService instance 
     Log.v("Szakbarbar", "mService itt még nulla"); 
     LocalBinder binder = (LocalBinder) service; 
     mService = binder.getService(); 
     mBound = true; 
     Log.v("Szakbarbar", "mService itt már nem nulla");   
    } 

    @Override 
    public void onServiceDisconnected(ComponentName arg0) { 
     mBound = false; 
    } 
}; 
public void updateDosageAdapter() { 
    Log.v("Szakbarbar", "1"); 
    alarmsCursor = mService.refreshCursor(); 
    Log.v("Szakbarbar", "2");  
    startManagingCursor(alarmsCursor); 
    Log.v("Szakbarbar", "3");  
    if (alarmsAdapter == null) { 
     Log.v("Szakbarbar", "4");   
     alarmsAdapter = new AlarmsAdapter(this, alarmsCursor); 
     alarmsList = (ListView) findViewById(R.id.dosage_alarm_list); 
     alarmsList.setAdapter(alarmsAdapter); 
     alarmsList.setVerticalScrollBarEnabled(true); 
     alarmsList.setScrollContainer(false); 
     alarmsList.setOnCreateContextMenuListener(this); 
    } else { 
     Log.v("Where is nullpointerexception", "5");    
     alarmsAdapter.changeCursor(alarmsCursor); 
    } 
} 

在我的服務我的問題 的

private final IBinder mBinder = new LocalBinder(); 
... 
// Return this instance of AlarmService so clients can call public methods 
public class LocalBinder extends Binder { 
    AlarmService getService() { 
     return AlarmService.this; 
    } 
} 

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

//Refresh the cursor 
public Cursor refreshCursor() { 

    Log.v("Szakbarbar", "ResreshCrusor : " + alarmTime); 

    alarmCursor = Utility.selectDosageAlarms(alarmTime);   
    return alarmCursor; 
} 

簡短說明我想你不知道什麼是我的問題呢。我不善於英語,對於麻煩感到抱歉。雖然我叫bindService()的調用onStart()的AlarmActivity的 方法,當我打電話(也AlarmActivity)updateDosageAdapter(),它使用refreshCursor()方法從我得到 一個空指針異常的服務,因爲onServiceConnected( )方法沒有運行下來,我的服務varieble應該持有 我的服務的參考是空的。

+0

描述發佈一些代碼將有助於 – 2011-04-27 17:38:37

+0

我不這麼認爲:)相信我,你會更混亂。不想讓你感到不安或任何我很高興的幫助,但我想我寫下了關於這個問題的一切。 啓動服務 開始活動,在活動在onStart嘗試調用從服務的公共方法,之後我做了onBind,但我得到NullPointerException異常導致我從ServiceConnection onServiceConnected方法沒有辦下來,所以我與服務的參考varieble是null – user727781 2011-04-27 17:56:44

+0

你是完全正確的問題。當你調用bindService時,服務是異步綁定的,所以在真正綁定服務之前調用onResume。UpdateDosageAdapter取決於服務,因此在調用此方法之前必須確保已連接服務,因此當您的活動連接到服務時,最佳的調用方法將位於onServiceConnected中。 – 2011-04-27 21:35:39

回答