android studio - bluetooth discovering ACCES_COARSE_LOCATION not granted - java

I am training coding on android studio, I am coding an activity that use bluetooth. I am able to enable/disable the bluetooth. but I am in trouble while I am trying to discover devices. The bluetooth doesn't find any device it seems that the ACTION_fOUND never trigger..
The code has no error, and the application runs well.
I found out that the permission ACCESS_COARSE_LOCATION is not granted. It may cause the error ?
Does anyone can tell how to grant the permission ?
I followed the following tutorial :
https://developer.android.com/guide/topics/connectivity/bluetooth
Here is my code..
package com.example.kartouche;
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.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
public class BluetoothActivity extends AppCompatActivity {
/** Declaration des variables privés
* - p_bluetoothAdapter : représente le bluetooth de l'appareil
* - p_acces_btn_bluetooth : représente le bouton logique d'activation et désactivation du bluetooth de l'appareil
* -
* -- */
private BluetoothAdapter p_bluetoothAdapter;
private Button p_access_btn_bluetooth;
private Button p_btn_discover_device;
private ListView p_list_device;
int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
private static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_DISCOVER_BT = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
p_access_btn_bluetooth = (Button) findViewById(R.id.btn_access_bluetooth);
p_btn_discover_device = (Button) findViewById(R.id.btn_discover_device);
p_list_device = (ListView) findViewById(R.id.lv_list_devices);
/** ETAPE 1
* Implementation Bluetooth qui objective le bluetooth de l'appareil. -- */
p_bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (p_bluetoothAdapter == null)
{Toast.makeText(getApplicationContext(), "Bluetooth non disponible sur cette appareil",Toast.LENGTH_SHORT).show();}
if (getApplicationContext().checkSelfPermission("android.permission.ACCESS_COARSE_LOCATION") == PackageManager.PERMISSION_GRANTED)
{
Log.e("[MESSAGE]","ACCES_COARSE_LOCATION GRANTED");
}
else
{
Log.e("[MESSAGE]","ACCES_COARSE_LOCATION NOT GRANTED");
}
/** Textualisation du bouton p_acces_btn_bluetooth*/
if(!p_bluetoothAdapter.isEnabled())
{p_access_btn_bluetooth.setText("ACTIVER BLUETOOTH");}
else
{p_access_btn_bluetooth.setText("DESACTIVER BLUETOOTH");}
/** ETAPE 2
* Vérification de l'etat d'activation de l'appareil, Si le bluetooth n'est pas activé alors nous l'activons (resp) et changeons le texte du bouton -- */
p_access_btn_bluetooth.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Button btn_logique_text = (Button) p_access_btn_bluetooth;
String buttonText = btn_logique_text.getText().toString();
if (!p_bluetoothAdapter.isEnabled())
{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
p_access_btn_bluetooth.setText("DESACTIVER BLUETOOTH");
}
else
{
p_bluetoothAdapter.disable();
p_access_btn_bluetooth.setText("ACTIVER BLUETOOTH");
}
}
});
/**
* ETAPE 3
* Analyse des appareils à proximité. -- */
p_btn_discover_device.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!p_bluetoothAdapter.isEnabled())
{Toast.makeText(getApplicationContext(), "Le bluetooth doit être activé pour effectuer l'analyse", Toast.LENGTH_SHORT).show();}
else
{
p_bluetoothAdapter.startDiscovery();
Toast.makeText(getApplicationContext(),"début d'analyse ...", Toast.LENGTH_SHORT).show();
}
}
});
// Register for broadcasts when a device is discovered.
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
}//OnCreate
// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
List<String> p_device_bluetooth = new ArrayList<String>();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(BluetoothActivity.this,android.R.layout.simple_list_item_1,p_device_bluetooth );
p_list_device.setAdapter(arrayAdapter);
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
Log.e("[MESSAGE]","Device enfin trouvé..");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
p_device_bluetooth.add(deviceName);
arrayAdapter.notifyDataSetChanged();
}
}
};// BroadcastReceiver
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}//onDestroy
#Override
public void onBackPressed(){
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
}//OnBackPressed
}
Here is the xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BluetoothActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="#+id/btn_access_bluetooth"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp" />
<Button
android:id="#+id/btn_access_bluetooth"
android:layout_width="345dp"
android:layout_height="40dp"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btn_discover_device"
android:layout_width="345dp"
android:layout_height="40dp"
android:text="Analyse bluetooth a proximite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.492"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.584" />
</androidx.constraintlayout.widget.ConstraintLayout>
here is the manifest xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.kartouche">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"

