android - fragment 中的蓝牙启用 Intent

标签 android bluetooth-lowenergy android-bluetooth

我到处找,找不到答案。我只是想在我的 fragment 中启用蓝牙。我在 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 自动连接 Scanner 类:

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);
//
//
//    }


}

最佳答案

使用下面的代码启用你的蓝牙

 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();
       }

关于android - fragment 中的蓝牙启用 Intent ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44954047/

相关文章:

android - 在 Marshmallow 中使用蓝牙扫描定位精度

android - 尽管尝试了教程,但蓝牙设备未连接到 Android 应用程序

android - 在 Android 中伪造应用程序崩溃

android - 主源集中的重构不会传播到非 Activity 构建变体

ios - 核心蓝牙 : How can the peripheral manager know that the central received an indication?

ubuntu - hcitool lescan 不适用于蓝牙版本 5

android - 具有rxBinding的setOnSeekBarChangeListener

android - 以编程方式膨胀底部导航 View 菜单

java - Android Studio 不兼容的类型

android - 蓝牙聊天示例