java.lang.SecurityException:需要BLUETOOTH权限:用户10065和当前进程都没有android.permission.BLUETOOTH

时间:2015-10-20 07:16:38

标签: java android bluetooth

我对Android编程完全陌生,这在技术上是我在Android Studio上工作的第一个大项目。我正在尝试创建一个通过蓝牙连接到我的Arduino设备的Android应用程序,并最终处理.txt文件。

目前,我似乎无法启用蓝牙。当我点击应该要求用户激活蓝牙权限的按钮时,该应用程序会冻结并最终崩溃。

我已经包含了java和logcat。对此事有任何帮助吗?

java文件:

InStr

logcat的:

package com.example.a0111601.testsplash;

import android.app.Activity;
import android.bluetooth.BluetoothSocket;
import android.bluetooth.BluetoothServerSocket;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;

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

import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
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 ConnectingScreen extends Activity {

    private TextView text;
    private ArrayAdapter<String> BTArrayAdapter;
    private ListView listView;
    public BluetoothAdapter bluetoothAdapter;
    private final static UUID uuid = UUID.fromString("fc5ffc49-00e3-4c8b-9cf1-6b72aad1001a");
    private Button btn_refresh;
    private Button btn_proceed;
    private ArrayAdapter adapter;
    private static final int ENABLE_BT_REQUEST_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.connecting_screen);

        // Initialize items on the screen from layout in order //

        // Get bluetooth status //
        text = (TextView) findViewById(R.id.status_BT);
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!bluetoothAdapter.isEnabled()) { // if bluetooth has not been enabled //
            text.setText("Disabled");
        } else { // bluetooth has already been enabled //
            text.setText("Enabled");
        }

        // Set up list for selection of available devices //
        listView = (ListView) findViewById(R.id.Connecting_devices);
        // Click listener on list //
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                // Cancel discovery because it's costly and we're about to connect
                bluetoothAdapter.cancelDiscovery();

                // Get the device MAC address, which is the last 17 chars in the View
                String info = ((TextView) v).getText().toString();
                String address = info.substring(info.length() - 17);
                BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);
                // Initiate a connection request in a separate thread
                ConnectingThread t = new ConnectingThread(bluetoothDevice);
                t.start();
            }
        });

        BTArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
        listView.setAdapter(BTArrayAdapter);

        // Register for broadcasts when a device is discovered
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(mReceiver, filter);

        // Register for broadcasts when discovery has finished
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(mReceiver, filter);

        // Initialize Refresh button //
        btn_refresh = (Button) findViewById(R.id.refresh);
        btn_refresh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BTArrayAdapter.clear();
                while (!bluetoothAdapter.isEnabled()) { // if bluetooth has not been enabled //
                    // Dialog to request user permission to enable BT //
                    Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableBluetoothIntent, ENABLE_BT_REQUEST_CODE);
                }
                if (bluetoothAdapter.isEnabled()) { // bluetooth has already been enabled //
                    text.setText("Enabled");
                    // To discover devices //
                    discoverDevices();
                    Toast.makeText(getApplicationContext(), "Scanning for devices...", Toast.LENGTH_LONG).show();
                }
            }
        });

        btn_proceed = (Button) findViewById(R.id.proceed_footer);
        // Source: http://stackoverflow.com/questions/24610527/how-do-i-get-a-button-to-open-another-activity-in-android-studio //
        // Proceed button to continue on to next activity //
        btn_proceed.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View v) {
                startActivity(new Intent(ConnectingScreen.this, MainActivity.class));
            }
        });

        // Disable "proceed" button by default to prevent user from going to next activity //
        // Source: //
        // http://stackoverflow.com/questions/4384890/how-to-disable-an-android-button //
        btn_proceed.setEnabled(false);

    }

    // ConnectingThread method to connect to device selected from list //
    private class ConnectingThread extends Thread {
        private final BluetoothSocket bluetoothSocket;
        private final BluetoothDevice bluetoothDevice;

        public ConnectingThread(BluetoothDevice device) {
            BluetoothSocket temp = null;
            bluetoothDevice = device;

            // Get a BluetoothSocket to connect with the selected BluetoothDevice
            try {
                temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
            } catch (IOException e) {
                e.printStackTrace();
            }
            bluetoothSocket = temp;
        }

        public void run() {
            // Cancel discovery first to not slow down connection speed //
            bluetoothAdapter.cancelDiscovery();

            try {
                // bluetoothSocket.connect() to initiate connection request //
                // This will block until it succeeds in connecting to the device through the bluetoothSocket or throws an exception //
                bluetoothSocket.connect();
            } catch (IOException connectException) {
                connectException.printStackTrace();
                try {
                    bluetoothSocket.close();
                } catch (IOException closeException) {
                    closeException.printStackTrace();
                }
            }
            if (bluetoothSocket.isConnected()) {
                btn_proceed.setEnabled(true);
            }
        }
    }

    // discoverDevices() method //
    // To scan for other devices //
    protected void discoverDevices() {
        // If we're already discovering, stop it
        if (bluetoothAdapter.isDiscovering()) {
            bluetoothAdapter.cancelDiscovery();
        }
        bluetoothAdapter.startDiscovery();
        // to change the bluetooth status accordingly //
        if (bluetoothAdapter.startDiscovery()) {
            text.setText("Scanning");
            Toast.makeText(getApplicationContext(), "Scanning for devices...", Toast.LENGTH_LONG).show();
        } else {
            text.setText("Error scanning");
            Toast.makeText(getApplicationContext(), "Discovery failed to start!", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * The BroadcastReceiver that listens for discovered devices and changes the title when
     * discovery is finished
     */
    private 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);
                // If it's already paired, skip it, because it's been listed already //
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    BTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                }

                // When discovery is finished, change the Activity title //
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                Toast.makeText(getApplicationContext(), "Select device to pair with", Toast.LENGTH_LONG).show();
                text.setText("Select device from list");
                if (BTArrayAdapter.getCount() == 0) {
                    text.setText("No devices found");
                    String noDevices = getResources().getText(R.string.none_found).toString();
                    BTArrayAdapter.add(noDevices);
                }
            }
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // Make sure we're not doing discovery anymore
        if (bluetoothAdapter != null) {
            bluetoothAdapter.cancelDiscovery();
        }
        // Unregister broadcast listeners
        this.unregisterReceiver(mReceiver);
    }
}

