Autore Topic: [Bluetooth] Scan dei dispositivi  (Letto 1297 volte)

Offline stefano861

  • Nuovo arrivato
  • *
  • Post: 9
  • Respect: 0
    • Mostra profilo
[Bluetooth] Scan dei dispositivi
« il: 16 Marzo 2014, 15:06:28 CET »
0
Ciao a tutti, stavo cercando di creare una chat che funziona col Bluetooth. Ho visto il sample e (non volendolo copiare pari pari, anzi, per essere più sinceri, non avendolo capito per niente o quasi) ho iniziato a scrivere codice leggendo il tutorial che c'è qui Bluetooth | Android Developers.
Fin'ora appena apro l'app questa guarda che il bluetooth è attivo, se non lo è lo attiva. Ho creato poi un bottone nel file xml e a questo volevo associare la ricerca dei dispositivi con il bluetooth attivato che sono nelle vicinanze. Il metodo che si occupa di fare cioò è scanForDevices.
Questo metodo non funziona, appena lo clicco l'app si blocca in modo anomalo.

Dove pensate sia il problema?
Grazie mille per qualsiasi consiglio/aiuto :)

Codice (Java): [Seleziona]
import java.util.Set;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks {
       
    // Intent request codes
    private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
    private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
    private static final int REQUEST_ENABLE_BT = 3;

    // Message types sent from the BluetoothChatService Handler
    public static final int MESSAGE_STATE_CHANGE = 1;
    public static final int MESSAGE_READ = 2;
    public static final int MESSAGE_WRITE = 3;
    public static final int MESSAGE_DEVICE_NAME = 4;
    public static final int MESSAGE_TOAST = 5;

    // Key names received from the BluetoothChatService Handler
    public static final String DEVICE_NAME = "device_name";
    public static final String TOAST = "toast";

    // Layout Views
    private ListView mConversationView;
    private EditText mOutEditText;
    private Button mSendButton;
   
    // Name of the connected device
    private String mConnectedDeviceName = null;
    // Array adapter for the conversation thread
    private ArrayAdapter<String> mConversationArrayAdapter;
    // String buffer for outgoing messages
    private StringBuffer mOutStringBuffer;
    // Local Bluetooth adapter
    private BluetoothAdapter mBluetoothAdapter = null;
    // Member object for the chat services
    //private BluetoothChatService mChatService = null;
       
    /**
     * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
     */

    private NavigationDrawerFragment mNavigationDrawerFragment;

    /**
     * Used to store the last screen title. For use in {@link #restoreActionBar()}.
     */

    private CharSequence mTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        // Set up the window layout
        setContentView(R.layout.activity_main);

        mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        mTitle = getTitle();

        // Set up the drawer.
        mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
                (DrawerLayout) findViewById(R.id.drawer_layout));
       
        // Get local Bluetooth adapter
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        // If the adapter is null, then Bluetooth is not supported
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, "Your device doesn't support Bluetooth.", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
    }

    @Override
    public void onStart() {
        super.onStart();
       
        // If bluetooth is not on, request that it be enabled.
        // setupChat() will then be called during onActivityResult
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        }
        // Otherwise, setup the chat session
        else {
            if (mChatService == null)
                setupChat();
        }
    }

    @Override
    public synchronized void onResume() {
        super.onResume();

        // Performing this check in onResume() covers the case in which BT was
        // not enabled during onStart(), so we were paused to enable it...
        // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
        if (mChatService != null) {
            // Only if the state is STATE_NONE, do we know that we haven't started already
            if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
              // Start the Bluetooth chat services
              mChatService.start();
            }
        }
    }
   
    private void setupChat() {
        // Initialize the array adapter for the conversation thread
        mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
        mConversationView = (ListView) findViewById(R.id.in);
        mConversationView.setAdapter(mConversationArrayAdapter);

        // Initialize the compose field with a listener for the return key
        mOutEditText = (EditText) findViewById(R.id.edit_text_out);
        mOutEditText.setOnEditorActionListener(mWriteListener);

        // Initialize the send button with a listener that for click events
        mSendButton = (Button) findViewById(R.id.button_send);
        mSendButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // Send a message using content of the edit text widget
                TextView view = (TextView) findViewById(R.id.edit_text_out);
                String message = view.getText().toString();
                sendMessage(message);
            }
        });

        // Initialize the BluetoothChatService to perform bluetooth connections
        mChatService = new BluetoothChatService(this, mHandler);

        // Initialize the buffer for outgoing messages
        mOutStringBuffer = new StringBuffer("");
    }

    @Override
    public synchronized void onPause() {
        super.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // Stop the Bluetooth chat services
        if (mChatService != null)
                mChatService.stop();
    }    
   
    @Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
                .commit();
    }

    public void onSectionAttached(int number) {
        switch (number) {
            case 1:
                mTitle = getString(R.string.title_section1);
                break;
            case 2:
                mTitle = getString(R.string.title_section2);
                break;
            case 3:
                mTitle = getString(R.string.title_section3);
                break;
        }
    }

    public void restoreActionBar() {
        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setTitle(mTitle);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (!mNavigationDrawerFragment.isDrawerOpen()) {
            // Only show items in the action bar relevant to this screen
            // if the drawer is not showing. Otherwise, let the drawer
            // decide what to show in the action bar.
            getMenuInflater().inflate(R.menu.main, menu);
            restoreActionBar();
            return true;
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */

    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */

        private static final String ARG_SECTION_NUMBER = "section_number";

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */

        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            TextView textView = (TextView) rootView.findViewById(R.id.section_label);
            textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
            return rootView;
        }

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            ((MainActivity) activity).onSectionAttached(
                    getArguments().getInt(ARG_SECTION_NUMBER));
        }
    }
   
    /**************************************************
     ****** ADDED *************************************
     *************************************************/

    public void scanForDevices(View view) {
                // Querying paired devices
                queryingPairedDevices(view);
        // Discovering devices
                discoveringDevices(view);
                // Enabling discoverability
                enablingDiscoverability(view);
    }  

   
    public void queryingPairedDevices(View view) {
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        // If there are paired devices
        if(pairedDevices == null) {
            //No Bonded Devices
                Toast.makeText(getApplicationContext(), "No Bonded Devices", Toast.LENGTH_SHORT).show();
        }
        else {
                if (pairedDevices.size() > 0) {
                    // Loop through paired devices
                    for (BluetoothDevice device : pairedDevices) {
                        // Add the name and address to an array adapter to show in a ListView
                        mConversationArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                    }
                    mConversationArrayAdapter.add("End");
                }
        }
        Toast.makeText(getApplicationContext(), "queryingPairedDevices", Toast.LENGTH_SHORT).show();
    }
   
    public void discoveringDevices(View view) {
        // Create a BroadcastReceiver for ACTION_FOUND
        //private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        final BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
                public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                // When discovery finds a device
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    // Get the BluetoothDevice object from the Intent
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    // Add the name and address to an array adapter to show in a ListView
                    mConversationArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                }
            }
        };
        // Register the BroadcastReceiver
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
        Toast.makeText(getApplicationContext(), "discoveringDevices", Toast.LENGTH_SHORT).show();
    }

    public void enablingDiscoverability(View view) {
        if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                        startActivity(discoverableIntent);
                        Toast.makeText(getApplicationContext(), "enablingDiscoverability", Toast.LENGTH_SHORT).show();
        }
    }
   
}

