2017-07-06 48 views
1

我一直在尋找,我無法找到答案。我只是想在我的片段中啓用藍牙。我增加了以下內容繫到我的onResume()回調:藍牙啓用意圖在片段

 if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { 
     Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
     startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT); 
    } 

出於某種原因,輸出只是口口聲聲說,Activity.onPostResume()叫了一遍又一遍,它實際上鎖住了我的UI。我想知道是否有解決方案?

編輯:AutoConnectFragment:

public class AutoConnectFragment extends Fragment { 

    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1; 
    private Toolbar mToolbar; 
    private CollapsingToolbarLayout collapsingToolbar; 
    private ImageView mBackArrow; 
    private Button mStartTiming; 
    private RecyclerView mLaserRecyclerView; 
    private LaserAdapter mAdapter; 
    private String mCurrentEvent; 
    private BluetoothAdapter mBluetoothAdapter; 
    private BluetoothLeScanner mBluetoothLeScanner; 
    private AutoConnectBLE mScanner; 
    private static boolean mIsLasersConnected; 
    private Drill mCurrentDrill; 
    private AutoConnectEventSelected mCallback; 
    private static final int REQUEST_ENABLE_BT = 3; 
    private static final int REQUEST_CODE_LOCATION = 42; 
    private boolean permissionChecked = false; 




    // Container Activity must implement this interface 
    public interface AutoConnectEventSelected { 
     public void onAutoConnectEventSelected(String event); 
    } 




    // private nested custom view holder class 
    public class LaserHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 

     private TextView mLaserName; 
     private Module mModule; 
     private ImageView mConnectIcon; 
     private ProgressBar mProgressBar; 


     public LaserHolder(LayoutInflater inflater, ViewGroup parent) { 
      super(inflater.inflate(R.layout.list_item_laser, parent, false)); 
      itemView.setOnClickListener(this); 


      // grab the font 
      Typeface mont_reg = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Montserrat-Regular.ttf"); 

      // grab the user name and change the font 
      mLaserName = (TextView) itemView.findViewById(R.id.laser_name); 
      mLaserName.setTypeface(mont_reg); 

      // grab the progress bar 
      mProgressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar); 

