活动st.stxma.Activities.SelectDeviceActivity泄露了IntentReceiver

时间:2015-08-21 16:11:25

标签: java android android-intent android-activity receiver

我如何以及在何处取消注册接收器?我搜索过并发现您使用onCreate08-21 10:32:02.291 12817-12817/st.stxma E/ActivityThread﹕ Activity st.stxma.Activities.SelectDeviceActivity has leaked IntentReceiver st.stxma.STXmaBluetooth$1@41d763e8 that was originally registered here. Are you missing a call to unregisterReceiver()? android.app.IntentReceiverLeaked: Activity st.stxma.Activities.SelectDeviceActivity has leaked IntentReceiver st.stxma.STXmaBluetooth$1@41d763e8 that was originally registered here. Are you missing a call to unregisterReceiver()? at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:809) at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:610) at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1803) at android.app.ContextImpl.registerReceiver(ContextImpl.java:1783) at android.app.ContextImpl.registerReceiver(ContextImpl.java:1777) at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:479) at st.stxma.STXmaBluetooth.enableBluetooth(STXmaBluetooth.java:72) at st.stxma.Activities.SelectDeviceActivity.scanForDevices(SelectDeviceActivity.java:90) at st.stxma.Activities.SelectDeviceActivity.scanForDevices(SelectDeviceActivity.java:101) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at android.view.View$1.onClick(View.java:3964) at android.view.View.performClick(View.java:4640) at android.view.View$PerformClick.run(View.java:19431) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5598) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) at dalvik.system.NativeStart.main(Native Method) 方法执行此操作但在我的情况下我该怎么做?

package st.stxma.Activities;
import android.app.Activity;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import java.util.Observable;
import java.util.Observer;
import st.stxma.R;
import st.stxma.STXmaApplication;



public class SelectDeviceActivity extends Activity implements Observer
{

    private STXmaApplication stx_app;
    private LinearLayout device_list;
    private Button disconnect_button;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.w("STXma", "onCreate: Create!");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.select_device_relative_layout);
        stx_app = (STXmaApplication)getApplicationContext();
        stx_app.getModel().addObserver(this);

        device_list = (LinearLayout)findViewById(R.id.device_list);
        disconnect_button = (Button)findViewById(R.id.disconnect_button);

        populateDevices();         
    }

    public void onPause()
    {
        Log.w("STXma", "onPause: Halt Discovery!");
        super.onPause();
        stx_app.getControl().stxBluetooth().haltDiscovery();
    }

    @Override
    public void onResume()
    {
        Log.w("STXma", "onResume: Resume!");
        super.onResume();

        setDisconnectButton();
    }

    void dummyDevice(View v)
    {
        //Intent launch_device = new Intent(v.getContext(), DynamicControlActivity.class);
        Intent launch_device = new Intent(v.getContext(), DynamicControlViewPager.class);
        startActivity(launch_device);
    }

    /*public void launchDevice(View v)
    {
        //Intent launch_device = new Intent(v.getContext(), DynamicControlActivity.class);
        Intent launch_device = new Intent(v.getContext(), DynamicControlViewPager.class);
        startActivity(launch_device);
    }*/

    void scanForDevices()
    {
        //  0.  Clear existing buttons
        stx_app.getModel().clearDeviceList();
        device_list.removeAllViews();

        //  1.  Turn on Bluetooth
        stx_app.getControl().stxBluetooth().enableBluetooth(this);



        //  2.  Scan for devices
        stx_app.getControl().stxBluetooth().startDiscovery();
    }

    public void scanForDevices(View v)
    {
        scanForDevices();
    }

    void setDisconnectButton()
    {

        BluetoothDevice dev = stx_app.getModel().getConnectedDevice();

        if(dev == null) {

            disconnect_button.setText("Not Connected");

        }else{

            disconnect_button.setText("Disconnect "+dev.getName());
        }
    }

    void populateDevices()
    {
        device_list.removeAllViews();
        BluetoothDevice devices[] = stx_app.getModel().getDevices();

        if(devices == null)
        {
            device_list.addView(createDummyButton());
            return;
        }

        for(BluetoothDevice dev : devices)
        {
            device_list.addView(createDeviceButton(dev));
        }
    }

    public void update(Observable obs, Object arg)
    {
        BluetoothDevice dev = stx_app.getModel().getLastDeviceAdded();
        device_list.addView(createDeviceButton(dev));
    }

    private Button createDummyButton()
    {
        Button b = new Button(this);
        Drawable button_icon = this.getResources().getDrawable(R.drawable.st360);
        if (button_icon != null) {
            button_icon.setBounds(0, 0, 30, 30);
        }
        b.setCompoundDrawables(button_icon, null, null, null);

        b.setText("Dummy Device");

        b.setOnClickListener(new OnClickListener(){
            public void onClick(View v)
            {
                dummyDevice(v);
            }
        });

        return b;
    }

    private Button createDeviceButton(BluetoothDevice dev)
    {
        Button b = new Button(this);
        Drawable button_icon = this.getResources().getDrawable(R.drawable.st360);
        if (button_icon != null) {
            button_icon.setBounds(0, 0, 30, 30);
        }
        b.setCompoundDrawables(button_icon, null, null, null);


        if ((dev.getName() != null) && (dev.getName().length() > 0)) {
            b.setText(dev.getName());
        }else{
            b.setText("Dummy Device");
        }

        b.setOnClickListener(new OnClickListener(){
            public void onClick(View v)
            {
                Button b = (Button)v;
                BluetoothDevice dev = stx_app.getModel().getDeviceByName(b.getText().toString());

                if(dev != null)
                {
                    //  Attempt to connect to the device
                    if(stx_app.getControl().connectDevice(dev))
                    {
                        Intent launch_device = new Intent(v.getContext(), DynamicControlViewPager.class);
                        startActivity(launch_device);
                    }
                    else Toast.makeText(SelectDeviceActivity.this, "Connection Failed", Toast.LENGTH_SHORT).show();
                }
            }
        });

        return b;
    }

    public void disconnectFromDevice(View v)
    {
        stx_app.getControl().disconnect();
        setDisconnectButton();
    }
}