It looks like you checked for the permission, however, did not ask the user to grant the permission. I would recommend following this developer documentation on this.
Hence, instead of just printing the logs, you might have to prompt the dialog to the user to grant your app the permissions that you need.
if (ContextCompat.checkSelfPermission(
CONTEXT, Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
Log.e("[MESSAGE]","ACCES_COARSE_LOCATION GRANTED");
else {
// You can directly ask for the permission.
// The registered ActivityResultCallback gets the result of this request.
requestPermissionLauncher.launch(
Manifest.permission.ACCESS_COARSE_LOCATION);
Log.e("[MESSAGE]","ACCES_COARSE_LOCATION NOT GRANTED");
}
And you have to override the onRequestPermissionsResult in your activity/fragment where you are asking for that.
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission is granted. Continue the action or workflow
// in your app.
} else {
// Explain to the user that the feature is unavailable because
// the features requires a permission that the user has denied.
// At the same time, respect the user's decision. Don't link to
// system settings in an effort to convince the user to change
// their decision.
}
return;
}
}
}

Related

how to keep scanning and writing in csv without pressing the button? Bluetooth Adapter

So I did a bluetooth scanner app in android studio and I want to store data in a csv. the problem is that I want to remove the button and the app to keep scanning and write in csv. Right now it scans automatically but I have to press the button in order to create and write in csv. Can you help me with implementing a method for automatically writing? I tried using the btn.setPressed(true) and btn.performClick() but it didn't work. Here is MainActivity and activity_xm. The manifest has all permissions and in gradle.app has minSDK 28 AND targetSDK 32.
package com.example.blutut;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
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.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Bluetooth bluetooth = new Bluetooth();
private BluetoothAdapter BTAdapter = BluetoothAdapter.getDefaultAdapter();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
Button btn = findViewById(R.id.btnDetect);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
String name = device.getName();
TextView txt = findViewById(R.id.textView);
txt.setText(txt.getText() + name + " => " + rssi + "dBm\n");
String entry = "\n" + String.format("%d", rssi);
try {
File path = new File("/storage/emulated/0/Download");
File file = new File(path + "/bluetooth.csv");
FileOutputStream f = new FileOutputStream(file, true);
try {
f.write(entry.getBytes());
f.flush();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
public void btnClick(View view) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
BTAdapter.startDiscovery();
return;
}
}
}
/// activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/btnDetect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="btnClick"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnDetect" />

bluetoothAdapter.startDiscovery() doesn't start without clicking the bluetooth button from the notification panel and finishes immediately

In android 12 api 31
I run this app ,it doesn't work properly
I want to find the name of the nearby devices but the Bluetooth device doesn't start until I click on the Bluetooth button from the notification panel and in log it shows Discovery Started and Gave another Log which shows Discovery Finished without searching a device.
package com.aditya.bluetoothfinder;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
ListView listView;
TextView statusTextView;
Button searchButton;
BluetoothAdapter bluetoothAdapter;//The BluetoothAdapter is required for any and all Bluetooth activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
statusTextView = findViewById(R.id.statusTextView);
searchButton = findViewById(R.id.searchButton);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
public void searchClicked(View view) {
if (bluetoothSupported()) {
openBluetooth();
} else {
statusTextView.setText("Bluetooth Not Supported");
}
}
//This function will check that the bluetooth is supported on the device or not
public boolean bluetoothSupported() {
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
}
//This function opens the bluetooth
public void openBluetooth() {
if (!bluetoothAdapter.isEnabled()) {
Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
requestThePermissons();
} else {
startActivityForResult(enableBluetoothIntent, 1);
}
} else {
searchBluetoothDevices();
}
}
//This function request the permission
private void requestThePermissons() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { //if we don't have any permission
requestPermissionLauncher.launch(Manifest.permission.BLUETOOTH_CONNECT);
} else { //if we already have permissionn of bluetooth connect
searchBluetoothDevices();
}
}
//This is a callback which give us the information that the user gave us the permission or not
private final ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
// Permission is granted. Continue the action or workflow in your
searchBluetoothDevices();
} else { //If user declined the permission request
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
});
//This is the function for searching bluetooth devices
public void searchBluetoothDevices() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Unable to locate bluetooth device", Toast.LENGTH_SHORT).show();
requestPermissions(new String[]{Manifest.permission.BLUETOOTH_SCAN},1);
} else {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Unable to locate", Toast.LENGTH_SHORT).show();
}
bluetoothAdapter.startDiscovery();
statusTextView.setText("Searching...");
searchButton.setEnabled(false);
}
}
When I call the bluetoothAdapter.startDiscovery();
It shows
D/BluetoothAdapter: startDiscovery(): called by: com.aditya.bluetoothfinder
but doesn't show the log Discovery started until I click on the Bluetooth button from the notification panel and after that it gives another Log Discovery Finished
//This function give us the details of the bluetooth device if found
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
Log.i("this", "Device Found");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
requestThePermissons();
Toast.makeText(MainActivity.this, "Unable to find", Toast.LENGTH_SHORT).show();
} else {
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
String text = (String) statusTextView.getText();
statusTextView.setText(text + "\n" +deviceName + "\n" + deviceHardwareAddress);
}
} else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Log.i("this", "Discovery Finished");
statusTextView.setText("Finished");
searchButton.setEnabled(true);
} else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Log.i("this", "Discovery started");
Toast.makeText(MainActivity.this, "Started", Toast.LENGTH_SHORT).show();
}
}
};
}
Permission used in AndroidManifest.xml
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
You also have to take location permission from the user and the user has to turn on location services in order to see other Bluetooth devices.

I'm try to grant access to Enable and Disable Bluetooth on Android Studio using JAVA; but startActivityForResult has been Deprecated. What I can do? [duplicate]