      //grab the connect icon 
      mConnectIcon = (ImageView) itemView.findViewById(R.id.connect_icon); 
     } 

     public void bind(Module module) { 

      // set the text view to the module name 
      mModule = module; 
      mLaserName.setText(module.getName()); 
     } 

     // if the user clicks on the connect laser 
     @Override 
     public void onClick(View v) { 
      if (mModule.getName().equals("RFID")) { 
       mProgressBar.setVisibility(View.VISIBLE); 
       mConnectIcon.setVisibility(View.GONE); 
//    mScanner.scanRFID(mCurrentDrill, mModule.getName(), v, getContext(), mAdapter,getAdapterPosition()); 
      } else { 
       mProgressBar.setVisibility(View.VISIBLE); 
       mConnectIcon.setVisibility(View.GONE); 
       mScanner.scanLaser(v,mCurrentDrill, mModule.getName(),mAdapter,getAdapterPosition()); 
      } 

      mAdapter.setCurrentPosition(getAdapterPosition()); 


     } 
    } 

    public class LaserAdapter extends RecyclerView.Adapter<LaserHolder> { 
     private List<Module> mModules; 
     private String mCurrentMAC; 
     private int mCurrentPosition; 


     public LaserAdapter(List<Module> modules) { 
      mModules = modules; 
     } 

     @Override 
     public LaserHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); 
      return new LaserHolder(layoutInflater, parent); 
     } 

     @Override 
     public void onBindViewHolder(LaserHolder holder, int position) { 
      Module module = mModules.get(position); 
      /* if a laser is already connected and 
      the user tries to connect the same laser to another position, 
      unconnect the previous connection 
      */ 
      if (!TextUtils.isEmpty(module.getMACaddress())){ 
       if (module.getMACaddress().equals(mCurrentMAC) && position != mCurrentPosition){ 
        holder.mConnectIcon.setImageResource(R.drawable.ic_flash); 
        module.setMACaddress(null); 
       } 
      } 

      checkAllLasersConnected(mModules); 

      holder.bind(module); 
     } 

     @Override 
     public int getItemCount() { 
      return mModules.size(); 
     } 

     public String getCurrentMAC() { 
      return mCurrentMAC; 
     } 

     public void setCurrentMAC(String currentMAC) { 
      mCurrentMAC = currentMAC; 
     } 

     public int getCurrentPosition() { 
      return mCurrentPosition; 
     } 

     public void setCurrentPosition(int currentPosition) { 
      mCurrentPosition = currentPosition; 
     } 

     public void checkAllLasersConnected(List<Module> modules){ 

      int numLasersConnected = 0; 
      // checking to see if all of the lasers are connected 
      for (int i = 0; i < modules.size(); i++) { 
       System.out.println("Name: " + modules.get(i).getName() + " MAC :" + modules.get(i).getMACaddress()); 
       if (modules.get(i).getMACaddress() == null) { 
        numLasersConnected++; 
       } 
      } 

      // if all of the lasers are connected, enabled the start timing button 
      if (numLasersConnected == 0) { 
       mStartTiming.setEnabled(true); 
      } else { 
       mStartTiming.setEnabled(false); 
      } 
     } 
    } 


    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 

     // inflate the layout for this fragment 
     View view = inflater.inflate(R.layout.fragment_autoconnect, container, false); 


     // grab the recyclerview and set its layout manager 
     mLaserRecyclerView = (RecyclerView) view.findViewById(R.id.list_recycler_view); 
     mLaserRecyclerView.setLayoutManager((new LinearLayoutManager(getActivity()))); 


     // update the UI (recycler view) 
     updateUI(savedInstanceState); 

     return view; 
    } 

    @Override 
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
     super.onViewCreated(view, savedInstanceState); 


     // grab the views 
     collapsingToolbar = (CollapsingToolbarLayout) view.findViewById(R.id.collapsing_toolbar); 
     mToolbar = (Toolbar) view.findViewById(R.id.toolbar); 
     mBackArrow = (ImageView) view.findViewById(R.id.back_arrow); 
     mStartTiming = (Button) view.findViewById(R.id.start_timing_button); 

     // disable the startTiming button until all of the lasers are connected 
     mStartTiming.setEnabled(false); 

     //Set toolbar title 
     collapsingToolbar.setTitle(getArguments().getString("Event") + " Connect"); 
     // setting the text alignment 
     collapsingToolbar.setExpandedTitleColor(Color.WHITE); 
     collapsingToolbar.setCollapsedTitleGravity(Gravity.CENTER_HORIZONTAL); 
     collapsingToolbar.setCollapsedTitleTextColor(Color.WHITE); 
     collapsingToolbar.setExpandedTitleGravity(Gravity.CENTER_HORIZONTAL); 

     // set the font 
     Typeface mont_bold = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Montserrat-Bold.ttf"); 
     Typeface mont_regular = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Montserrat-Regular.ttf"); 
     collapsingToolbar.setExpandedTitleTypeface(mont_bold); 
     collapsingToolbar.setCollapsedTitleTypeface(mont_regular); 

     // set background color to dark grey 
     mToolbar.setBackgroundColor(getResources().getColor(R.color.darkGrey)); 

     // set up bluetooth 
     mScanner = new AutoConnectBLE(getContext()); 


     // collapsing tool bar effect (explained in main activtiy) 
     AppBarLayout mAppBarLayout = (AppBarLayout) view.findViewById(R.id.app_bar_layout); 
     mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { 
      @Override 
      public void onOffsetChanged(AppBarLayout appBarLayout, int i) { 
       //measuring for alpha 
       int toolBarHeight = mToolbar.getMeasuredHeight(); 
       int appBarHeight = appBarLayout.getMeasuredHeight(); 
       Float f = ((((float) appBarHeight - toolBarHeight) + i)/((float) appBarHeight - toolBarHeight)) * 255; 
       if (Math.round(f) == 0) { 
        mToolbar.setBackgroundColor(getResources().getColor(R.color.darkGrey)); 
       } else { 
        mToolbar.getBackground().setAlpha(0); 
       } 

      } 
     }); 


     // if user clicks on the back arrow, go back to testing page 
     mBackArrow.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Fragment frag = new TestingFragment(); 
       FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); 
       ft.replace(R.id.container, frag, frag.getTag()); 
       ft.addToBackStack(null); 
       ft.commit(); 
      } 
     }); 

     // if the user clicks on the start timing, goto the timing page 
     mStartTiming.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       mCallback.onAutoConnectEventSelected(getArguments().getString("Event")); 
      } 
     }); 


    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     System.out.println("ON RESUME CALLED"); 

     if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { 
      System.out.println("INTENT CALLED"); 
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      getActivity().startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 
     } 
