Pergunta

Um pouco sobre minha configuração atual:

Atualmente tenho um programa Android dividido em vários fragmentos diferentes.O fragmento inicial procura uma conexão Bluetooth com um endereço MAC específico e UUID de soquete.Esta conexão funciona bem (ainda não há problema).

O servidor de transmissão Bluetooth é um beaglebone black que está executando o Ubuntu e utiliza bluez para transmitir um serviço específico com um UUID específico.

Problema:Quando mudo para o fragmento da galeria, tento usar o serviço Bluetooth já conectado para enviar dados (fotos).

Onde tenho problemas é com o comando outputStream.write(msgBuffer);.Ele retorna com um erro "nulo".

Até agora, para depuração, fiz o seguinte:

Fiquei curioso para ver se a conexão original funcionou (no fragmento inicial), então, depois de me conectar ao servidor Bluetooth com uma chamada para connect(), testei-a com uma chamada para socket.getConnected().Isso retornou verdadeiro, o que significa que o soquete Bluetooth deve estar conectado ao servidor Bluetooth.

Queria então ver o que estava acontecendo no fragmento da galeria.Antes de enviar meus dados com o outputStream.write(msgBuffer);comando, executei socket.getConnected() que retornou falso.Assim, significa que a tomada deve ser desconectada.... Por que o servidor Bluetooth está desconectado agora?Preciso fazer algo especial para manter a conexão Bluetooth aberta?Preciso fazer algo especial para manter a conexão ativa ao trocar fragmentos?

O que estaria causando a desconexão da minha conexão no intervalo entre esses dois eventos?

Abaixo estão meus dois fragmentos.

Fragmento inicial

    package edu.umass.ecs.chalkmaster3000;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Fragment;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;  
import java.io.IOException;
import java.util.UUID;

/**
 * Created by Oskoss on 11/16/13.
 */
public class HomeFragment extends Fragment {

    public static final int BT_ACTIVITY = 5;
    public int i;

    ActivityCommunication activityCallback;