This question already has answers here:
OnActivityResult method is deprecated, what is the alternative?
(29 answers)
Closed last year.
I would like grant access to Enable and Disable Bluetooth from Android Studio. I also pretend to use other functionalities of Bluetooth as list of devices and connect to previous pared device and more.
Since starActivityForResult has been Deprecated, I'm having trouble to lunch the pop up activity that ask the user for allowance.
This is my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.bluetoothonofftest"
tools:ignore="CoarseFineLocation">
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30"
tools:ignore="CoarseFineLocation" />
<!-- Needed only if your app looks for Bluetooth devices.
If your app doesn't use Bluetooth scan results to derive physical
location information, you can strongly assert that your app
doesn't derive physical location. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Needed only if your app uses Bluetooth scan results to derive physical location. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<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/Theme.BlUetoothTest">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
This is my ManinActivity
package com.example.bluetoothexamples;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Set;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_DISCOVER_BT = 1;
TextView mStatusBlueTv;
TextView mPairedTv;
ImageView mBlueIv;
Button mOnBtn;
Button mOffBtn;
Button mDiscoverBtn;
Button mPairedBtn;
BluetoothAdapter mBlueAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStatusBlueTv = findViewById(R.id.statusBluetoothTv);
mPairedTv = findViewById(R.id.pairedTv);
mBlueIv = findViewById(R.id.bluetoothIv);
mOnBtn = findViewById(R.id.onBtn);
mOffBtn = findViewById(R.id.offBtn);
mDiscoverBtn = findViewById(R.id.discoverableBtn);
mPairedBtn = findViewById(R.id.pairedBtn);
// Adapter
mBlueAdapter = BluetoothAdapter.getDefaultAdapter();
//Check if bluetooth is available or not
if (mBlueAdapter == null) {
mStatusBlueTv.setText("Bluetooth is NOT Available");
} else {
mStatusBlueTv.setText("Bluetooth is Available");
// Set image according to bluetooth status (on/off)
if (mBlueAdapter.isEnabled()) {
mBlueIv.setImageResource(R.drawable.ic_action_on);
} else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
mOnBtn.setOnClickListener(this); // Turn on Bluetooth btn click
mDiscoverBtn.setOnClickListener(this); // Discover bluetooth btn click
mOffBtn.setOnClickListener(this); // Turn off Bluetooth btn click
mPairedBtn.setOnClickListener(this); // Get Paired devices button click
}
}
#Override
public void onClick(View view) {
switch (view.getId()) {
// Turn on Bluetooth btn click
case R.id.onBtn:
if (!mBlueAdapter.isEnabled()) {
// showToast("Turning On Bluetooth...");
// if (getApplicationContext().checkSelfPermission(Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) {
// } else {
// requestPermissions(new String[]{Manifest.permission.BLUETOOTH_ADMIN},1);
// }
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.BLUETOOTH_ADMIN},1);
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
// Intent to On Bluetooth
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE_BT);
}
else {
showToast("Bluetooth is already on");
}
break;
// Discover bluetooth btn click
case R.id.discoverableBtn:
if (!mBlueAdapter.isDiscovering()){
showToast("Making Your Device Discoverable");
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(intent ,REQUEST_DISCOVER_BT);
}
break;
// Turn off Bluetooth btn click
case R.id.offBtn:
if (mBlueAdapter.isEnabled()) {
mBlueAdapter.disable();
showToast("Turning Bluetooth Off");
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
else {
showToast("Bluetooth is already off");
}
break;
// Get Paired devices button click
case R.id.pairedBtn:
if (mBlueAdapter.isEnabled()) {
mPairedTv.setText("Paired Devices");
Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
for (BluetoothDevice device: devices){
mPairedTv.append("\nDevice: " + device.getName() + ", " + device);
}
}
else {
//bluetooth is off so can't get paired devices
showToast("Turn ON Bluetooth to get paired devices");
}
break;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
showToast("Permission Granted");
}
else {
showToast("Permission Denied");
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
switch (requestCode){
case REQUEST_ENABLE_BT:
if (resultCode == RESULT_OK) {
// Bluetooth is on
mBlueIv.setImageResource(R.drawable.ic_action_on);
showToast("Bluetooth is on");
}
else {
showToast("Failed to connect to bluetooth");
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
//Toast message function
private void showToast (String msg) {
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
This is my XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".MainActivity">
<!-- Display whether bluetooth is available or not-->
<TextView
android:id="#+id/statusBluetoothTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAlignment="center"
android:textSize="20sp"
android:textColor="#000" />
<!-- Bluetooth icon-->
<ImageView
android:id="#+id/bluetoothIv"
android:layout_width="100dp"
android:layout_height="100dp" />
<!-- on Button-->
<Button
android:id="#+id/onBtn"
android:minWidth="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Turn On"
style="#style/Base.Widget.AppCompat.Button.Colored" />
<!-- off Button-->
<Button
android:id="#+id/offBtn"
android:minWidth="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Turn Off"
style="#style/Base.Widget.AppCompat.Button.Colored" />
<!-- Discoverable button-->
<Button
android:id="#+id/discoverableBtn"
android:minWidth="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Discoverable"
style="#style/Base.Widget.AppCompat.Button.Colored" />
<!-- Get list of paired devices button-->
<Button
android:id="#+id/pairedBtn"
android:minWidth="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Paired Devices"
style="#style/Base.Widget.AppCompat.Button.Colored" />
<!-- Show paired devices here-->
<TextView
android:id="#+id/pairedTv"
android:minWidth="200dp"
android:text=""
android:textColor="#000"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Currently the recommended approach is using a ActivityResultLauncher to get the results like so:
ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Log.e("Activity result","OK");
// There are no request codes
Intent data = result.getData();
}
});
so just call it like:
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activityResultLauncher.launch(intent);
and for your case assuming everything else is working fine ,you update to something like below:
package com.example.bluetoothexamples;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import android.app.Activity;
import android.util.Log;
import java.util.Set;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_DISCOVER_BT = 1;
TextView mStatusBlueTv;
TextView mPairedTv;
ImageView mBlueIv;
Button mOnBtn;
Button mOffBtn;
Button mDiscoverBtn;
Button mPairedBtn;
BluetoothAdapter mBlueAdapter;
ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Log.e("Activity result","OK");
// There are no request codes
Intent data = result.getData();
}
});
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStatusBlueTv = findViewById(R.id.statusBluetoothTv);
mPairedTv = findViewById(R.id.pairedTv);
mBlueIv = findViewById(R.id.bluetoothIv);
mOnBtn = findViewById(R.id.onBtn);
mOffBtn = findViewById(R.id.offBtn);
mDiscoverBtn = findViewById(R.id.discoverableBtn);
mPairedBtn = findViewById(R.id.pairedBtn);
// Adapter
mBlueAdapter = BluetoothAdapter.getDefaultAdapter();
//Check if bluetooth is available or not
if (mBlueAdapter == null) {
mStatusBlueTv.setText("Bluetooth is NOT Available");
} else {
mStatusBlueTv.setText("Bluetooth is Available");
// Set image according to bluetooth status (on/off)
if (mBlueAdapter.isEnabled()) {
mBlueIv.setImageResource(R.drawable.ic_action_on);
} else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
mOnBtn.setOnClickListener(this); // Turn on Bluetooth btn click
mDiscoverBtn.setOnClickListener(this); // Discover bluetooth btn click
mOffBtn.setOnClickListener(this); // Turn off Bluetooth btn click
mPairedBtn.setOnClickListener(this); // Get Paired devices button click
}
}
#Override
public void onClick(View view) {
switch (view.getId()) {
// Turn on Bluetooth btn click
case R.id.onBtn:
if (!mBlueAdapter.isEnabled()) {
// showToast("Turning On Bluetooth...");
// if (getApplicationContext().checkSelfPermission(Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) {
// } else {
// requestPermissions(new String[]{Manifest.permission.BLUETOOTH_ADMIN},1);
// }
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.BLUETOOTH_ADMIN},1);
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
// Intent to On Bluetooth
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
// startActivityForResult(intent, REQUEST_ENABLE_BT);
activityResultLauncher.launch(intent);
}
else {
showToast("Bluetooth is already on");
}
break;
// Discover bluetooth btn click
case R.id.discoverableBtn:
if (!mBlueAdapter.isDiscovering()){
showToast("Making Your Device Discoverable");
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//startActivityForResult(intent ,REQUEST_DISCOVER_BT);
activityResultLauncher.launch(intent);
}
break;
// Turn off Bluetooth btn click
case R.id.offBtn:
if (mBlueAdapter.isEnabled()) {
mBlueAdapter.disable();
showToast("Turning Bluetooth Off");
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
else {
showToast("Bluetooth is already off");
}
break;
// Get Paired devices button click
case R.id.pairedBtn:
if (mBlueAdapter.isEnabled()) {
mPairedTv.setText("Paired Devices");
Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
for (BluetoothDevice device: devices){
mPairedTv.append("\nDevice: " + device.getName() + ", " + device);
}
}
else {
//bluetooth is off so can't get paired devices
showToast("Turn ON Bluetooth to get paired devices");
}
break;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
showToast("Permission Granted");
}
else {
showToast("Permission Denied");
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
switch (requestCode){
case REQUEST_ENABLE_BT:
if (resultCode == RESULT_OK) {
// Bluetooth is on
mBlueIv.setImageResource(R.drawable.ic_action_on);
showToast("Bluetooth is on");
}
else {
showToast("Failed to connect to bluetooth");
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
//Toast message function
private void showToast (String msg) {
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
for java <8 :
ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Log.e("Activity result", "OK");
// There are no request codes
Intent data = result.getData();
}
}
}
);