清单:

10-20 14:52:23.693 6976-6976/? E/Zygote: MountEmulatedStorage()
10-20 14:52:23.693 6976-6976/? E/Zygote: v2
10-20 14:52:23.693 6976-6976/? I/libpersona: KNOX_SDCARD checking this for 10065
10-20 14:52:23.693 6976-6976/? I/libpersona: KNOX_SDCARD not a persona
10-20 14:52:23.693 6976-6976/? I/SELinux: Function: selinux_compare_spd_ram, SPD-policy is existed. and_ver=SEPF_GT-I9505_5.0.1 ver=27
10-20 14:52:23.693 6976-6976/? I/SELinux: Function: selinux_compare_spd_ram , priority [2] , priority version is VE=SEPF_GT-I9505_5.0.1-1_0032
10-20 14:52:23.703 6976-6976/? E/SELinux: [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
10-20 14:52:23.703 6976-6976/? I/art: Late-enabling -Xcheck:jni
10-20 14:52:23.723 6976-6983/? E/art: Failed sending reply to debugger: Broken pipe
10-20 14:52:23.723 6976-6983/? I/art: Debugger is no longer active
10-20 14:52:23.753 6976-6976/? D/ResourcesManager: creating new AssetManager and set to /data/app/com.example.a0111601.testsplash-2/base.apk
10-20 14:52:23.943 6976-6976/? D/Activity: performCreate Call secproduct feature valuefalse
10-20 14:52:23.943 6976-6976/? D/Activity: performCreate Call debug elastic valuetrue
10-20 14:52:23.953 6976-7015/? D/OpenGLRenderer: Render dirty regions requested: true
10-20 14:52:23.983 6976-7015/? I/Adreno-EGL: <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build:  ()
10-20 14:52:23.983 6976-7015/? I/Adreno-EGL: OpenGL ES Shader Compiler Version: E031.25.03.06
10-20 14:52:23.983 6976-7015/? I/Adreno-EGL: Build Date: 01/24/15 Sat
10-20 14:52:23.983 6976-7015/? I/Adreno-EGL: Local Branch: AF11_RB1_AU15
10-20 14:52:23.983 6976-7015/? I/Adreno-EGL: Remote Branch: 
10-20 14:52:23.983 6976-7015/? I/Adreno-EGL: Local Patches: 
10-20 14:52:23.983 6976-7015/? I/Adreno-EGL: Reconstruct Branch: 
10-20 14:52:23.983 6976-7015/? I/OpenGLRenderer: Initialized EGL, version 1.4
10-20 14:52:24.013 6976-7015/? D/OpenGLRenderer: Enabling debug mode 0
10-20 14:52:24.674 6976-6976/? I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@29f66b0b time:6733391
10-20 14:52:25.735 6976-6983/com.example.a0111601.testsplash I/art: Ignoring second debugger -- accepting and dropping
10-20 14:52:26.736 6976-7014/? I/Timeline: Timeline: Activity_launch_request id:com.example.a0111601.testsplash time:6735467
10-20 14:52:26.816 6976-6976/? D/AbsListView: Get MotionRecognitionManager
10-20 14:52:26.836 6976-6976/? D/Activity: performCreate Call secproduct feature valuefalse
10-20 14:52:26.836 6976-6976/? D/Activity: performCreate Call debug elastic valuetrue
10-20 14:52:27.066 6976-6976/? I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@21202ee1 time:6735796
10-20 14:53:00.079 6976-6976/? I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@21202ee1 time:6768804
10-20 14:54:12.720 6976-6976/? D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
10-20 14:54:14.441 6976-6976/? D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
10-20 14:54:14.952 6976-6976/? D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
10-20 14:54:17.514 6976-6976/? D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
10-20 15:04:08.991 6976-6976/? D/AndroidRuntime: Shutting down VM
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime: FATAL EXCEPTION: main
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime: Process: com.example.a0111601.testsplash, PID: 6976
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime: java.lang.SecurityException: Need BLUETOOTH permission: Neither user 10065 nor current process has android.permission.BLUETOOTH.
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.os.Parcel.readException(Parcel.java:1540)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.os.Parcel.readException(Parcel.java:1493)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.bluetooth.IBluetooth$Stub$Proxy.isEnabled(IBluetooth.java:1156)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.bluetooth.BluetoothAdapter.isEnabled(BluetoothAdapter.java:695)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at com.example.a0111601.testsplash.ConnectingScreen$2.onClick(ConnectingScreen.java:93)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.view.View.performClick(View.java:5197)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.view.View$PerformClick.run(View.java:20926)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:145)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5942)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
10-20 15:04:09.021 6976-6976/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
10-20 15:04:09.031 6976-6976/? E/AndroidRuntime: Error reporting crash
10-20 15:04:09.031 6976-6976/? E/AndroidRuntime: android.os.DeadObjectException
10-20 15:04:09.031 6976-6976/? E/AndroidRuntime:     at android.os.BinderProxy.transactNative(Native Method)
10-20 15:04:09.031 6976-6976/? E/AndroidRuntime:     at android.os.BinderProxy.transact(Binder.java:496)
10-20 15:04:09.031 6976-6976/? E/AndroidRuntime:     at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:4686)
10-20 15:04:09.031 6976-6976/? E/AndroidRuntime:     at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:95)
10-20 15:04:09.031 6976-6976/? E/AndroidRuntime:     at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
10-20 15:04:09.031 6976-6976/? E/AndroidRuntime:     at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
10-20 15:04:09.031 6976-6976/? I/Process: Sending signal. PID: 6976 SIG: 9

2 个答案:

答案 0 :(得分:3)

function

答案 1 :(得分:-1)

为蓝牙管理员添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>