2011-07-19 57 views
0

我正在嘗試使活動運行某項服務。Android遠程服務:無通訊

我跟着教程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()); 
    } 
} 

}

非常感謝大家的幫助!

回答

0

bindService()是異步的。在調用onServiceConnected()之前,您不能使用callsLoggingService

+0

哦,我如何確保我可以在'onServiceConnected()'之後使用它? – noloman

+0

@noloman:那是你的工作。 – CommonsWare

+0

但我不明白它:它沒有被調用,但服務仍在開始?因爲Log.i(getClass()。getSimpleName(),「調用dumpCallsLog」)行被執行 – noloman