Buenas tardes.
In the development of an app with bluetooth connectivity, a small problem has arisen, since I have never worked with fragments, and I see them as somewhat complicated.
From the main window, I start a new fragment with a button. This button when pressed will send a character via bluetooth. The problem is how I can access the socket that I have created in the main to write that character.
From the main one I have no problem doing it, it sends the character, but when I go to that other fragment, from its .java, I can't find a way to access the socket, and it doesn't let me send it by parameter either, since it tells me that the fragments must have an empty constructor...
THANK YOU!
EDIT:
Main code, which connects perfectly and establishes a socket:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, AsientosFragment.OnFragmentInteractionListener,ComplementosFragment.OnFragmentInteractionListener,OpcionesFragment.OnFragmentInteractionListener {
TextView txtlink;
TextView txtnombre1;
TextView txtnombre;
TextView txtestado1;
TextView txtestado;
BluetoothAdapter bAdapter;
UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothDevice device;
ThreadConnectBTdevice myThreadConnectBTdevice;
ThreadConnected myThreadConnected;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("AudioBus Bluetooth Controller");
txtlink=(TextView)findViewById(R.id.txtlink);
txtnombre1=(TextView)findViewById(R.id.txtnombre1);
txtnombre=(TextView)findViewById(R.id.txtnombre);
txtestado1=(TextView)findViewById(R.id.txtestado1);
txtestado=(TextView)findViewById(R.id.txtestado);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
// .setAction("Action", null).show();
finish();
System.exit(0);
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
bAdapter = BluetoothAdapter.getDefaultAdapter();
device = bAdapter.getRemoteDevice(getIntent().getExtras().getString("MAC"));
setup();
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
public void abrir(View view){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.audiobus.com"));
startActivity(intent);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
txtestado.setText("");
txtestado1.setText("");
txtnombre1.setText("");
txtnombre.setText("");
Fragment fragment=null;
Boolean FragmentoSeleccionado=false;
int id = item.getItemId();
if (id == R.id.asientos) {
fragment=new AsientosFragment();
FragmentoSeleccionado=true;
} else if (id == R.id.complementos) {
fragment=new ComplementosFragment();
FragmentoSeleccionado=true;
} else if (id == R.id.opciones) {
fragment=new OpcionesFragment();
FragmentoSeleccionado=true;
}
if (FragmentoSeleccionado) {
getSupportFragmentManager().beginTransaction().replace(R.id.Contenedor,fragment).commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
public void onFragmentInteraction(Uri uri) {
}
public void enviarAsientos(View view) {
if (myThreadConnected != null) {
byte[] envio = "Asientos".getBytes();
myThreadConnected.write(envio);
}
}
public void enviarComplementos(View view) {
if (myThreadConnected != null) {
byte[] envio = "Complementos".getBytes();
myThreadConnected.write(envio);
}
}
public void enviarOpciones(View view) {
if (myThreadConnected != null) {
byte[] envio = "Opciones".getBytes();
myThreadConnected.write(envio);
}
}
public void setup() {
bAdapter.cancelDiscovery();
txtestado.setText("Conectando...");
txtnombre.setText(device.getName());
myThreadConnectBTdevice = new ThreadConnectBTdevice(device);
myThreadConnectBTdevice.start();
}
private void startThreadConnected(BluetoothSocket socket) {
myThreadConnected = new ThreadConnected(socket);
myThreadConnected.start();
}
private class ThreadConnectBTdevice extends Thread{
BluetoothSocket bluetoothSocket=null;
final BluetoothDevice bluetoothDevice;
private ThreadConnectBTdevice (BluetoothDevice device){
bluetoothDevice=device;
try {
bluetoothSocket=device.createRfcommSocketToServiceRecord(MY_UUID);
txtestado.setText("BTSOCKET: "+bluetoothSocket);
}catch (Exception e){
System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
e.printStackTrace();
}
}
@Override
public void run() {
boolean succes=false;
try{
bluetoothSocket.connect();
succes=true;
}catch(Exception e){
System.out.println("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ");
runOnUiThread(new Runnable() {
@Override
public void run() {
txtestado.setText("Fallo en la conexion...");
}
});
e.printStackTrace();
}
if (succes){
runOnUiThread(new Runnable() {
@Override
public void run() {
txtestado.setText("¡Conectado!");
}
});
startThreadConnected(bluetoothSocket);
}else{
runOnUiThread(new Runnable() {
@Override
public void run() {
txtestado.setText("Intente la conexion en otro momento");
}
});
}
}
}
private class ThreadConnected extends Thread{
final BluetoothSocket connectedBluetoothSocket;
final InputStream connectedInputStream;
final OutputStream connectedOutputStream;
public ThreadConnected(BluetoothSocket socket){
connectedBluetoothSocket=socket;
InputStream in=null;
OutputStream out=null;
try{
in=socket.getInputStream();
out=socket.getOutputStream();
}catch (Exception e){
System.out.println("PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP");
e.printStackTrace();
}
connectedInputStream=in;
connectedOutputStream=out;
}
@Override
public void run() {
byte[] buffer=new byte[1024];
int bytes;
while(true){
try{
/* bytes=connectedInputStream.read(buffer);
String recibida=new String(buffer,0,bytes);
System.out.println("RECIBO: "+recibida);
*/
}catch(Exception e){
System.out.println("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE");
e.printStackTrace();
}
}
}
public void write(byte[] buffer){
try{
connectedOutputStream.write(buffer);
}catch(Exception e){
System.out.println("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT");
e.printStackTrace();
}
}
}
}
Fragment from which I want to send using the established socket:
public class AsientosFragment extends Fragment implements View.OnClickListener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
Button btnup;
Button btndown;
Button btnrear;
Button btnfront;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public AsientosFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static AsientosFragment newInstance(String param1, String param2) {
AsientosFragment fragment = new AsientosFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
System.out.println("AQUIIIIII");
View view=inflater.inflate(R.layout.fragment_asientos,container,false);
btnup=(Button)view.findViewById(R.id.btnup);
btndown=(Button)view.findViewById(R.id.btndown);
btnrear=(Button)view.findViewById(R.id.btnrear);
btnfront=(Button)view.findViewById(R.id.btnfront);
btnup.setOnClickListener(this);
btndown.setOnClickListener(this);
btnrear.setOnClickListener(this);
btnfront.setOnClickListener(this);
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btnup:
System.out.println("AAAAAAAAAAAAA");
break;
case R.id.btndown:
System.out.println("BBBBBBBBBBBBBB");
break;
case R.id.btnrear:
break;
case R.id.btnfront:
break;
}
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
getActivity() on the fragment gives you a reference to the containing activity . By casting this reference to our MainActivity we have access to its public attributes and methods .
For example, if in MainActivity there is a getLevel() method, in the fragment we can put: