J'ai ajouté <uses-permission android:name="android.permission.BLUETOOTH" /> à mon manifeste mais l'erreur
Autorisation manquante requise par BluetoothAdapter.isEnabled: android.permission.BLUETOOTH. est toujours là.
Aussi, dans ContextCompat.checkSelfPermission(...) quel est le premier paramètre CONTEXT ? La documentation https://developer.android.com/training/permissions/requesting ne le dit pas.
Et ai-je raison de dire que je dois déconnecter et reconnecter Bluetooth chaque fois que l'application n'est pas utilisée?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rwb.btconnectortest">
<uses-permission android:name="android.permission.BLUETOOTH" />
<!--<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />-->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/btconnectortestTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Éditer:
class MainActivity : AppCompatActivity() {
var bt: BluetoothAdapter? = null
var bts: BluetoothSocket? = null
val REQUEST_BLUETOOTH_PERMISSION: Int = 1
val REQUEST_BLUETOOTH_ENABLE: Int = 2
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))
{
Toast.makeText(
getApplicationContext(),
"Device does not support Bluetooth therefore this application cannot run.",
Toast.LENGTH_SHORT
).show();
return;
}
bt = BluetoothAdapter.getDefaultAdapter()
if (bt == null) {
// This device does not have Bluetooth.
Toast.makeText(
getApplicationContext(),
"Device does not have a Bluetooth adapter therefore this application cannot run.",
Toast.LENGTH_SHORT
).show();
return;
}
bluetoothConnect();
}
fun bluetoothConnect() {
if (ContextCompat.checkSelfPermission(
CONTEXT, // What is this? It's not explained at https://developer.android.com/training/permissions/requesting
Manifest.permission.BLUETOOTH
) == PackageManager.PERMISSION_GRANTED
) {
if (bt.isEnabled == false) { // Error: Missing permission required by BluetoothAdapter.isEnabled: android.permission.BLUETOOTH.
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBtIntent, REQUEST_BLUETOOTH_ENABLE)
} else {
val pairedDevices: Set<BluetoothDevice>? = bt.bondedDevices
pairedDevices?.forEach { device ->
val deviceName = device.name
val deviceHardwareAddress = device.address // MAC address
}
}
}
else {
// Request permission. That will call back to onActivityResult which in the case of success will call this method again.
// Ask for permission.
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.BLUETOOTH),
REQUEST_BLUETOOTH_PERMISSION
)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_BLUETOOTH_PERMISSION) {
if (resultCode == RESULT_OK) {
bluetoothConnect();
} else {
Toast.makeText(
getApplicationContext(),
"This application cannot run because it does not have Bluetooth permission.",
Toast.LENGTH_SHORT
).show();
// Do we need to quit? How?
}
}
else if( requestCode == REQUEST_BLUETOOTH_ENABLE)
{
if(resultCode == RESULT_OK)
{
// try again
bluetoothConnect();
}
else {
Toast.makeText(
getApplicationContext(),
"This application cannot run because Bluetooth is not enabled and could not be enabled.",
Toast.LENGTH_SHORT
).show();
// Do we need to quit? How?
}
}
}
override fun onPause() {
super.onPause()
// Release Bluetooth
}
override fun onResume() {
super.onResume()
// Connect Bluetooth
}
override fun onStop() {
super.onStop()
// Release Bluetooth
}
override fun onStart() {
super.onStart()
// Connect Bluetooth
}
}
3 Réponses :
Juste parce que les commentaires ne sont pas bons pour cela, laissez-moi vous donner une liste de choses que vous devriez faire avant de pouvoir agir avec Bluetooth. (excuses, c'est en Java car c'est ce que j'ai en ce moment, mais très facile à traduire en Kotlin si nécessaire)
Je fais cela pour BT LE (basse énergie) qui est le moyen préféré pour .. des raisons évidentes.
BluetoothDevice device = adapter.getRemoteDevice(macAddress); device.connectGatt(context, false, anotherCallback);
int rssi = result.getRssi(); BluetoothDevice device = result.getDevice(); String advertiseName = device.getName(); String macAddress = device.getAddress();
Maintenant que vous avez un gestionnaire, vous devez obtenir l' BluetoothAdapter :
public void onScanResult(int callbackType, ScanResult scanResult) {
Tout cela fonctionne bien dans onCreate, mais gardez à l'esprit que vous devez vérifier si BT est activé chaque fois que l'utilisateur reprend l'activité (car il aurait pu être désactivé / désactivé / révoqué / etc.).
Probablement dans onResume:
public void onScan(final BluetoothDevice device, int rssi, byte[] record);
Si la radio BT est éteinte (l'utilisateur l'éteignant), vous pouvez l'activer par programme, si vous avez l'autorisation correspondante (qui, je pense, est BT admin ou similaire, vous devrez rechercher celle-ci, car cela a été un tandis que).
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> Je crois que c'était le cas.
Puisque BT est une radio qui a besoin d'alimentation, il faudra un certain temps (secondes) pour s'allumer et être disponible. Pour cela, vous devez «écouter» avec Yet Another Broadcast Receiver ...
En d'autres termes, l'activité déclenchera une intention ( startActivityForResult(...) ) indiquant à Android d'activer BT, vous vous startActivityForResult(...) à cette diffusion pour écouter le rappel. Une fois qu'Android vous informe que BT est activé, vous pouvez revenir à l'étape 1 et commencer à vérifier s'il est activé, que vous avez l'autorisation, etc.
Le rappel est si je n'ai pas trop oublié ... ressemblait à
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE);
switch (state) {
case BluetoothAdapter.STATE_OFF:
case BluetoothAdapter.STATE_TURNING_OFF:
case BluetoothAdapter.STATE_TURNING_ON:
case BluetoothAdapter.STATE_ON:
}
Ici, vous devez vérifier divers états de BluetoothAdapter ... parmi eux:
BluetoothAdapter.ACTION_STATE_CHANGED
Cela signale que l'état a changé, mais un autre imbriqué est nécessaire pour déterminer dans quel état ...
public void onReceive(Context context, Intent intent) {
Ce sont tous ceux qui vous intéressent (consultez l'énumération BluetoothAdapter pour plus d'informations).
Dans le ON vous savez que BT est ON ... alors ..
Vous pouvez maintenant indiquer à l'adaptateur que vous souhaitez scan ...
adapter.startLeScan(callback);
(n'oubliez pas d'appeler stopLeScan(callback) lorsque vous avez terminé).
À mesure que chaque appareil est trouvé, le callback sera appelé avec les informations dont vous avez besoin pour tenter de vous connecter et de vous associer (si nécessaire).
La signature du rappel ( LeScanCallback ) est quelque chose comme:
// obviously, you need to check that Bt adapter isn't null and all that, // otherwise you ought to go back and "construct" it again, check permissions, etc. adapter = getBTAdapter(); // do all the checks in there... boolean bluetoothEnabled = adapter != null && adapter.isEnabled();
(Je tape par mémoire, donc ça peut être un nom différent mais vous voyez l'idée)
C'est, pour autant que je me souvienne de l'ancienne API.
L'API 21 a un ScanSettings.Builder() où vous pouvez spécifier comment vous voulez analyser, mais c'est essentiellement une méthode similaire. Lancez l'analyse, transmettez un rappel et attendez que les résultats s'affichent.
Vous avez également différents modes:
SCAN_MODE_BALANCED: équilibrer l'efficacité de la batterie et la vitesse de numérisation
SCAN_MODE_LOW_LATENCY: préférez la vitesse de numérisation à la batterie
SCAN_MODE_LOW_POWER: préférez l'efficacité de la batterie à la vitesse de numérisation
SCAN_MODE_OPPORTUNISTIC: je ne me souviens plus :) Je pense que c'était pour utiliser d'autres résultats de scanner «autour» de vous. Jamais utilisé.
Une fois que vous avez identifié le périphérique que vous recherchez, le BluetoothDevice a tout ce dont vous avez besoin pour dire à BT de se «connecter» à celui-ci.
BluetoothAdapter bluetoothAdapter = manager.getAdapter();
^ c'est la signature du "nouveau" Scanner.
À partir de ce ScanResult, vous pouvez faire:
// Does BLE exist?
if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
final BluetoothManager manager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
Si l'analyse échoue pour une raison quelconque, vous obtenez un rappel sur onScanFailed(int errorCode) . Et encore une fois, il y a plusieurs «raisons» (vérifiez le errorCode ) pour lesquelles l'analyse a échoué.
Rappelez-vous que je mixe peut-être API 18 ou API 21 "apis" ici, mais le concept est très similaire dans les deux.
Une fois que vous avez finalement saisi l'adresse MAC d'un appareil ... vous pouvez demander à l'adaptateur d'essayer de vous y connecter:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" /> <uses-permission android:name="android.permission.BLUETOOTH"/>
Le rappel est de BluetoothGattCallback et encore une fois, il a un tas de méthodes parmi elles onConnectionStateChange...
À ce stade, vous devriez en savoir plus sur le fonctionnement de Bluetooth (et sur son fonctionnement sur Android) car il existe différents modes (Gatt étant un moyen) de fonctionner avec BT. Il est impossible de savoir chacun et comment / ce que vous voulez faire une fois connecté.
La règle d'or sera la suivante: assurez-vous que vous êtes prêt à avoir à réappairer ou à demander à nouveau les autorisations, car c'est finalement le choix de l'utilisateur de désactiver, désactiver, quitter, révoquer l'autorisation, etc. à tout moment pendant ce.
Bonne chance!
J'ai redémarré AndroidStudio et maintenant l'erreur a disparu. Quel morceau complet de détritus.
Mais maintenant, la mise en page est cassée ...
Avez-vous essayé: File -> Invalidate Caches -> Invalidate And Restart ?
Non; jamais entendu parler.
Un tel élément de menu n'existe pas dans AndroidStudio 3.6.3.
Regardez de plus près, le menu pour invalider les caches / redémarrer existe depuis que je me souviens (même avant qu'Android Studio n'existe en tant que tel); Intelli-J avait déjà cela en 2013. Le menu Fichier, puis Invalidate Cache / Restart, cela ouvre une boîte de dialogue où vous pouvez invalider les caches et redémarrer Android Studio. Cela a tendance à résoudre la plupart des problèmes de construction. Xcode a une série d'étapes similaire (suppression des données dérivées, entre autres). C'est la (les) tentative (s) de l'EDI pour nettoyer les build / dossiers confus et / ou les artefacts indésirables.
dans le fichier manifeste, ajoutez ces deux autorisations
private lateinit var binding: ActivityMainBinding
private var myBluetooth:BluetoothAdapter? = null
lateinit var mypairedDevices:Set<BluetoothDevice>
val Request_Enable_Blutooth=1
companion object {
val EXTRA_ADDRESS :String= "Device_Address"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
myBluetooth= BluetoothAdapter.getDefaultAdapter()
if (myBluetooth == null)
{
Toast.makeText(applicationContext, "Bluetooth Device Not Available", Toast.LENGTH_LONG).show()
}
if (!myBluetooth!!.isEnabled)
{
val enableBlutoothIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBlutoothIntent, Request_Enable_Blutooth)
}
binding.BTNPairedDevices.setOnClickListener {
pairedDeviceList()
}
}
private fun pairedDeviceList (){
mypairedDevices = myBluetooth!!.bondedDevices
val list : ArrayList<BluetoothDevice> = ArrayList()
if (!mypairedDevices.isEmpty())
{
for ( device:BluetoothDevice in mypairedDevices)
list.add(device)
//list.add(device.name() + "\n" + device.address())
Log.i("Device", "This is messeage")
}
else {
Toast.makeText(applicationContext, " NO PAIRED DEVICES FOUND", Toast.LENGTH_LONG).show()
}
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, list)
binding.DeviceListView.adapter = adapter
binding.DeviceListView.onItemClickListener = AdapterView.OnItemClickListener{ _, _, position, _ ->
val device: BluetoothDevice = list[position]
val address: String = device.address
val intent = Intent(this, LedController::class.java)
intent.putExtra(EXTRA_ADDRESS, address)
startActivity(intent)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == Request_Enable_Blutooth)
{
if(resultCode ==Activity.RESULT_OK)
{
if (myBluetooth!!.isEnabled)
{ Toast.makeText(applicationContext, "Bluetooth Enabled", Toast.LENGTH_LONG).show()
}
else ( Toast.makeText(applicationContext, "Bluetooth Disabled", Toast.LENGTH_LONG).show()
)
}
} else if(resultCode == Activity.RESULT_CANCELED)
Toast.makeText(applicationContext, "Bluetooth has been canceled", Toast.LENGTH_LONG).show()
}
}
################################################ #######
* REMARQUE: j'ai joint mon code bluetooth kotlin, et cela fonctionne avec moi. enter code here j'espère que cela vous sera utile
classe MainActivity: AppCompatActivity () {
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH"
Avant de vérifier la BT, vérifier s'il y a BT dans l'appareil. Quelque chose de similaire
(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);En ce qui concerne le «contexte» dans votre cas, c'estthis(ou l'activité), puisque c'est votre contexte actuel. Vous pouvez également faireif (getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { ...D'après ce que j'ai lu,
bt == nullsert à vérifier si l'appareil dispose de Bluetooth. N'est-ce pas vrai?Il y a une différence entre l'instance de Bluetooth étant nulle, le matériel n'ayant pas BT pour commencer, vous n'avez pas la permission, l'utilisateur désactivant BT, etc. Toutes ces alternatives sont interconnectées; certains comptent sur d'autres, d'autres non. Postez votre manifeste, allez-vous utiliser Bluetooth LE (basse énergie?) (J'espère) cela dépend de votre API MIN (21 si je ne me souviens pas mal ou peut-être 18).
Je n'ai jamais entendu parler de Bluetooth LE; Je doute que mon appareil le prenne en charge. J'aimerais vraiment travailler sur 4.4.4.
CONTEXTE est le
Contextde l'activité, vous pouvez simplement passerthissi vous l' appelez de votre activitéJe ne connais pas Android 4.4.4. C'est plus de 7 ans. Je ne développe que des applications API 23 et supérieures, désolé.