// 
//  if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 
//   Toast.makeText(getActivity(), "No LE Support, Please install this app on another phone", Toast.LENGTH_SHORT).show(); 
//   return; 
//  } 

    } 

    private void updateUI(Bundle savedInstanceState) { 

     List<Module> modules = null; 
     // check to see which event the user chose and grab the laser array list 
     switch (getArguments().getString("Event")) { 
      case "Dash": 
       Dash dash = Dash.getInstance(); 
       modules = dash.getModules(); 
       mCurrentDrill = dash; 
       break; 
      case "ProAgility": 
       ProAgility pa = ProAgility.getInstance(); 
       modules = pa.getModules(); 
       mCurrentDrill = pa; 
       break; 
      case "DashSplit": 
       DashSplit ds = DashSplit.getInstance(); 
       modules = ds.getModules(); 
       mCurrentDrill = ds; 
       break; 
      case "Flying40": 
       Flying40 f = Flying40.getInstance(); 
       modules = f.getModules(); 
       mCurrentDrill = f; 
       break; 
      case "Lap": 
       Lap l = Lap.getInstance(); 
       modules = l.getModules(); 
       mCurrentDrill = l; 
       break; 
     } 

     mAdapter = new LaserAdapter(modules); 
     mLaserRecyclerView.setAdapter(mAdapter); 

    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 

     Activity a; 

     if (context instanceof Activity){ 

      a = (Activity) context; 
      // This makes sure that the container activity has implemented 
      // the callback interface. If not, it throws an exception 
      try { 
       mCallback = (AutoConnectEventSelected) a; 
      } catch (ClassCastException e) { 
       throw new ClassCastException(a.toString() 
         + " must implement OnHeadlineSelectedListener"); 
      } 
     } 

    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == REQUEST_ENABLE_BT) { 
      System.out.println(requestCode); 
      if (resultCode == Activity.RESULT_CANCELED) { 
       //Bluetooth not enabled. 
       getActivity().finish(); 
       return; 
      } else { 
       return; 

      } 
     } 

     super.onActivityResult(requestCode, resultCode, data); 
    } 



} 

BLE自動連接掃描儀類:

public class AutoConnectBLE { 

    private BluetoothAdapter mBluetoothAdapter; 
    private BluetoothManager mBluetoothManager; 
    private BluetoothLeScanner mBluetoothLEScanner; 
    private ScanSettings mSettings; 
    private Context mContext; 
    private long mStartScanTimeStamp; 
    private long connectTimeStamp = 0L; 





    private class laserCallBack extends ScanCallback { 

     private Drill drill; 
     private AutoConnectFragment.LaserAdapter mAdapter; 
     private int position; 
     private boolean isConnected = false; 
     private long scanTimeStamp = 0L; 
     private long mElapsedTimeScanning; 
     private String mHex; 
     private long mLaserTime; 
     private String mBeefMessage; 
     private String name; 
     private ImageView mConnectIcon; 
     private ProgressBar mProgressBar; 



     public laserCallBack(View view, Drill drill,String name, AutoConnectFragment.LaserAdapter mAdapter, int position) { 
      super(); 
      this.drill = drill; 
      this.mAdapter = mAdapter; 
      this.position = position; 
      this.name = name; 

      // grab views 
      mProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar); 
      mConnectIcon = (ImageView) view.findViewById(R.id.connect_icon); 

     } 