    public interface ActivityCommunication{
        public void updateColors(int color);
        public String getAddress();
        public UUID getUUID();
        public BluetoothSocket getBTSocket();
        public BluetoothAdapter getBTAdapter();
        public void setConnectionStatus(boolean status);
        public boolean getConnectionStatus();
        public View getView(int viewID);
        public Context getContext();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            activityCallback = (ActivityCommunication) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement ActivityCommunication");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
       View V = inflater.inflate(R.layout.home_fragment,container,false);
        ImageView robotImage = (ImageView) V.findViewById(R.id.robotStatus);
        ImageButton staticRobotImage = (ImageButton) V.findViewById(R.id.button);
        TextView status = (TextView) V.findViewById(R.id.textView_Status);
        if(activityCallback.getConnectionStatus()){
            V.setBackgroundColor(getResources().getColor(R.color.blue));
            activityCallback.updateColors(1);
            activityCallback.setConnectionStatus(true);

            status.setText("Bluetooth Connected to Dusty!");
            robotImage.setImageResource(R.drawable.happy_dusty);
            Animation pulse = AnimationUtils.loadAnimation(activityCallback.getContext(), R.anim.pulse);
            robotImage.startAnimation(pulse);
        }
        else{
           //checkBTStates();
            if(BluetoothAdapter.getDefaultAdapter()==null){
                V.setBackgroundColor(getResources().getColor(R.color.orange));
                staticRobotImage.setImageResource(R.drawable.sad_dusty);
                //robotImage.setImageResource(R.drawable.sad_dusty);
                status.setText("Your phone has no Bluetooth :/!");
                activityCallback.updateColors(0);
                activityCallback.setConnectionStatus(false);
            }
            else{
                V.setBackgroundColor(getResources().getColor(R.color.red));
                staticRobotImage.setImageResource(R.drawable.sad_dusty);
                //robotImage.setImageResource(R.drawable.sad_dusty);
                activityCallback.updateColors(2);
                activityCallback.setConnectionStatus(false);
            }

            final ImageButton button = (ImageButton) V.findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    checkBTStates();
                }
            });
        }
        return V;
    }

    private void checkBTStates() {
        BluetoothAdapter btAdapter = activityCallback.getBTAdapter();
        View currentView = activityCallback.getView(R.id.home_fragment);
        ImageButton staticRobotImage = (ImageButton) getView().findViewById(R.id.button);
        TextView status = (TextView) getView().findViewById(R.id.textView_Status);
        // Check for Bluetooth support and then check to make sure it is turned on
        if(btAdapter==null) {
            status.setText("Fatal Error: Bluetooth doesn't seem to be supported on your device! :(");
            staticRobotImage.setImageResource(R.drawable.sad_dusty);
            //Toast toast = Toast.makeText(activityCallback.getContext(), "Fatal Error: Bluetooth doesn't seem to be supported on your device! :(", Toast.LENGTH_LONG);
            //toast.show();
            currentView.setBackgroundColor(getResources().getColor(R.color.orange));
            activityCallback.updateColors(0);
            activityCallback.setConnectionStatus(false);
           //robotImage.setImageResource(R.drawable.sad_dusty);
        }
        else {
                if (btAdapter.isEnabled()) {
                    connectBT();
                    }
                else {
                        //Prompt user to turn on Bluetooth
                        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(enableBtIntent, BT_ACTIVITY);
                }
        }
    }

    public String address = "00:02:72:3F:86:B3";

    final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
    public  BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
    // Set up a pointer to the remote node using it's address.
    BluetoothDevice device = btAdapter.getRemoteDevice(address);
    BluetoothSocket btSocket = null;



    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private void connectBT(){
        ImageButton staticRobotImage = (ImageButton) getView().findViewById(R.id.button);
        TextView status = (TextView) getView().findViewById(R.id.textView_Status);
        try {
            btSocket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            status.setText("Fatal Error in onResume() and socket create failed");
            //Toast toast = Toast.makeText(activityCallback.getContext(), "Fatal Error in onResume() and socket create failed: " + e.getMessage() + ".", Toast.LENGTH_LONG);
            //toast.show();
        }

        View currentView = activityCallback.getView(R.id.home_fragment);
        ImageView robotImage = (ImageView) activityCallback.getView(R.id.robotStatus);


        // Two things are needed to make a connection:
        //   A MAC address, which we got above.
        //   A Service ID or UUID.  In this case we are using the
        //     UUID for SPP.


        // Discovery is resource intensive.  Make sure it isn't going on
        // when you attempt to connect and pass your message.
        btAdapter.cancelDiscovery();

        // Establish the connection.  This will block until it connects.
        try {
            btSocket.connect();
            if(btSocket.isConnected()){

            Toast toast = Toast.makeText(activityCallback.getContext(), "socket is connected", Toast.LENGTH_LONG);
            toast.show();
            }
            currentView.setBackgroundColor(getResources().getColor(R.color.blue));
            activityCallback.updateColors(1);
            activityCallback.setConnectionStatus(true);
            ImageButton connect = (ImageButton) getView().findViewById(R.id.button);
            ViewGroup layout = (ViewGroup) connect.getParent();
            status.setText("Bluetooth Connected to Dusty!");
            robotImage.setImageResource(R.drawable.happy_dusty);
            Animation pulse = AnimationUtils.loadAnimation(activityCallback.getContext(), R.anim.pulse);
            robotImage.startAnimation(pulse);
            if(null!=layout) //for safety only  as you are doing onClick
              layout.removeView(connect);

        } catch (IOException e) {
            try {
                staticRobotImage.setImageResource(R.drawable.sad_dusty);
                currentView.setBackgroundColor(getResources().getColor(R.color.orange));
                activityCallback.updateColors(0);
                //robotImage.setImageResource(R.drawable.sad_dusty);
                status.setText("No Bluetooth server broadcasting to connect to....");
                activityCallback.setConnectionStatus(false);
                //Toast toast = Toast.makeText(activityCallback.getContext(),"No Bluetooth server broadcasting to connect to....", Toast.LENGTH_LONG);
                //toast.show();
                btSocket.close();
            } catch (IOException e2) {
                status.setText("Fatal Error in onResume() and unable to close socket during connection failure");
                //Toast toast = Toast.makeText(activityCallback.getContext(),"Fatal Error in onResume() and unable to close socket during connection failure" + e2.getMessage() + ".", Toast.LENGTH_LONG);
                //toast.show();
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        TextView status = (TextView) getView().findViewById(R.id.textView_Status);
        ImageButton staticRobotImage = (ImageButton) getView().findViewById(R.id.button);
        super.onActivityResult(requestCode, resultCode, data);
        View currentView = activityCallback.getView(R.id.home_fragment);
        switch(requestCode){
            case BT_ACTIVITY:
                if(resultCode == -1){
                    i = 50; //Stop asking the user to enable bluetooth
                    status.setText("Bluetooth is now on!");
                    connectBT();
                    Toast.makeText(activityCallback.getContext(), "Bluetooth is now on!", Toast.LENGTH_SHORT).show();
                }
                else if(resultCode == 0){
                    staticRobotImage.setImageResource(R.drawable.sad_dusty);
                    currentView.setBackgroundColor(getResources().getColor(R.color.red));
                    activityCallback.updateColors(2);
                    //robotImage.setImageResource(R.drawable.sad_dusty);
                    activityCallback.setConnectionStatus(false);
                    status.setText("This application requires Bluetooth...Maybe try to turn it on?! ;)");
                    //Toast toast = Toast.makeText(activityCallback.getContext(), "This application requires Bluetooth...Maybe try to turn it on?! ;)", Toast.LENGTH_LONG);
                    //toast.show();
                }
            break;
        }
    }
}

Fragmento da Galeria

 package edu.umass.ecs.chalkmaster3000;


import android.widget.CheckBox;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;



public class GalleryFragment extends Fragment {
    private int count;
    int id;
    private Bitmap[] thumbnails;
    private boolean[] thumbnailsselection;
    private String[] arrPath;
    private ImageAdapter imageAdapter;
    public OutputStream outStream = null;
    public ViewGroup container1 = null;

    ActivityCommunication activityCallback;

    public interface ActivityCommunication{
        public String getAddress();
        public UUID getUUID();
        public BluetoothSocket getBTSocket();
        public boolean getConnectionStatus();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            activityCallback = (ActivityCommunication) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement ActivityCommunication");
        }
    }
    /** Called when the activity is first created. */
    @Override
    public View onCreateView(LayoutInflater inflater,  ViewGroup container, Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        container1 = container;
        View V = inflater.inflate(R.layout.gallery, container, false);
        final String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID };
        final String orderBy = MediaStore.Images.Media._ID;
        Cursor imagecursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                columns,
                MediaStore.Images.Media.DATA + " like ? ",
                new String[]{"%/Robo Pics/%"},
                null);

        int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID);
        this.count = imagecursor.getCount();
        this.thumbnails = new Bitmap[this.count];
        this.arrPath = new String[this.count];
        this.thumbnailsselection = new boolean[this.count];
        for (int i = 0; i < this.count; i++) {
            imagecursor.moveToPosition(i);
            id = imagecursor.getInt(image_column_index);
            int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);
            thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
                    getActivity().getContentResolver(), id,
                    MediaStore.Images.Thumbnails.MICRO_KIND, null);
            arrPath[i]= imagecursor.getString(dataColumnIndex);
        }
        GridView imagegrid = (GridView) V.findViewById(R.id.PhoneImageGrid);
        imageAdapter = new ImageAdapter();
        imagegrid.setAdapter(imageAdapter);

        final Button selectBtn = (Button) V.findViewById(R.id.selectBtn);
        final Button previewBtn = (Button) V.findViewById(R.id.previewBtn);
        final Button deleteBtn = (Button) V.findViewById(R.id.deleteBtn);
        selectBtn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                if(activityCallback.getConnectionStatus()){
                    // TODO Auto-generated method stub
                    final int len = thumbnailsselection.length;
                    int cnt = 0;
                    String selectImages = "";

                    for (int i =0; i<len; i++)
                    {
                        if (thumbnailsselection[i]){
                            cnt++;
                            selectImages = selectImages + arrPath[i];
                        }
                    }
                    if (cnt == 0){
                        Toast.makeText(getActivity(),
                                "Dusty can't draw anything unless you select an image! Sadface",
                                Toast.LENGTH_LONG).show();
                    }
                    else if(cnt>1){
                        Toast.makeText(getActivity(),
                                "Dusty is amazing but he can't draw two images at one time! Sadface",
                                Toast.LENGTH_LONG).show();
                    }
                    else {
                           byte sendArray[] = readBytes(selectImages);
                           sendBTData(sendArray);
                    }
                }
                else
                    Toast.makeText(getActivity(), "You need to first connect to Dusty!", Toast.LENGTH_LONG).show();
            }
        });

        previewBtn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                    final int len = thumbnailsselection.length;
                    int cnt = 0;
                    String selectImages = "";

                    for (int i =0; i<len; i++)
                    {
                        if (thumbnailsselection[i]){
                            cnt++;
                            selectImages = selectImages + arrPath[i];
                        }
                    }
                    if (cnt == 0){
                        Toast.makeText(getActivity(),
                                "There is nothing to preview! Sadface",
                                Toast.LENGTH_LONG).show();
                    }
                    else if(cnt>1){
                        Toast.makeText(getActivity(),
                                "You can't preview more than one thing! Silly",
                                Toast.LENGTH_LONG).show();
                    }
                    else {
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        intent.setDataAndType(Uri.parse("file://" + selectImages), "image/*");
                        startActivity(intent);
                    }
            }
        });

        deleteBtn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                    final int len = thumbnailsselection.length;
                    int cnt = 0;
                    String[] storage = new String[len];

                    for (int i =0; i<len; i++)
                    {
                        if (thumbnailsselection[i]){
                            cnt++;
                            storage[i] = arrPath[i];
                        }
                    }
                    if (cnt == 0){
                        Toast.makeText(getActivity(),
                                "Can't delete nothing! Silly",
                                Toast.LENGTH_LONG).show();
                    }
                    else{
                        AlertDialog diaBox = AskOption(storage);
                        diaBox.show();


                    }
            }
        });
      return V;
    }

    public class ImageAdapter extends BaseAdapter {
        private LayoutInflater mInflater;

        public ImageAdapter() {
            mInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        public int getCount() {
            return count;
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = mInflater.inflate(
                        R.layout.galleryitem, null);
                holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
                holder.checkbox = (CheckBox) convertView.findViewById(R.id.yup123);

                convertView.setTag(holder);
            }
            else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.checkbox.setId(position);
            holder.imageview.setId(position);
            holder.checkbox.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    CheckBox cb = (CheckBox) v;
                    int id = cb.getId();
                    if (thumbnailsselection[id]){
                        cb.setChecked(false);
                        thumbnailsselection[id] = false;
                    } else {
                        cb.setChecked(true);
                        thumbnailsselection[id] = true;
                    }
                }
            });
            holder.imageview.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    RelativeLayout row = (RelativeLayout) v.getParent();
                    CheckBox cb = (CheckBox) row.getChildAt(2);
                    id=cb.getId();
                    if (thumbnailsselection[id]) {
                        cb.setChecked(false);
                        thumbnailsselection[id] = false;
                    } else {
                        cb.setChecked(true);
                        thumbnailsselection[id] = true;
                    }
                }
            });
            holder.imageview.setImageBitmap(thumbnails[position]);
            holder.checkbox.setChecked(thumbnailsselection[position]);
            holder.id = position;
            return convertView;
        }
    }
    class ViewHolder {
        ImageView imageview;
        CheckBox checkbox;
        int id;
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private void sendBTData(byte[] msgBuffer){
        String address = activityCallback.getAddress();
        UUID MY_UUID = activityCallback.getUUID();
        BluetoothSocket btSocket = activityCallback.getBTSocket();
        try {
            btSocket.connect();

        } catch (IOException e) {
            try {
                e.printStackTrace();
                btSocket.close();
            } catch (IOException e2) {
                    e2.printStackTrace();
            }
        }

        // Create a data stream so we can talk to server.
        Toast toast1 = Toast.makeText(getActivity(),"Sending message to server...", Toast.LENGTH_LONG);
        toast1.show();

        try {
            outStream = btSocket.getOutputStream();
        } catch (IOException e) {

            Toast toast = Toast.makeText(getActivity(),"Fatal Error in onResume() and output stream creation failed:" + e.getMessage() + ".", Toast.LENGTH_LONG);
            toast.show();
        }

        try {
            if(btSocket.isConnected()){

                Toast toast = Toast.makeText(getActivity(), "socket is connected", Toast.LENGTH_LONG);
                toast.show();
            }
            else{
                Toast toast = Toast.makeText(getActivity(), "NOT CONNECTEDDDDDD", Toast.LENGTH_LONG);
                toast.show();
            }
            outStream.write(msgBuffer);
            Toast.makeText(getActivity(), "Images are now being sent through outter space to Robo for drawing!" , Toast.LENGTH_LONG).show();
        } catch (Throwable e) {
            String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
            e.printStackTrace();
            if (address.equals("00:00:00:00:00:00")) {
                msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on line 37 in the java code";
            }
            else{
                msg = msg +  ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";
            }
            Toast toast = Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG);
            toast.show();
        }
    }

    public byte[] readBytes(String filePath){
        BitmapFactory cute = new BitmapFactory();
        Bitmap picSend = cute.decodeFile(filePath);
        ByteArrayOutputStream stream1 = new ByteArrayOutputStream();
        picSend.compress(Bitmap.CompressFormat.PNG, 100, stream1);
        byte picByteSend[] = stream1.toByteArray();
        return picByteSend;

    }
    public AlertDialog AskOption(final String[] toBeDeleted)
    {
        AlertDialog myQuittingDialogBox =new AlertDialog.Builder(getActivity())
                //set message, title, and icon
                .setTitle("Delete Confirmation")
                .setMessage("Are you sure you want to delete the selected pictures?")
                .setIcon(R.drawable.new_pic)

                .setPositiveButton("Delete", new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        for (int i = 0; i < toBeDeleted.length; i++) {
                            if (toBeDeleted[i] != null) {
                                File f = new File(toBeDeleted[i]);
                                if (f.exists()) {
                                    if (f.delete()) {

                                        Log.w("DELETED", "file Deleted");
                                    } else {
                                        Log.w("NOT DELETED", "file not Deleted");
                                    }
                                }
                            }

                            getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
                                    Uri.parse("file://" + Environment.getExternalStorageDirectory())));
                            FragmentManager manager = getActivity().getFragmentManager();
                            FragmentTransaction ft = manager.beginTransaction();
                            Fragment newFragment = getFragmentManager().findFragmentByTag("gallery");;
                            newFragment.onDestroy();
                            ft.remove(newFragment);
                            ft.replace(container1.getId(),newFragment);
                            //container is the ViewGroup of current fragment
                            ft.addToBackStack(null);
                            ft.commit();
                        }
                        dialog.dismiss();
                    }

                })

                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();

                    }
                })
                .create();

        return myQuittingDialogBox;

    }
}

Como sempre, obrigado!

Editar% s:

Tentei limpar isso um pouco.Se você não entende isso, pode me dizer o que não entende para que eu possa fornecer mais informações?

Foi útil?

Solução

Eu não estava passando os soquetes corretamente entre os fragmentos e, portanto, abri vários soquetes... precisei fazer uma pausa no projeto para perceber um erro tão bobo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top