使用线程

时间:2015-11-09 17:31:43

标签: java android android-fragments

首先,我很抱歉我的英语不好,我希望你能理解我。

APP:

  • 1个包含3个片段和PageAdaptater的活动确定

  • 从蓝牙设备收集数据。的确定

  • 每次通过处理程序在MainActivity中收集数据时,都会更新片段中的TextView。

在我的代码下面:

MainActivity:

public class MainActivity extends FragmentActivity {

    private PagerAdapter mPagerAdapter;
    private static final String TAG = "bluetooth2";
    private String btaddr = "20:14:09:17:00:40";
    Handler h;
    final int RECIEVE_MESSAGE = 1;        // Status  for Handler
    private BluetoothAdapter btAdapter = null;
    private BluetoothSocket btSocket = null;
    private StringBuilder sb = new StringBuilder();
    private ConnectedThread mConnectedThread;
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.viewpager);

        // Création de la liste de Fragments que fera défiler le PagerAdapter
        List<Fragment> fragments = new Vector<Fragment>();

        // Ajout des Fragments dans la liste
        fragments.add(Fragment.instantiate(this,HomeFragment.class.getName()));
        fragments.add(Fragment.instantiate(this,NormalFragment.class.getName()));
        fragments.add(Fragment.instantiate(this,ConfigFragment.class.getName()));

        // Création de l'adapter qui s'occupera de l'affichage de la liste de
        // Fragments
        this.mPagerAdapter = new MyPagerAdapter(super.getSupportFragmentManager(), fragments);

        ViewPager pager = (ViewPager) super.findViewById(R.id.viewpager);
        // Affectation de l'adapter au ViewPager
        pager.setAdapter(this.mPagerAdapter);

        h = new Handler() {
            public void handleMessage(android.os.Message msg)  {
                switch (msg.what) {
                case RECIEVE_MESSAGE:                                                   // if receive massage
                    byte[] readBuf = (byte[]) msg.obj;
                    String strIncom = new String(readBuf, 0, msg.arg1);                 // create string from bytes array
                    sb.append(strIncom);                                                // append string
                    int endOfLineIndex = sb.indexOf("\r\n");                            // determine the end-of-line
                    if (endOfLineIndex > 0) {                                            // if end-of-line,
                        String sbprint = sb.substring(0, endOfLineIndex);               // extract string
                        sb.delete(0, sb.length());                                      // and clear

                        Log.d(TAG, "...String:"+ sb.toString() +  "Byte:" + msg.arg1 + "...");
                        //My question : How to send data to fragment from here ?

                        break;
                    }
                }
            };
        };

        btAdapter = BluetoothAdapter.getDefaultAdapter();       // get Bluetooth adapter

        checkBTState();


      }

      private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
          if(Build.VERSION.SDK_INT >= 10){
              try {
                  final Method  m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
                  return (BluetoothSocket) m.invoke(device, MY_UUID);
              } catch (Exception e) {
                  Log.e(TAG, "Could not create Insecure RFComm Connection",e);
              }
          }
          return  device.createRfcommSocketToServiceRecord(MY_UUID);
      }

      @Override
      public void onResume() {
        super.onResume();

        Log.d(TAG, "...onResume - try connect...");

        // Set up a pointer to the remote node using it's address.
        BluetoothDevice device = btAdapter.getRemoteDevice(btaddr);

        // Two things are needed to make a connection:
        //   A MAC address, which we got above.
        //   A Service ID or UUID.  In this case we are using the
        //     UUID for SPP.

        try {
            btSocket = createBluetoothSocket(device);
        } catch (IOException e) {
            errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
        }

        // Discovery is resource intensive.  Make sure it isn't going on
        // when you attempt to connect and pass your message.
        btAdapter.cancelDiscovery();

        // Establish the connection.  This will block until it connects.
        Log.d(TAG, "...Connecting...");
        try {
          btSocket.connect();
          Log.d(TAG, "....Connection ok...");
        } catch (IOException e) {
          try {
            btSocket.close();
          } catch (IOException e2) {
            errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
          }
        }

        // Create a data stream so we can talk to server.
        Log.d(TAG, "...Create Socket...");

        mConnectedThread = new ConnectedThread(btSocket);
        mConnectedThread.start();
      }

      @Override
      public void onPause() {
        super.onPause();

        Log.d(TAG, "...In onPause()...");

        try     {
          btSocket.close();
        } catch (IOException e2) {
          errorExit("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
        }
      }

      private void checkBTState() {
        // Check for Bluetooth support and then check to make sure it is turned on
        // Emulator doesn't support Bluetooth and will return null
        if(btAdapter==null) {
          errorExit("Fatal Error", "Bluetooth not support");
        } else {
          if (btAdapter.isEnabled()) {
            Log.d(TAG, "...Bluetooth ON...");
          } else {
            //Prompt user to turn on Bluetooth
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
          }
        }
      }

      private void errorExit(String title, String message){
        Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show();
        finish();
      }

      public class ConnectedThread extends Thread {
            private final InputStream mmInStream;
            private final OutputStream mmOutStream;

            public ConnectedThread(BluetoothSocket socket) {
                InputStream tmpIn = null;
                OutputStream tmpOut = null;

                // Get the input and output streams, using temp objects because
                // member streams are final
                try {
                    tmpIn = socket.getInputStream();
                    tmpOut = socket.getOutputStream();
                } catch (IOException e) { }

                mmInStream = tmpIn;
                mmOutStream = tmpOut;
            }

            public void run() {
                byte[] buffer = new byte[256];  // buffer store for the stream
                int bytes; // bytes returned from read()

                // Keep listening to the InputStream until an exception occurs
                while (true) {
                    try {
                        // Read from the InputStream
                        bytes = mmInStream.read(buffer);        // Get number of bytes and message in "buffer"
                        h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget();     // Send to message queue Handler
                    } catch (IOException e) {
                        break;
                    }
                }
            }

            /* Call this from the main activity to send data to the remote device */
            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() + "...");
                  }
            }
        }

}