     @Override 
     public void onScanResult(int callbackType, ScanResult result) { 
      super.onScanResult(callbackType, result); 

      // grab a timestamp of when the scan starts 
      scanTimeStamp = SystemClock.uptimeMillis(); 

      // if its been 3 seconds, without scanning then stop 
      mElapsedTimeScanning = (scanTimeStamp - mStartScanTimeStamp)/1000; 
      // if the elapsed time is 3 seconds, then stop the scan 
      if (mElapsedTimeScanning >= 3) { 

       if (mConnectIcon.getVisibility() != View.VISIBLE) { 

        // if nothing was found, stop the circular progress bar and place the lightning bolt 
        mProgressBar.setVisibility(View.GONE); 
        mConnectIcon.setImageResource(R.drawable.ic_flash); 
        mConnectIcon.setVisibility(View.VISIBLE); 
        // clear out laser 
        ArrayList<Module> m = drill.getModules(); 
        m.get(position).setMACaddress(null); 

       } 

       mAdapter.notifyDataSetChanged(); 
       isConnected = false; 
       mBluetoothLEScanner.stopScan(this); 
      } else { 
       // grabbing important data from byte record 
       mHex = ConversionHelper 
         .bytesToHex(result.getScanRecord().getBytes()); 
       mLaserTime = ConversionHelper. 
         hex2decimal(mHex.substring(24, 32)); 
       mBeefMessage = mHex.substring(32, 36); 

      /* if there is no connection yet, and the beef message is preset, 
      and the laser time < 3 seconds, 
      and its atleast 3 seconds since another laser has advertised, 
      accept this new scan record as a potential new laser 
      */ 
       System.out.println("CONNECTION DELAY:" + (scanTimeStamp - connectTimeStamp)); 
       if (!isConnected 
         && ConversionHelper.hex2decimal(mBeefMessage) == 48879 
         && mLaserTime < 3000 
         && scanTimeStamp - connectTimeStamp > 3000) { 
        // set isConnected to true 
        isConnected = true; 

        // grab second timestamp - used so that people can't connect the same MAC for 2 lasers 
        connectTimeStamp = SystemClock.uptimeMillis(); 
        System.out.println("CONNECT TIME STAMP" + connectTimeStamp); 
        // set the MAC address of the laser 
        drill.setMAC(name, result.getDevice().getAddress()); 
        mAdapter.setCurrentMAC(result.getDevice().getAddress()); 
        mAdapter.notifyDataSetChanged(); 

        // check to see if this laser is connected to another position 




        // if the device finds a viable laser, replace the circular progress bar with a checkmark 
        mProgressBar.setVisibility(View.GONE); 
        mConnectIcon.setImageResource(R.drawable.ic_connected); 
        mConnectIcon.setVisibility(View.VISIBLE); 

        // notify the user that the start laser has been connected 
        Toast message = Toast.makeText(mContext, name + " Connected!", Toast.LENGTH_SHORT); 
        message.setGravity(Gravity.CENTER_VERTICAL, 0, 0); 
        message.show(); 




        isConnected = false; 
        mBluetoothLEScanner.stopScan(this); 

       } 

      } 
     } 

    } 


    public AutoConnectBLE(Context context) { 

     // grab context 
     mContext = context; 


     // grab BLE scanner 
     mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE); 
     mBluetoothAdapter = mBluetoothManager.getAdapter(); 
     mBluetoothLEScanner = mBluetoothAdapter.getBluetoothLeScanner(); 

     // set settings to LOW LATENCY 
     mSettings = new ScanSettings.Builder() 
       .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) 
       .build(); 


    } 



    public void scanLaser(View view,Drill drill ,String name, final AutoConnectFragment.LaserAdapter mAdapter, int position) { 

     mStartScanTimeStamp = SystemClock.uptimeMillis(); 
     mBluetoothLEScanner.startScan(new ArrayList<ScanFilter>(), mSettings,new laserCallBack(view, drill, name, mAdapter, position)); 

    } 

