Android удаленных сервисов: нет связи - PullRequest
0 голосов
/ 19 июля 2011

Я пытаюсь заставить Activity выполнять определенный сервис.

Я следовал учебному пособию здесь , но адаптировался к своему коду, и я не могу заставить его работать, потому что когда яя вызываю службу после запуска и привязываю ее к действию, мой объект интерфейса (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());
    }
}

} ​​

Большое спасибо всем за помощь!

1 Ответ

0 голосов
/ 19 июля 2011

bindService() является асинхронным. Вы не можете использовать callsLoggingService, пока не будет вызван onServiceConnected().

...