SelectDeviceActivity.java

package st.stxma;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.widget.Toast;

import java.io.IOException;
import java.util.ArrayList;
import java.util.UUID;


public class STXmaBluetooth 
{
    final static int REQUEST_ENABLE_BT = 1;
    BluetoothAdapter bt_adapter;
    BroadcastReceiver receiver;
    BluetoothSocket bt_socket;
    STXmaModel stx_model;
    Boolean connected = false;
    CommunicationThread comm_thread;
    ArrayList<String> message_fragment;

    public STXmaBluetooth(STXmaModel model)
    {
        bt_adapter = BluetoothAdapter.getDefaultAdapter();
        stx_model = model;
        message_fragment = new ArrayList<String>();

        createReceiver();
    }


    public boolean enableBluetooth(Activity blue_activity)
    {
        Intent enable_bluetooth;
        //  Check to see if the device supports Bluetooth

        if(bt_adapter == null)
        {

            Toast.makeText(blue_activity.getApplicationContext(), "No bluetooth detected",Toast.LENGTH_LONG).show();
            blue_activity.finish();
            //  Device does not support bluetooth - do something!
        }

        //  Check to see if the Bluetooth is enabled
        //  If not, ask the user if they want to enable it
        if(!bt_adapter.isEnabled())
        {

            enable_bluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            blue_activity.startActivityForResult(enable_bluetooth, REQUEST_ENABLE_BT);

        }

        //  Enable Receiver

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        blue_activity.registerReceiver(receiver, filter);


        return true;
    }


    private void createReceiver()
    {
        receiver = new BroadcastReceiver()
        {
            public void onReceive(Context context, Intent intent)
            {
                //Log.w("STXma", "OnReceive called");
                //aa.notifyDataSetChanged();
                String action = intent.getAction();
                if(BluetoothDevice.ACTION_FOUND.equals(action))
                {
                    //  Get the Bluetooth device object from the Intent
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    stx_model.addDevice(device);



                }
            }
        };
    }

    public void haltDiscovery()
    {

        bt_adapter.cancelDiscovery();

    }

    public boolean disconnect()
    {
        try
        {
            comm_thread.disconnect();
            bt_socket.close();
        }
        catch(Exception e)
        {
            Log.w("STXma", "disconnect(): "+e.getMessage());
            return false;
        }
        Log.w("STXma", "Disconnected Now");
        stx_model.setConnectedDevice(null);
        return true;
    }