// public void scanRFID(final Drill drill, final String name, final View v, final Context context, final AutoConnectFragment.LaserAdapter mAdapter, final int position) { 
// 
//  final ScanCallback RFIDCallBack = new ScanCallback() { 
//   @Override 
//   public void onScanResult(int callbackType, ScanResult result) { 
//    super.onScanResult(callbackType, result); 
// 
//    // grab a timestamp 
//    scanTimeStamp = SystemClock.uptimeMillis(); 
// 
// 
//    String hex = ConversionHelper 
//      .bytesToHex(result.getScanRecord().getBytes()); 
//    String RFIDBeefMessage = hex.substring(36, 40); 
//    System.out.println(hex); 
// 
//    // if its been 3 seconds, without connecting then stop 
//    mElapsedTimeScanning = (scanTimeStamp - mStartScanTimeStamp)/1000; 
//    if (mElapsedTimeScanning == 3) { 
//     ImageView mConnectIcon = (ImageView) v.findViewById(R.id.connect_icon); 
//     if (mConnectIcon.getVisibility() != View.VISIBLE) { 
// 
//      // if nothing was found, stop the circular progress bar and place the lightning bolt 
//      ProgressBar mProgressBar = (ProgressBar) v.findViewById(R.id.progress_bar); 
//      mProgressBar.setVisibility(View.GONE); 
//      mConnectIcon.setImageResource(R.drawable.ic_flash); 
//      mConnectIcon.setVisibility(View.VISIBLE); 
// 
//     } 
//     System.out.println("STOPPED SCANNING"); 
//     mBluetoothLEScanner.stopScan(this); 
//     isConnected = false; 
//    } 
// 
//    // RFID 
//    if (!isConnected && RFIDBeefMessage.equals("BEEF")) { 
//     isConnected = true; 
//     mBluetoothLEScanner.stopScan(this); 
// 
//     // set the MAC address of the laser 
//     String MACAddress = result.getDevice().getAddress(); 
//     drill.setMAC(name, MACAddress); 
//     // notify the user that the start laser has been connected 
// 
//     // if the device finds a viable laser, replace the circular progress bar with a checkmark 
//     ImageView mConnectIcon = (ImageView) v.findViewById(R.id.connect_icon); 
//     ProgressBar mProgressBar = (ProgressBar) v.findViewById(R.id.progress_bar); 
//     mProgressBar.setVisibility(View.GONE); 
//     mConnectIcon.setImageResource(R.drawable.ic_connected); 
//     mConnectIcon.setVisibility(View.VISIBLE); 
//     Toast message = Toast.makeText(context, name + " Connected!", Toast.LENGTH_SHORT); 
//     message.setGravity(Gravity.CENTER_VERTICAL, 0, 0); 
//     message.show(); 
// 
//    } 
// 
//   } 
// 
//  }; 
//  mStartScanTimeStamp = SystemClock.uptimeMillis(); 
//  mBluetoothLEScanner.startScan(new ArrayList<ScanFilter>(), mSettings, RFIDCallBack); 
// 
// 
// } 


} 
+0

這部分代碼是正確的,我們使用相同的方式,它運作良好。你應該發佈你的活動/片段的完整代碼。 –

+0

你在你的片段中使用這段代碼?因爲當我在活動中使用它時,它工作正常,但將它分段根本不起作用。 –

+0

是的,它是片段 –

回答

1

下面的代碼使用,使你的藍牙

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 

     if(!mBluetoothAdapter.isEnabled()){ 
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity()); 
     alertBuilder.setCancelable(true); 
     alertBuilder.setMessage("Do you want to enable bluetooth"); 
     alertBuilder.setNeutralButton("OK", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       dialog.dismiss(); 
       mBluetoothAdapter.enable(); 
      } 
     }); 
     AlertDialog alert = alertBuilder.create(); 
     alert.show(); 
     } 
+0

我想能夠有一個對話框要求用戶打開藍牙 –

+0

@JonSherman我已經編輯我的代碼現在檢查 –

0

只需添加一個清單權限藍牙訪問。

<uses-permission android:name="android.permission.BLUETOOTH"/> 

並將此片段添加到片段中,以獲得運行時權限限制。

if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.BLUETOOTH) 
      != PackageManager.PERMISSION_GRANTED) 
    { 
     ActivityCompat.requestPermissions(((Activity)getContext()), 
       new String[]{Manifest.permission.BLUETOOTH}, REQUEST_CODE); 
    } 

該代碼段會自動啓動藍牙訪問警報。