我一直在寻找,我无法找到答案。我只是想在我的片段中启用蓝牙。我将以下内容添加到我的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 :(得分:2)
使用以下代码启用蓝牙功能
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();
}
答案 1 :(得分: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);
}
该代码段会自动启动蓝牙访问警报。
答案 2 :(得分:0)
首先获取BluetoothAdapter对象
BluetoothAdapter adapter = BluetoothAdapter.getDefaultBluetoothAdapter();
if(adapter != null){
adapter.enable();
}
使用上面的代码,您可以在没有用户许可的情况下启用蓝牙。我希望此代码可以帮助您