2015-11-09 69 views
-2

首先,我爲我可憐的英語感到抱歉,我希望你能理解我。更新線程片段

的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和大多數教程都是英文的,有關文檔同樣的事情,所以很難獨自正確學習...

我試過沒有成功計算器發現許多片段,現在我感到有點失落..

編輯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 
     } 
+0

我只是給你出主意。在fregement中使用獲取值的接口 –

+0

@Virat Puar:接口不是用於從片段到活動的通信? –

回答

0

你可以保持您HomeFragment參考您的MainActivity喜歡這一點,並把它添加到您的尋呼機適配器:

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()); 
+0

現在我可以在方法中獲取我的字符串,但是當我嘗試將字符串設置爲文本視圖時,我收到「NullPointerException」。 –

+0

你能發佈完整的異常消息嗎? –