我正在开发一款通过蓝牙从Arduino接收数据并将该数据发送到服务器的应用。我已经完成了这部分工作 - 一旦用户按下按钮,我就会启动BT连接,接收数据并通过异步任务将其发送到服务器:
接收数据的线程:
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i("test", "Connected thread RUN");
byte[] buffer = new byte[256];
int bytes;
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
Log.i("test", "Trying....");
bytes = mmInStream.read(buffer);
handler.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(String message) {
Log.d(TAG, "...Data to send: " + message + "...");
byte[] msgBuffer = message.getBytes();
try {
mmOutStream.write(msgBuffer);
} catch (IOException e) {
Log.d(TAG, "...Error data send: " + e.getMessage() + "...");
}
}
}
ConnectedThread处理程序(接收数据,启动AsyncTask):
private final Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RECIEVE_MESSAGE:
byte[] readBuf = (byte[]) msg.obj;
//String readMessage = new String(readBuf, 0, msg.arg1);
String strIncom = new String(readBuf, 0, msg.arg1);
sb.append(strIncom);
int endOfLineIndex = sb.indexOf("\r\n");
if (endOfLineIndex > 0) {
String sbprint = sb.substring(0, endOfLineIndex);
sb.delete(0, sb.length());
Log.i("test", "sbprint: " + sbprint);
sendDataToServer(sbprint);
txtData.setText("Data from Arduino: " + sbprint);
}
break;
}
};
};
sendDataToServer方法:
private void sendDataToServer(String dataToSend){
if(dataToSend != null && !dataToSend.equals("")) {
sendDataAsyncTask = new SendDataAsyncTask(MyActivity.this, dataToSend);
sendDataAsyncTask.setSendDataListener(MyActivity.this);
sendDataAsyncTask.execute();
}
}
这或多或少有效。但是,现在我需要每两分钟重复一次这个过程。我已经使用TimerTask,但当设备进入休眠状态时,任务停止运行。
我猜我需要一个服务和/或一个AlarmManager来每两分钟唤醒一次设备并运行上面的代码?有什么提示吗?
答案 0 :(得分:3)
是的,没错。您需要实现Service
来执行后台作业,即执行向服务器发送数据,即使您的应用不在前台或设备显示器关闭时也是如此。
您可以在此处使用我的示例代码之一:https://xjaphx.wordpress.com/2012/07/07/create-a-service-that-does-a-schedule-task/
此外,如果您想让Service
以最佳状态运行(即确保它不被系统杀死),您需要经常检查
实施BOOT_RECEIVED
Intent
,BroadcastReceiver
,以便在设备启动时启动您的应用。
注册AlarmManager
以安排检查Service
是否正在运行;如果它已经死亡,你可以重新启动(唤醒)它。
答案 1 :(得分:0)
对于偶然需要的人:
MainActivity.class:
public class MainActivity extends Activity implements OnClickListener {
private AlarmManager alarmManager;
private static final long INTERVAL = 10*1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn = (Button) findViewById(R.id.btn);
final Button btn2 = (Button) findViewById(R.id.btn2);
btn.setOnClickListener(this);
btn2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn:
setServiceAlarm();
break;
case R.id.btn2:
cancelServiceAlarm();
break;
default:
break;
}
}
private void setServiceAlarm(){
if(alarmManager == null){
Log.i("test", "***STARTING SERVICE***");
showToast("Starting...");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), INTERVAL, pendingIntent);
}
}
private void cancelServiceAlarm(){
if(alarmManager != null){
Log.i("test", "***STOPPING SERVICE***");
showToast("Stopping...");
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
}
private void showToast(String message){
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
AlarmReciever.class:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i("test", "Alarm received...");
Intent serviceIntent = new Intent(context, MyIntentService.class);
serviceIntent.putExtra("date", Utils.getDateTime());
context.startService(serviceIntent);
//Log.i("test", "onReceive: " + Utils.getDateTime());
}
}
MyIntentService.class:
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
// TODO Auto-generated constructor stub
}
@Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
final String str = intent.getStringExtra("date");
Log.i("test", "MyIntentService " + str);
}
}
应用程序标记内的清单声明:
<service android:name=".MyIntentService"/>
<receiver android:name=".AlarmReceiver"></receiver>