Samsung 10 plus won't allow wifi p2p discovery

I wrote an Android app to allow a device to discover nearby devices via Wi-Fi P2P discovery. I am following this doc.
The app works beautifully on my Samsung Tab E tablet -- I am able to scan and find other devices when the app is running on the tablet. But I am unable to even activate the peer discovery process when running the app on my Samsung Galaxy S10 Plus. My Samsung s10 Plus won't even appear on my tablet's list of available peers unless I manually go into my Galaxy S10 Plus's settings and enable Wi-Fi Discovery Mode. At that point, my Tab E tablet can "see" my Galaxy S10 Plus, but as soon as I exit the settings screen on the Galaxy s10 Plus, Wi-Fi discovery is turned back off and I am no longer able to see it as a potential p2p peer.
Is there a way to allow peer discovery on a Samsung s10 Plus? I am unable to test out my app without it and would rather not have to purchase another Tab E to test p2p connectivity.
Below is the code my app is running for reference:
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
Button btnOnOff, btnDiscover, btnSend;
ListView listView;
TextView read_msg_box, connectionStatus;
EditText writeMsg;
//For programmatically turning wifi on and off:
WifiManager wifiManager;
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
BroadcastReceiver mReceiver;
IntentFilter mIntentFilter = new IntentFilter();
//For keeping track of available clients to connect to
List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
String[] deviceNameArray;
WifiP2pDevice[] deviceArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initialWork();
//initializeButtonOnClickListeners();
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
btnDiscover = (Button)findViewById(R.id.discover);
connectionStatus = (TextView) findViewById(R.id.connectionStatus);
// btnSend = (Button)findViewById(R.id.sendButton);
listView = (ListView)findViewById(R.id.peerListView);
// read_msg_box = (TextView) findViewById(R.id.readMsg);
// writeMsg = (EditText)findViewById(R.id.writeMsg);
wifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
initializeOnClickListeners();
}
private void initializeOnClickListeners() {
//Set up functionality for when the discover button is clicked.
btnDiscover.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "looking for a new peer", Toast.LENGTH_SHORT).show();
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
connectionStatus.setText("Discovery Started");
}
#Override
public void onFailure(int reason) {
connectionStatus.setText("Discovery Failed to start");
}
});
}
});
}
//Define the logic for when a new peer is discovered
WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
if(!peerList.getDeviceList().equals(peers)) {
//clear the peers
peers.clear();
//store device list
peers.addAll(peerList.getDeviceList());
deviceNameArray = new String[peerList.getDeviceList().size()];
deviceArray = new WifiP2pDevice[peerList.getDeviceList().size()];
int index = 0;
for(WifiP2pDevice device : peerList.getDeviceList()) {
deviceNameArray[index] = device.deviceName;
deviceArray[index] = device;
index++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1,
deviceNameArray);
listView.setAdapter(adapter);
}
if(peers.size() == 0) {
Toast.makeText(getApplicationContext(), "No Devices Found :(", Toast.LENGTH_SHORT).show();
}
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
}
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.p2p.WifiP2pManager;
import android.widget.Toast;
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity mActivity;
WifiP2pManager.PeerListListener myPeerListListener;
public WiFiDirectBroadcastReceiver(WifiP2pManager mManager, WifiP2pManager.Channel mChannel, MainActivity mActivity) {
this.mManager = mManager;
this.mChannel = mChannel;
this.mActivity = mActivity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
System.out.println("The following action was received: " + action);
if(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)){
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
//if wifi is enabled
if(state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
Toast.makeText(context, "Wifi is ON", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "Wifi is OFF", Toast.LENGTH_LONG).show();
}
} else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
Toast.makeText(context, "INSIDE THE P2P_PEERS_CHANGED_ACTION", Toast.LENGTH_LONG).show();
if(mManager != null) {
mManager.requestPeers(mChannel, mActivity.peerListListener);
Toast.makeText(context, "A new peer has been found!!!", Toast.LENGTH_LONG).show();
}
} else if(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
//do something
} else if(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
//do something
}
}
}
I don't code in Android for sometimes, but I think my experience might still valid, you can give it a try.
Correct me if I'm wrong, so, you have developed an app that allows your devices to discover and connect to each other, without the need to access to the phone's settings. For your S10, you have installed and opened the app, but you cannot discover it via your Tab, unless you manually switch it on in the settings?
First, ensure your app has all the required permission added and requested when using the app.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.nsdchat"
...
<uses-permission
android:required="true"
android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission
android:required="true"
android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission
android:required="true"
android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission
android:required="true"
android:name="android.permission.INTERNET"/>
Just to make sure your app has the permission, add the permission to the code below for the respective permission:
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.CHANGE_WIFI_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
}
...
Second, look at the code library version. Since s10 + is fairly new, Android has actually enhanced the privacy and security starting from Android 8.0. The code you wrote might be outdated due to the library version, and some APIs might be deprecated.