    ////////////////////////////////////////////////////////////////////////////
    //  ************************************************************************
    //
    //  boolean connect(BluetoothDevice dev)
    //
    //  July 10th, 2014
    //
    //  This function creates a connection to the bluetooth device provided to
    //  it.  It returns true if successful.
    //
    //  Note:  enableCommunicationsThread() must be called to to open the device
    //  for communications.
    //
    //  ************************************************************************
    ////////////////////////////////////////////////////////////////////////////
    public boolean connect(BluetoothDevice dev)
    {
        bt_adapter.cancelDiscovery();
        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

        try
        {
            bt_socket = dev.createRfcommSocketToServiceRecord(uuid);
            bt_socket.connect();
            stx_model.setConnectedDevice(dev);
        }
        catch(IOException e)
        {
            Log.w("STXma", "IOException in connect "+e.getMessage());
            connected = false;
        }
        catch(Exception e)
        {
            Log.w("STXma", "Exception in connect "+e.getMessage());
            connected = false;
        }

        if(connected)
        {
            Log.w("STXma", "Connection completed");
        }

        connected = enableCommunicationsThread();

        return connected;
    }

    ////////////////////////////////////////////////////////////////////////////
    //  ************************************************************************
    //
    //  boolean enableCommunicationsThread()
    //
    //  July 10th, 2014
    //
    //  This function creates and starts the communication thread.  Once started
    //  commands can be sent to the device and the software will read the BT
    //  responses
    //
    //  ************************************************************************
    ////////////////////////////////////////////////////////////////////////////
    private boolean enableCommunicationsThread()
    {
        comm_thread = new CommunicationThread(bt_socket, this);
        comm_thread.start();
        return comm_thread.isConnected();        
    }

    ////////////////////////////////////////////////////////////////////////////
    //  ************************************************************************
    //
    //  void sendCommand(String cmd)
    //
    //  July 10th, 2014
    //
    //  Converts the string command into an integer and sends it to the
    //  communication thread to be writen to the device.
    //
    //  ************************************************************************
    ////////////////////////////////////////////////////////////////////////////
    public void sendCommand(String cmd)
    {
        try
        {
            int i = Integer.decode(cmd);
            comm_thread.write(i); 
        }
        catch(Exception e)
        {
            Log.w("STXma", "Send Command Failed: "+e.getMessage());
        }        
    }

    ////////////////////////////////////////////////////////////////////////////
    //  ************************************************************************
    //
    //  public void startDiscovery()
    //
    //  July 7th, 2014
    //
    //  This function clears the existing list of devices then starts the
    //  discovery process.
    //
    //  ************************************************************************
    ////////////////////////////////////////////////////////////////////////////
    public void startDiscovery()
    {
        Log.w("STXma", "Start Discovery");
        bt_adapter.startDiscovery();
    }

    public void processBuffer(Integer[] buffer)
    {
        //Log.w("STXma", "Process Buffer");

        for(int value : buffer)
        {
            String byte_string = Integer.toHexString(value);
            Log.w("STXma", "0x"+byte_string);


            message_fragment.add(byte_string);
            if(completedMessage())
            {
                String byte_array[] = new String[message_fragment.size()];
                byte_array = message_fragment.toArray(byte_array);

                stx_model.processBluetoothMessage(byte_array);

                //  Clear the messages
                message_fragment.clear();
            }

        }

    }   

    ////////////////////////////////////////////////////////////////////////////
    //  ************************************************************************
    //
    //  boolean completedMessage()
    //
    //  July 21, 2014
    //
    //  There are three valid return sizes
    //  4X - These are all five byte messages.  The first is the command, the
    //      other four bytes are the data
    //  8X - These are two byte messages returned separately.  The first byte
    //      tells the device what is being set, the second is the value it
    //      sets it to
    //  XX - These are command bytes that are a single byte long
    //
    //  ************************************************************************
    ////////////////////////////////////////////////////////////////////////////
    private boolean completedMessage()
    {
        //  If the message_fragment is empty, we do not have a valid return
        if(message_fragment.isEmpty())return false;

        //  If the first byte starts with a "4", we know we have a 5 byte
        //  return, so we need to collect 5 bytes before returning true
        String first = message_fragment.get(0);
        if(first.startsWith("4")) {
            return message_fragment.size() == 5;
        }
        else if(first.startsWith("8"))
        {
            return message_fragment.size() == 2;
        }

        //  Any other size is a valid single byte command return
        return true;
    }
}

STXmaBluetooth.java

git

1 个答案:

答案 0 :(得分:1)

创建方法onDestroy()并放入unregisterReceiver(broadcast)