Logcat:
03-16 14:25:31.712: D/libEGL(984): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
03-16 14:25:31.727: D/libEGL(984): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
03-16 14:25:31.735: D/libEGL(984): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
03-16 14:25:31.813: D/OpenGLRenderer(984): Enabling debug mode 0
03-16 14:25:32.001: I/ActivityManager(984): Timeline: Activity_idle id: android.os.BinderProxy@41ecdb40 time:38005382
03-16 14:26:07.977: I/ActivityManager(984): Timeline: Activity_idle id: android.os.BinderProxy@41f36520 time:38041356
03-16 14:26:11.157: I/ActivityManager(984): Timeline: Activity_idle id: android.os.BinderProxy@41f36520 time:38044534
03-16 14:26:16.376: D/AndroidRuntime(984): Shutting down VM
03-16 14:26:16.376: W/dalvikvm(984): threadid=1: thread exiting with uncaught exception (group=0x4167aba8)
03-16 14:26:16.384: E/AndroidRuntime(984): FATAL EXCEPTION: main
03-16 14:26:16.384: E/AndroidRuntime(984): Process: com.example.bchat, PID: 984
03-16 14:26:16.384: E/AndroidRuntime(984): java.lang.IllegalStateException: Could not execute method of the activity
03-16 14:26:16.384: E/AndroidRuntime(984):    at android.view.View$1.onClick(View.java:3823)
03-16 14:26:16.384: E/AndroidRuntime(984):    at android.view.View.performClick(View.java:4438)
03-16 14:26:16.384: E/AndroidRuntime(984):    at android.view.View$PerformClick.run(View.java:18422)
03-16 14:26:16.384: E/AndroidRuntime(984):    at android.os.Handler.handleCallback(Handler.java:733)
03-16 14:26:16.384: E/AndroidRuntime(984):    at android.os.Handler.dispatchMessage(Handler.java:95)
03-16 14:26:16.384: E/AndroidRuntime(984):    at android.os.Looper.loop(Looper.java:136)
03-16 14:26:16.384: E/AndroidRuntime(984):    at android.app.ActivityThread.main(ActivityThread.java:5050)
03-16 14:26:16.384: E/AndroidRuntime(984):    at java.lang.reflect.Method.invokeNative(Native Method)
03-16 14:26:16.384: E/AndroidRuntime(984):    at java.lang.reflect.Method.invoke(Method.java:515)
03-16 14:26:16.384: E/AndroidRuntime(984):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-16 14:26:16.384: E/AndroidRuntime(984):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-16 14:26:16.384: E/AndroidRuntime(984):    at dalvik.system.NativeStart.main(Native Method)
03-16 14:26:16.384: E/AndroidRuntime(984): Caused by: java.lang.reflect.InvocationTargetException
03-16 14:26:16.384: E/AndroidRuntime(984):    at java.lang.reflect.Method.invokeNative(Native Method)
03-16 14:26:16.384: E/AndroidRuntime(984):    at java.lang.reflect.Method.invoke(Method.java:515)
03-16 14:26:16.384: E/AndroidRuntime(984):    at android.view.View$1.onClick(View.java:3818)
03-16 14:26:16.384: E/AndroidRuntime(984):    ... 11 more
03-16 14:26:16.384: E/AndroidRuntime(984): Caused by: java.lang.NullPointerException
03-16 14:26:16.384: E/AndroidRuntime(984):    at com.example.bchat.MainActivity.queryingPairedDevices(MainActivity.java:313)
03-16 14:26:16.384: E/AndroidRuntime(984):    at com.example.bchat.MainActivity.scanForDevices(MainActivity.java:286)
03-16 14:26:16.384: E/AndroidRuntime(984):    ... 14 more
03-16 14:26:18.368: I/Process(984): Sending signal. PID: 984 SIG: 9

linea 286
    queryingPairedDevices(view);

linea 313
    mConversationArrayAdapter.add(device.getName() + "\n" + device.getAddress());

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[Bluetooth] Scan dei dispositivi
« Risposta #1 il: 16 Marzo 2014, 18:08:13 CET »
+1
Se c'è qualcosa di NULL alla riga 313 potrebbe essere mConversationArrayAdapter o device.

Io propendo per device, perchè è valorizzato da una funzione (getParcelableExtra) che può tranquillamente ritornare un null, e prima di usarlo non fai nessun check del tipo if (device!=null).
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline stefano861

  • Nuovo arrivato
  • *
  • Post: 9
  • Respect: 0
    • Mostra profilo
Re:[Bluetooth] Scan dei dispositivi
« Risposta #2 il: 16 Marzo 2014, 18:23:21 CET »
0
Ti ringrazio per la risposta, ho appena risolto aggiungendo nel metodo l'istruzione:
Codice (Java): [Seleziona]
mConversationArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
Comunque grazie!