Android 处理数据流并在后台创建记录
我已经创建了一个应用程序,它可以很好地完成以下步骤-Android 处理数据流并在后台创建记录,android,sockets,android-broadcast,android-bluetooth,android-background,Android,Sockets,Android Broadcast,Android Bluetooth,Android Background,我已经创建了一个应用程序,它可以很好地完成以下步骤- 使用蓝牙插座连接远程设备(SPP) 然后侦听来自远程蓝牙设备的流 在单独的线程中 然后,当数据流出现时,它将数据流传递给处理程序以对其进行解析 解析数据时,发送广播并创建记录 输入数据库 现在我想添加一个新功能- 当应用程序处于后台并“连接”到远程设备时,它需要继续处理数据流并创建记录 因此,一旦连接了套接字,我就将结果“connected”传递给onPostExecute()方法 重要提示: 1) 我所有与套接字相关的工作(套接字连接、
- 使用蓝牙插座连接远程设备(
)SPP
- 然后侦听来自远程蓝牙设备的流 在单独的线程中
- 然后,当数据流出现时,它将数据流传递给处理程序以对其进行解析
- 解析数据时,发送广播并创建记录 输入数据库
onPostExecute()
方法
重要提示:
1) 我所有与套接字相关的工作(套接字连接、套接字数据解析、数据处理程序)都在片段中
2) 一旦建立了连接,片段中的私有类(Thread-ConnectedThread.java)将继续侦听InputStream
3) 处理步骤2的读取的我的处理程序
4) 我已连接,因此可以从AsyncTask parseStream的onPostExecute()执行某些操作
5) 我在步骤4中调用了该服务,目的是在应用程序进入后台时执行该服务
和处理数据。但是,它将如何与片段通信,因为我的整个工作
数据处理在片段中。我真的需要它来处理数据还是应该打电话给这里的广播接收机是否也可以在后台处理 我在这方面做了不少工作。我将与你分享我的经验中最有效的方法 -专用蓝牙服务,运行在它自己的独立进程中,用于处理连续的数据流
-在获取和处理数据时避免广播;特别是如果它是快速和大数据流。这是我过去在处理bt流时犯的一个错误。我意识到,它可能适用于少量或慢速流,但是,广播非常昂贵,当用IPC代替它们时,我看到了巨大的性能改进(UI线程我们需要以固定的时间间隔调用服务以从套接字获取数据吗?我已经实现了连接和处理片段中数据的逻辑,所以我需要像上面的代码那样将其转移到BluetoothManager类吗?服务应该在从该片段进行套接字连接之后启动,所以我认为BluetoothManager class需要重新实现。请查看我的更新!@VedPrakash,不,您不需要以固定的时间间隔呼叫该服务。该服务将通知(通过发送新消息)每当有新的数据可用时,主线程。@ VePraskash,我还补充说,你应该真正考虑到你的蓝牙工作流在一个片段中的影响。你在Android的生命周期控制下,无法正确地使用你的蓝牙工作流。从某个视图来看,需要转到此片段视图,以便向用户显示。然后用户可以关闭应用程序,数据将继续在后台流动。因此,我必须使用此片段。但是,查看您的代码,我同意“绑定”使用片段的范围。@VedPrakash,理想情况下,您应该将其绑定到片段的基本活动。更好的是,绑定任何活动,让后台服务处理数据并将其转发给绑定的任何人。这样,您可以将应用程序放在后台,关闭当前活动/片段,您仍然可以执行bl这是一个非常好的工作。而且,您不需要每次处理一段数据时都重新启动ConnectedThread。您只需要一个
public class EntryFragment extends Fragment{
//More fragment code here then this
public class ConnectedThread extends Thread {
public ConnectedThread(BluetoothSocket socket) {
//code initialization stuff
}
public void run() {
// Keep listening to the InputStream until an exception occurs
while (true)
{
// Read from the InputStream
if(mmInStream.available() > 0)
{
bytes = mmInStream.read(buffer);
mHandler.obtainMessage(MESSAGE_READ,
bytes, -1, buffer).sendToTarget();
}
}
}
}
case MESSAGE_READ:
//Call to AsyncTask to do background processing of data
new parseStream(getActivity()).execute();
break;
@Override
protected void onPostExecute(Void result) {
//Database related work here
//Result is connected so listen to data if app goes to background after this state
if(result.equals("connected"))
{
Log.i(TAG, "CONNECTED TO Remote Device!");
Toast.makeText(getActivity(),"CONNECTED TO Remote
Device!",Toast.LENGTH_SHORT).show();
//Do something when connected
setSetting("STATUS", "Connected");
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
//Do I need to call Service here to handle data ?????
Intent serviceIntent= new Intent(context, DataProcessService.class);
getActivity().startService(serviceIntent);
}
}
public class BluetoothService extends Service {
//
// API keys for the messages being passed across ui thread <-> service
//
static final int REGISTER_CLIENT = 3;
static final int NEW_DATA = 2;
static final int WRITE_DATA = 1;
static final int CONNECT_BT = 0;
// manages actual connection
private BluetoothManager btManager;
// who is activity and ready to receive messages?
private Messenger clientToReply;
public int onStartCommand(Intent intent, int flags, int startId) {
btManager = new BluetoothManager(this);
return START_STICKY;//makes sure the service keeps running and get's back up if it gets terminated
}
//
// Send data back to your activity
//
public void sendDataToBoundClient(byte[] bytes) {
Message msgToClient = new Message();
msgToClient.what = NEW_DATA;
Bundle bNewData = new Bundle();
bNewData.putByteArray("newData", bytes);
msgToClient.setData(bNewData);
try {
clientToReply.send(msgToClient); //send
} catch (RemoteException e) {
e.printStackTrace(); //couldn't send
}
}
/**
* Handles messages received from a bound Context
*/
public class MessageHandler extends Handler {
/* (non-Javadoc)
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case REGISTER_CLIENT:
// now we know to whom to reply with our messages, callbacks or new data
clientToReply = msg.replyTo;
break;
case WRITE_DATA:
break;
case CONNECT_BT:
// launches Connect & Connected Threads
// would follow the same pattern as in http://developer.android.com/guide/topics/connectivity/bluetooth.html#ConnectingAsAClient
btManager.connect();
break;
}
}
}
}
//
// Check examples in http://developer.android.com/guide/topics/connectivity/bluetooth.html#ConnectingAsAClient
//
public class BluetoothManager {
private ConnectThread connectThread; //thread to connect
private ConnectedThread connectedThread; //thread manages connection
private BluetoothService service;
public BluetoothManager(BluetoothService service) {
this.service = service;
}
//
// stuff omitted...
//
public void connect() {
connectThread = new ConnectThread();
connectThread.start();
}
public void writeData(byte[] bytes) {
connectedThread.write(bytes);
}
public void onDataRead(byte[] bytes) {
// service knows how to forward this to the client (bound activity, for example)
this.service.sendDataToBoundClient(bytes);
}
}
//
// Based on the example from http://developer.android.com/guide/components/bound-services.html#Messenger
//
public class ActivityMessenger extends Activity {
/** Messenger for communicating with the service. */
Messenger mService = null;
// handle incoming messages
protected Messenger messagesFromService = new Messenger(new IncomingHandler());
/** Flag indicating whether we have called bind on the service. */
boolean mBound;
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};
public void registerAsClient() {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = new Message();
msg.what = BluetoothService.REGISTER_CLIENT;
msg.replyTo = messagesFromService; // reply to "me"!
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
public class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BluetoothService.NEW_DATA:
Bundle data = msg.getData;
// handle your new data!
break;
}
}
}
}
}
}