0

我正在尝试让 Activity 运行某个服务。

我按照教程here但是适应了我的代码,我不能让它工作,因为当我在启动并将它绑定到活动后调用服务时,我的接口(IMyRemoteCallsLoggingService)对象似乎没有正确创建连接.

几天来我一直在尝试完成这项工作,但我似乎无法摆脱NullPointException.

不知道我是否说清楚了,在这种情况下,代码如下:

public class MtprojectActivity extends Activity {
[...]
private boolean started = false;

private RemoteSmsLoggingServiceConnection SmsLoggingConn = null;
private RemoteCallsLoggingServiceConnection CallsLoggingConn = null;

private IMyRemoteCallsLoggingService callsLoggingService;
private IMyRemoteSmsLoggingService smsLoggingService;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    retrievePreferences();

    Button prefBtn = (Button) findViewById(R.id.prefsBtn);

    prefBtn.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            // Explicit intent to call the preferences
            Intent preferencesActivity = new Intent(getBaseContext(),
                    Preferences.class);
            startActivity(preferencesActivity);
        }
    });
}

private void retrievePreferences() {
    // Get the xml/preferences.xml preferences
    SharedPreferences prefs = PreferenceManager
            .getDefaultSharedPreferences(getBaseContext());
    callsCheckbox = prefs.getBoolean("callsLogChk", false);
    smsCheckbox = prefs.getBoolean("smsLogChk", false);
    locationCheckbox = prefs.getBoolean("locationLogChk", false);

    if (callsCheckbox) {
        startCallsService();
        bindCallsService();
        try {
            invokeCallsService();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    } else {

    }
    private void startCallsService() {
    if (started) {
        Toast.makeText(MtprojectActivity.this, "Service already started",
                Toast.LENGTH_SHORT).show();
    } else {
        Intent i = new Intent();
        i.setClassName("app.mtproject", "app.mtproject.CallsLoggingService");
        startService(i);
        started = true;
        updateCallsServiceStatus();
        Log.d(getClass().getSimpleName(), "startService()");
    }
}
    private void bindCallsService() {
    if (CallsLoggingConn == null) {
        CallsLoggingConn = new RemoteCallsLoggingServiceConnection();
        Intent i = new Intent();
        i.setClassName("app.mtproject", "app.mtproject.CallsLoggingService");
        bindService(i, CallsLoggingConn, Context.BIND_AUTO_CREATE);
        updateCallsServiceStatus();
        Log.d(getClass().getSimpleName(), "bindService()");
    } else {
        Toast.makeText(MtprojectActivity.this,
                "Cannot bind - service already bound", Toast.LENGTH_SHORT)
                .show();
    }
}
    private void invokeCallsService() throws RemoteException {
    if (CallsLoggingConn == null) {
        Toast.makeText(MtprojectActivity.this,
                "Cannot invoke - service not bound", Toast.LENGTH_SHORT)
                .show();
    } else {
        callsLoggingService.dumpCallsLog();
        TextView t = (TextView) findViewById(R.id.notApplicable);
        t.setText("It worked!");
        Log.d(getClass().getSimpleName(), "invokeService()");
    }
}
    class RemoteCallsLoggingServiceConnection implements ServiceConnection {
    public void onServiceConnected(ComponentName className,
            IBinder boundService) {
        callsLoggingService = IMyRemoteCallsLoggingService.Stub
                .asInterface((IBinder) boundService);
        Log.d(getClass().getSimpleName(), "onServiceConnected()");
    }

    public void onServiceDisconnected(ComponentName className) {
        callsLoggingService = null;
        updateCallsServiceStatus();
        Log.d(getClass().getSimpleName(), "onServiceDisconnected");
    }
};

我在方法NullPointerException上是正确的,但我不确定是什么问题!callsLoggingService.dumpCallsLog()invokeCallsService()

这是服务的代码:

public class CallsLoggingService extends Service {
String date, duration, type;

private Handler serviceHandler;
private Task myTask = new Task();

@Override
public IBinder onBind(Intent arg0) {
    Log.d(getClass().getSimpleName(), "onBind()");
    return myRemoteCallsServiceStub;
}

private IMyRemoteCallsLoggingService.Stub myRemoteCallsServiceStub = new IMyRemoteCallsLoggingService.Stub() {
    public void dumpCallsLog() throws RemoteException {
        CallsLoggingService.this.dumpCallsLog();
    }
};

@Override
public void onCreate() {
    super.onCreate();
    Log.d(getClass().getSimpleName(), "onCreate()");
}

@Override
public void onDestroy() {
    super.onDestroy();
    serviceHandler.removeCallbacks(myTask);
    serviceHandler = null;
    Log.d(getClass().getSimpleName(), "onDestroy()");
}

@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    serviceHandler = new Handler();
    serviceHandler.postDelayed(myTask, 10L);
    Log.d(getClass().getSimpleName(), "onStart()");
}

class Task implements Runnable {
    public void run() {
        try {
            myRemoteCallsServiceStub.dumpCallsLog();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        serviceHandler.postDelayed(this, 86400000L);
        Log.i(getClass().getSimpleName(), "Calling the dumpCallsLog");
    }
}

private synchronized void dumpCallsLog() {
    ContentResolver cr = getContentResolver();
    String columns[] = new String[] { CallLog.Calls.DATE,
            CallLog.Calls.DURATION, CallLog.Calls.TYPE };
    Uri mContacts = CallLog.Calls.CONTENT_URI;
    Cursor c = cr.query(mContacts, columns, // Which columns to return
            null, // WHERE clause; which rows to return(all rows)
            null, // WHERE clause selection arguments (none)
            CallLog.Calls.DEFAULT_SORT_ORDER // Order-by clause
            // (ascending
            // by name)

            );
    if (c.moveToFirst()) {
        do {
            // Get the field values
            date = c.getString(c.getColumnIndex(CallLog.Calls.DATE));
            duration = c
                    .getString(c.getColumnIndex(CallLog.Calls.DURATION));
            type = c.getString(c.getColumnIndex(CallLog.Calls.TYPE));
        } while (c.moveToNext());
    }
}

}

非常感谢大家的帮助!

4

1 回答 1

0

bindService()是异步的。你不能使用callsLoggingService直到onServiceConnected()被调用。

于 2011-07-19T17:41:27.700 回答