HomeFragment(接收者):

public class HomeFragment extends Fragment {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View myInflatedView = inflater.inflate(R.layout.home_layout, container, false);

        return myInflatedView;
    }

}

家庭布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="20dp"
        android:text="DATA" />

</LinearLayout>

在这种情况下,对于您来说,如何从活动中的处理程序轻松地将数据发送到HomeFragment并更新内部的textview?

我是Java的新手,大多数教程都是英文的,关于文档也是如此,所以单独学习很难...

我尝试了很多在stackoverflow上找到的片段而没有成功,现在我有点迷失了..

编辑1:
根据要求,这里是PagerAdaptater的代码:

public class MyPagerAdapter extends FragmentPagerAdapter {

    private final List<Fragment> fragments;

    //On fournit à l'adapter la liste des fragments à afficher
    public MyPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return this.fragments.get(position);
    }

    @Override
    public int getCount() {
        return this.fragments.size();
    }
}

编辑2:
更新了HomeFragment

public class HomeFragment extends Fragment {

    TextView data;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View myInflatedView = inflater.inflate(R.layout.home_layout, container, false);
        data= (TextView) myInflatedView.findViewById(R.id.data);

        return myInflatedView;
    }
      public void change(String txt){
          data.setText(txt); //Don't WORK "NullPointerException"
          Log.d("TEST", "...String:"+ txt +  "..."); //Work
        }

}

编辑3:

解决方案,在执行setText之前检查数据是否为空。

public void change(String txt){
            if(data != null){
                data.setText(str);
            }
          Log.d("TEST", "...String:"+ txt +  "..."); //Work
        }

1 个答案:

答案 0 :(得分:0)

您可以在MainActivity中保留对HomeFragment的引用,并将其添加到寻呼机适配器:

public class MainActivity extends FragmentActivity {
    // instanciate other variables
    private HomeFragment myHomeFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.

        List<Fragment> fragments = new Vector<Fragment>();

        this.myHomeFragment = fragment.instantiate(this,HomeFragment.class.getName());

        fragments.add(myHomeFragment);
        fragments.add(Fragment.instantiate(this,NormalFragment.class.getName()));
        fragments.add(Fragment.instantiate(this,ConfigFragment.class.getName()));

        ...
    }
}

然后,在HomeFragment中,声明一个公共方法,它接受一个字符串并设置TextView的文本并在你的处理程序中调用它:

myHomeFragment.setTextView(sb.toString());