2011-04-27 123 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

回答