Getting GoogleApiClient to work with Activity Recognition

I am currently working with ActivityRecognitionClient , but unfortunately that Google has announced that the class had been deprecated and to use GoogleApiClient instead.
Not sure if I am doing it wrong or not, I am getting confused with the new API file. I have imported the Google Play Libraries, setup the API v2 key. I followed an online source on coding up the ActivityRecognitionClient version.
Below are the codes of the different files, whenever I switch tab to the actRecog it crashes and points the error to this line with a null pointer exception.
mActivityRecognitionPendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Full source code below : (API v2 keys are intentionally hidden for privacy purposes.)
MainActivity.java
package com.example.healthgps;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.app.Activity;
import android.app.TabActivity;
import android.content.Context;
import android.content.Intent;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
public class MainActivity extends TabActivity {
TabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabHost = getTabHost();
TabSpec firstSpec = mTabHost.newTabSpec("Stats");
firstSpec.setIndicator("Stats");
Intent firstIntent = new Intent(this, FirstActivity.class);
firstSpec.setContent(firstIntent);
TabSpec thirdSpec = mTabHost.newTabSpec("ActRecog");
thirdSpec.setIndicator("ActRecog");
Intent thirdIntent = new Intent(this, activityrecignition.class);
thirdSpec.setContent(thirdIntent);
mTabHost.addTab(firstSpec);
mTabHost.addTab(thirdSpec);
}
}
Manifest XML File :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.healthgps"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<permission
android:name="com.example.healthgps.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="com.example.healthgps.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
<activity
android:name="com.example.healthgps.MainActivity"
android:label="Health Kit"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".FirstActivity"
android:label="Health Kit" >
</activity>
<activity
android:name=".activityrecignition"
android:label="Health Kit" >
</activity>
<service
android:name="com.example.healthgps.ActivityRecognitionIntentService"
android:label="#string/app_name"
android:exported="false">
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
activityrecignition.java (purposely typo for the name)
package com.example.healthgps;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.ActivityRecognition;
import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity;
public class activityrecignition extends FragmentActivity implements ConnectionCallbacks,OnConnectionFailedListener {
public static final int MILLISECONDS_PER_SECOND = 1000;
public static final int DETECTION_INTERVAL_SECONDS = 20;
public static final int DETECTION_INTERVAL_MILLISECONDS =
MILLISECONDS_PER_SECOND * DETECTION_INTERVAL_SECONDS;
private final static int
CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private PendingIntent mActivityRecognitionPendingIntent;
// Store the current activity recognition client
private GoogleApiClient mGoogleApiClient;
private Context mContext;
private Intent intent;
TextView tv;
ActivityRecognitionIntentService ar;
private boolean mInProgress;
public enum REQUEST_TYPE {START, STOP}
private REQUEST_TYPE mRequestType;
Intent i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third);
mActivityRecognitionPendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
tv=(TextView) findViewById(R.id.activityname);
mInProgress=false;
ar.onHandleIntent(i);
}
#SuppressLint("NewApi") public static class ErrorDialogFragment extends DialogFragment {
private Dialog mDialog;
#SuppressLint("NewApi") public ErrorDialogFragment() {
super();
mDialog = null;
}
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
public void show(FragmentManager supportFragmentManager, String tag) {
}
}
#Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST :
switch (resultCode) {
case Activity.RESULT_OK :
break;
}
}
}
private boolean servicesConnected() {
int resultCode =
GooglePlayServicesUtil.
isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == resultCode) {
Log.d("Activity Recognition", "Google Play services is available.");
return true;
} else {
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
resultCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(
getSupportFragmentManager(),
"Activity Recognition");
}
return false;
}
}
public class ActivityRecognitionIntentService extends IntentService {
public ActivityRecognitionIntentService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
private String getNameFromType(int activityType) {
switch(activityType) {
case DetectedActivity.IN_VEHICLE:
return "in_vehicle";
case DetectedActivity.ON_BICYCLE:
return "on_bicycle";
case DetectedActivity.ON_FOOT:
return "on_foot";
case DetectedActivity.STILL:
return "still";
case DetectedActivity.UNKNOWN:
return "unknown";
case DetectedActivity.TILTING:
return "tilting";
}
return "unknown";
}
#Override
protected void onHandleIntent(Intent intent) {
// If the incoming intent contains an update
if (ActivityRecognitionResult.hasResult(intent)) {
// Get the update
ActivityRecognitionResult result =
ActivityRecognitionResult.extractResult(intent);
// Get the most probable activity
DetectedActivity mostProbableActivity =
result.getMostProbableActivity();
/*
* Get the probability that this activity is the
* the user's actual activity
*/
int confidence = mostProbableActivity.getConfidence();
/*
* Get an integer describing the type of activity
*/
int activityType = mostProbableActivity.getType();
String activityName = getNameFromType(activityType);
tv.setText(activityName);
/*
* At this point, you have retrieved all the information
* for the current update. You can display this
* information to the user in a notification, or
* send it to an Activity or Service in a broadcast
* Intent.
*/
} else {
/*
* This implementation ignores intents that don't contain
* an activity update. If you wish, you can report them as
* errors.
*/
tv.setText("There are no updates!!!");
}
}
}
public void onClick(View v){
if(v.getId()==R.id.Start){
startUpdates();
}
if(v.getId()==R.id.Stop){
stopUpdates();
}
}
public void startUpdates() {
// Check for Google Play services
mRequestType = REQUEST_TYPE.START;
if (!servicesConnected()) {
return;
}
// If a request is not already underway
if (!mInProgress) {
// Indicate that a request is in progress
mInProgress = true;
// Request a connection to Location Services
mGoogleApiClient.connect();
//
} else {
/*
* A request is already underway. You can handle
* this situation by disconnecting the client,
* re-setting the flag, and then re-trying the
* request.
*/
mInProgress = true;
mGoogleApiClient.disconnect();
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
}
}
#Override
public void onConnected(Bundle dataBundle) {
// TODO Auto-generated method stub
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
/*
* Since the preceding call is synchronous, turn off the
* in progress flag and disconnect the client
*/
mInProgress = false;
mGoogleApiClient.disconnect();
switch (mRequestType) {
case START :
/*
* Request activity recognition updates using the
* preset detection interval and PendingIntent.
* This call is synchronous.
*/
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, DETECTION_INTERVAL_MILLISECONDS, mActivityRecognitionPendingIntent);
break;
case STOP :
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(mGoogleApiClient, mActivityRecognitionPendingIntent);
/*
* An enum was added to the definition of REQUEST_TYPE,
* but it doesn't match a known case. Throw an exception.
*/
default :
try {
throw new Exception("Unknown request type in onConnected().");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
mInProgress = false;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Turn off the request flag
mInProgress = false;
/*
* If the error has a resolution, start a Google Play services
* activity to resolve it.
*/
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (SendIntentException e) {
// Log the error
e.printStackTrace();
}
// If no resolution is available, display an error dialog
} else {
// Get the error code
int errorCode = connectionResult.getErrorCode();
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
errorCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment =
new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(
getSupportFragmentManager(),
"Activity Recognition");
}
}
}
public void stopUpdates() {
// Set the request type to STOP
mRequestType = REQUEST_TYPE.STOP;
/*
* Test for Google Play services after setting the request type.
* If Google Play services isn't present, the request can be
* restarted.
*/
if (!servicesConnected()) {
return;
}
// If a request is not already underway
if (!mInProgress) {
// Indicate that a request is in progress
mInProgress = true;
// Request a connection to Location Services
mGoogleApiClient.connect();
//
} else {
/*
* A request is already underway. You can handle
* this situation by disconnecting the client,
* re-setting the flag, and then re-trying the
* request.
*/
}
}
}
In the old code, it contains a part where the ActivityRecognitionClient requires an instantiation, but GoogleApiClient doesn't have.
Is there anyone who manage to switch over to the new API already ? I need some guide to get it there.
Thanks.
you must use GoogleApiClient.Builder in the following way
GoogleApiClient.Builder builder = new GoogleApiClient.Builder(<context>)
.addApi(<some api, i.e LocationServices.API>)
.addConnectionCallbacks(new ConnectionCallbacks() {
#Override
public void onConnectionSuspended(int arg) {}
#Override
public void onConnected(Bundle arg0) {
Intent intent = new Intent(getApplicationContext(), ActivityRecognitionService.class); // your custom ARS class
mPendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
ActivityRecognition.ActivityRecognitionApi
.requestActivityUpdates(mGoogleApiClient, ACTIVITY_RECOGNITION_INTERVAL, mPendingIntent);}
}
.addOnConnectionFailedListener(new OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult arg0) {
}
});
mGoogleApiClient = builder.build();
mGoogleApiClient.connect();

Categories

Resources