问题遇到的现象和发生背景
只学过一点Android Studio的皮毛,该代码由https://github.com/kai-morich/SimpleBluetoothTerminal修改而来,现有一父Fragment及3个子Fragment,求教于进入父Fragment并连接上蓝牙之后,子Fragment该如何直接调用蓝牙
问题相关代码,请勿粘贴截图
package de.kai_morich.simple_bluetooth_terminal;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
public class TabPageActivity extends Fragment implements RadioGroup.OnCheckedChangeListener, ServiceConnection, SerialListener {
private String deviceAddress;
private Fragment fg1,fg2,fg3;
private RadioGroup rg_tab_bar;
private RadioButton rb_control;
private enum Connected { False, Pending, True }
private SerialService service;
private TextView receiveText;
private TextView sendText;
private TextUtil.HexWatcher hexWatcher;
private Connected connected = Connected.False;
private boolean initialStart = true;
private boolean hexEnabled = false;
private boolean pendingNewline = false;
private String newline = TextUtil.newline_crlf;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
setRetainInstance(true);
deviceAddress = getArguments().getString("device");
}
@Override
public void onDestroy() {
if (connected != Connected.False)
disconnect();
getActivity().stopService(new Intent(getActivity(), SerialService.class));
super.onDestroy();
}
@Override
public void onStart() {
super.onStart();
if(service != null)
service.attach(this);
else
getActivity().startService(new Intent(getActivity(), SerialService.class)); // prevents service destroy on unbind from recreated activity caused by orientation change
}
@Override
public void onStop() {
if(service != null && !getActivity().isChangingConfigurations())
service.detach();
super.onStop();
}
@SuppressWarnings("deprecation") // onAttach(context) was added with API 23. onAttach(activity) works for all API versions
@Override
public void onAttach(@NonNull Activity activity) {
super.onAttach(activity);
getActivity().bindService(new Intent(getActivity(), SerialService.class), this, Context.BIND_AUTO_CREATE);
}
@Override
public void onDetach() {
try { getActivity().unbindService(this); } catch(Exception ignored) {}
super.onDetach();
}
@Override
public void onResume() {
super.onResume();
if(initialStart && service != null) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((SerialService.SerialBinder) binder).getService();
service.attach(this);
if(initialStart && isResumed()) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
service = null;
}
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab_page, container, false);
rg_tab_bar = (RadioGroup)view.findViewById(R.id.rg_tab_bar);
rg_tab_bar.setOnCheckedChangeListener(this);
//获取第一个单选按钮,并设置其为选中状态
rb_control = (RadioButton)view.findViewById(R.id.rb_control);
rb_control.setChecked(true);
return view;
}
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i) {
case R.id.rb_control:
if (fg1 == null) {
Bundle args = new Bundle();
args.putString("device", deviceAddress);
fg1 = new ButtonFragment(); //載入序列埠之Layout
fg1.setArguments(args);
getChildFragmentManager().beginTransaction().replace(R.id.fragment2, fg1, "control").addToBackStack(null).commit();
} else {
getChildFragmentManager().beginTransaction().replace(R.id.fragment2, fg1, "control").addToBackStack(null).commit();
}
break;
case R.id.rb_making:
if (fg2 == null) {
Bundle args = new Bundle();
args.putString("device", deviceAddress);
fg2 = new MakingActivity(); //載入序列埠之Layout
fg2.setArguments(args);
getChildFragmentManager().beginTransaction().replace(R.id.fragment2, fg2, "making").addToBackStack(null).commit();
} else {
getChildFragmentManager().beginTransaction().replace(R.id.fragment2, fg2, "making").addToBackStack(null).commit();
}
break;
case R.id.rb_serial:
if (fg3 == null) {
Bundle args = new Bundle();
args.putString("device", deviceAddress);
fg3 = new TerminalFragment(); //載入序列埠之Layout
fg3.setArguments(args);
getChildFragmentManager().beginTransaction().replace(R.id.fragment2, fg3, "serial").addToBackStack(null).commit();
} else {
getChildFragmentManager().beginTransaction().replace(R.id.fragment2, fg3, "serial").addToBackStack(null).commit();
}
break;
}
}
/*
* Serial + UI
*/
private void connect() {
try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
Toast.makeText(getActivity(), "connecting...", Toast.LENGTH_SHORT).show();
connected = Connected.Pending;
SerialSocket socket = new SerialSocket(getActivity().getApplicationContext(), device);
service.connect(socket);
} catch (Exception e) {
onSerialConnectError(e);
}
}
private void disconnect() {
connected = Connected.False;
service.disconnect();
}
/*
* SerialListener
*/
@Override
public void onSerialConnect() {
Toast.makeText(getActivity(), "connected", Toast.LENGTH_SHORT).show();
connected = Connected.True;
}
@Override
public void onSerialConnectError(Exception e) {
disconnect();
}
@Override
public void onSerialRead(byte[] data) {
}
@Override
public void onSerialIoError(Exception e) {
Toast.makeText(getActivity(), "connection lost", Toast.LENGTH_SHORT).show();
disconnect();
}
}