Android Wifi Direct detects peers but Peer List is empty - java

Everything works fine but when WifiP2pManager calls onPeersAvailable method (it calls it correctly) the Peers Device List is empty, which makes no sense because if the method is called, it's because a peer was discovered. :S
Is something wrong in my code? Thanks.
Main Activity, Broadcast Receiver, and Discovery:
public class Main extends Activity{
FileManager flManager;
Context ctx;
LinearLayout lay_found_users;
LinearLayout lay_conversations;
AddLayoutItem addLayoutItem = new AddLayoutItem();
private final String TAG = "Main";
//Wifi Direct
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
BroadcastReceiver mReceiver;
IntentFilter mIntentFilter;
WifiP2pManager.PeerListListener mPeerListListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_main);
ctx = getApplicationContext();
flManager = new FileManager(ctx);
//Wifi Direct
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);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mPeerListListener = new WifiP2pManager.PeerListListener(){
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList){
Log.i(TAG, "Peers available");
int size = peerList.getDeviceList().size();
Log.i(TAG, String.valueOf(size));
}
};
mReceiver = new WDBroadcastReceiver(mManager, mChannel, this, mPeerListListener);
WDDiscovery wdDiscovery = new WDDiscovery(mManager, mChannel);
wdDiscovery.discover();
}
#Override
protected void onResume(){
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
#Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(mReceiver);
}
public class WDBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private Main mActivity;
private final String TAG = this.getClass().getSimpleName();
private WifiP2pManager.PeerListListener mPeerListListener;
public WDBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel, Main activity, WifiP2pManager.PeerListListener peerListListener){
super();
this.mManager = manager;
this.mChannel = channel;
this.mActivity = activity;
this.mPeerListListener = peerListListener;
}
#Override
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)){
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED){
Log.i(TAG, "Wifi P2P Enabled");
} else {
Log.i(TAG, "Wifi P2P Disabled");
}
}else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)){
if (mManager != null){
mManager.requestPeers(mChannel, mPeerListListener);
Log.i(TAG, "Peer Discovered");
}
}else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){
// Respond to new connection or disconnections
}else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){
// Respond to this device's wifi state changing
}
}
}
public class WDDiscovery {
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
private final String TAG = this.getClass().getSimpleName();
public WDDiscovery(WifiP2pManager manager, WifiP2pManager.Channel channel) {
mManager = manager;
mChannel = channel;
}
public void discover() {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.i(TAG, "WiFi P2P Discovery successful");
}
#Override
public void onFailure(int reasonCode) {
Log.i(TAG, "WiFi P2P Discovery error");
}
});
}
}

In my case, I add
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
in manifest and give app the permission.
It works.

I was facing the same issue, the solution in my case was
add these two lines into Android Manifiest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
and make sure to ask for runtime permission of the location

Related

Cannot discover peers - Wifi Direct-

I want to have a connection between two android devices on the same local network and exchange data between them through my android app.
I used Wifi Direct Api with Broadcast receiver approach in order to get into that purpose, but for some reason the discoverPeers method does not get triggered.
This is the code for my MainActivity:
public class MainActivity extends AppCompatActivity {
private static MainActivity instance;
Button btnOnOff, btnDiscover, btnSend;
ListView listView;
TextView read_msg_box, connection_status;
EditText writeMessage;
WifiManager wifiManager;
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
BroadcastReceiver mReceiver;
IntentFilter mIntentFilter;
List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
String[] deviceNameArray;
WifiP2pDevice[] deviceArray;
WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
if (!peerList.getDeviceList().equals(peers)) {
peers.clear();
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 device Found", Toast.LENGTH_SHORT).show();
return;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialWork();
exqListener();
}
public static MainActivity getInstance() {
return instance;
}
private void exqListener() {
btnOnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (wifiManager.isWifiEnabled() == true) {
wifiManager.setWifiEnabled(false);
btnOnOff.setText("Set To OFF ");
} else {
wifiManager.setWifiEnabled(true);
btnOnOff.setText("Set To ON");
}
}
});
btnDiscover.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != 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.
return;
}
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
connection_status.setText("Discovery Started");
}
#Override
public void onFailure(int reason) {
connection_status.setText("Discovery Starting Failed");
}
});
}
});
}
private void initialWork() {
btnOnOff = (Button) findViewById(R.id.onOff);
btnDiscover = (Button) findViewById(R.id.discover);
btnSend = (Button) findViewById(R.id.sendButton);
read_msg_box = (TextView) findViewById(R.id.readMsg);
connection_status = (TextView) findViewById(R.id.connectionStatus);
writeMessage = (EditText) findViewById(R.id.writeMsg);
listView = (ListView) findViewById(R.id.peerListView);
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
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);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
}
And this is the one of the WifiDirectBroadcatReceiver:
public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private AppCompatActivity mActivity;
public WifiDirectBroadcastReceiver(WifiP2pManager mManager, WifiP2pManager.Channel mChannel, AppCompatActivity mActivity) {
this.mManager = mManager;
this.mChannel = mChannel;
this.mActivity = mActivity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
Toast.makeText(context, "Wifi is ON", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Wifi is OFF", Toast.LENGTH_SHORT).show();
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
Toast.makeText(context, "Dkhal hnaya bro", Toast.LENGTH_SHORT).show();
if (mManager != null) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != 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.
return;
}
mManager.requestPeers(mChannel, MainActivity.getInstance().peerListListener);
}
} 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
}
}
}
And this the permissions in AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
According to the code, there is a textView that should change its text once I press on the button btnDiscover, but when I do, nothing happens.
Knowing that I was turning my location service on before running the app, what would the error be ?
Every other approach to tackle the situation will be welcome.
Starting Android 11, certain permissions have to be requested during runtime, regardless of what's defined in your manifest. As the comments in your code point out, you should use requestPermissions to do so in your MainActivity and (optionally) react to the outcome using onRequestPermissionsResult.

Send bluetooth message via Android Studio

I'm trying to send a message via bluetooth in Android Studio. I've googled but I cannot find the answer. I want to send a message to a connected device.
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private ImageView bluetoothOnImageView;
private ImageView bluetoothOffImageView;
private TextView bluetoothOnOffTextView;
private BluetoothAdapter bluetoothAdapter;
private ListView listView;
private EditText messageEditText;
private ArrayList<String> deviceList = new ArrayList<String>();
private ArrayList<BluetoothDevice> deviceListBluetooth = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bluetoothOnImageView = findViewById(R.id.bluetoothOnImageView);
bluetoothOffImageView = findViewById(R.id.bluetoothOffImageView);
bluetoothOnOffTextView = findViewById(R.id.bluetoothOnOffTextView);
listView = findViewById(R.id.listView);
messageEditText = findViewById(R.id.messageEditText);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.startDiscovery();
checkBluetooth();
Toast.makeText(this, "Scanning devices...", Toast.LENGTH_SHORT).show();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
IntentFilter filterChange = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(receiverChange, filter);
listView.setOnItemClickListener(MainActivity.this);
}
private final BroadcastReceiver receiverChange = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 3 Cases
// 1: Bonded already
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
Log.d("BroadcastReceiver", "BOND_BONDED");
Toast.makeText(MainActivity.this, "Already connected to this device.", Toast.LENGTH_SHORT).show();
}
// 2: Creating a bond
if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
Log.d("BroadcastReceiver", "BOND_BONDING");
}
// 3: Breaking a bond
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
Log.d("BroadcastReceiver", "BOND_NONE");
Toast.makeText(MainActivity.this, "Broke connection to this device.", Toast.LENGTH_SHORT).show();
}
}
}
};
public void bluetoothSearchOnClick(View view) {
Toast.makeText(this, "Rescanning devices...", Toast.LENGTH_SHORT).show();
// Reset devices
deviceList.clear();
deviceListBluetooth.clear();
bluetoothAdapter.startDiscovery();
checkBluetooth();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
}
#Override
protected void onDestroy() {
unregisterReceiver(receiver);
unregisterReceiver(receiverChange);
super.onDestroy();
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String newDevice = device.getName() + "\n" + device.getAddress();
boolean duplicate = false;
// No duplicate devices
for (int i = 0; i < deviceList.size(); i++) {
if (newDevice.equals(deviceList.get(i))) {
duplicate = true;
}
}
if (!duplicate) {
deviceList.add(newDevice);
deviceListBluetooth.add(device);
}
Log.i("BT", device.getName() + "\n" + device.getAddress());
listView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, deviceList));
}
}
};
public void bluetoothOnOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.disable();
// Wait x milliseconds
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
checkBluetooth();
}
}, 500);
}
public void bluetoothOffOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.enable();
// Wait x milliseconds
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
checkBluetooth();
}
}, 500);
}
private void checkBluetooth() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
// Device does not support Bluetooth
Toast.makeText(this, "This device does not support Bluetooth", Toast.LENGTH_SHORT).show();
} else if (!bluetoothAdapter.isEnabled()) {
// Bluetooth is not enabled :)
bluetoothOnImageView.setVisibility(View.GONE);
bluetoothOffImageView.setVisibility(View.VISIBLE);
bluetoothOnOffTextView.setText("OFF");
bluetoothOnOffTextView.setTextColor(Color.RED);
} else {
// Bluetooth is enabled
bluetoothOffImageView.setVisibility(View.GONE);
bluetoothOnImageView.setVisibility(View.VISIBLE);
bluetoothOnOffTextView.setText("ON");
bluetoothOnOffTextView.setTextColor(Color.GREEN);
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
checkBluetooth();
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bluetoothAdapter.cancelDiscovery();
Log.d("Bluetooth Adapter", "onItemClick: You Clicked on a device.");
String[] device = deviceList.get(position).split("\n");
String deviceName = device[0];
// Bond
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
Log.d("Bluetooth Adapter", "Trying to pair with " + deviceName);
deviceListBluetooth.get(position).createBond();
}
}
public void sendButtonOnClick(View view) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Send message
}
}
In the method sendButtonOnClick(View view) is where I want to send the message. You can find this method at the bottom of the code.
Can anyone help me?
this is not so simple as you think (packing up messaging feature into one method). you need to connect to BluetoothSocket obtained from BluetoothDevice using createRfcommSocketToServiceRecord and knowing "messaging" UUID (you can list them with getUuids() method). after proper socket connection you can obtain input and output streams (getInputStream and getOutputStream), from which you can read and write bytes converting to text if you want. found pretty good sample in HERE, which is using separated Threads for Bluetooth communication making whole feature async and not hanging main/UI thread

Unable to fetch devices from WifiP2pDeviceList

I am just trying to implement Wifi P2P and I'm stuck on getting the peer list.
When I click on discover device Button then I just want to fetch all the devices append the list of devices to a string which I can output using a text view.
MainActivity.java
package com.example.lrmah.wifip2p;
public class MainActivity extends AppCompatActivity implements
WifiP2pManager.PeerListListener {
private List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
BroadcastReceiver mReceiver;
Button B;
TextView t;
IntentFilter mIntentFilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t=(TextView) findViewById(R.id.displayTextView);
B=(Button) findViewById(R.id.discoverPeers);
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);
B.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(getApplicationContext(),"success",Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
}
});
}
});
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
/* unregister the broadcast receiver */
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
List<WifiP2pDevice> refreshedPeers = (List<WifiP2pDevice>) peerList.getDeviceList();
if (!refreshedPeers.equals(peers)) {
peers.clear();
peers.addAll(refreshedPeers);
}
WifiP2pDevice device= refreshedPeers.get(0);
t.setText(device.deviceName);
if (peers.size() == 0) {
return;
}
}}
WifiDirectBroadcastReceiver
package com.example.lrmah.wifip2p;
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity mActivity;
WifiP2pManager.PeerListListener myPeerListListener;
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel,
MainActivity activity) {
super();
this.mManager = manager;
this.mChannel = channel;
this.mActivity = activity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
Toast.makeText(mActivity,"wifi is on",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(mActivity,"Please turn on wifi",Toast.LENGTH_LONG).show();
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
if (mManager != null) {
mManager.requestPeers(mChannel, mActivity);
}
}
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
// Respond to new connection or disconnections
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// Respond to this device's wifi state changing
}
}}
I may be wrong but I think the onPeerAvailable is not being called.
Some points:
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
// here you should call
NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected() && isSender) {
// connected with the other device, request connection info to find group owner IP
manager.requestConnectionInfo(channel, yourWifiP2pManager.ConnectionInfoListene);
}
else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// call discoverPeers here
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
if (manager != null) {
manager.requestPeers(channel, yourWifiP2pManager.PeerListListener);
}
}
#Override
public void onFailure(int reasonCode) {}
});
then the device list will be broadcast in
else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
WifiP2pDeviceList list = intent.getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST);
for (WifiP2pDevice d : list.getDeviceList()) { //...

How do I access deviceName and deviceHardwareAddress from within this object?

I have the following lines of code. I'm trying to access the Strings deviceName and deviceHarwareAddress. Do I need to construct a class that extends BroadcastReceiver and create a method within that which will return the code for me?
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
}
}
};
Not necessary. If you are limiting its use within a single component (say activity/fragment/service), you can keep "mReceiver" inside that component and then register mReceiver for that. That will work fine.
This is the case if you are doing it inside an activity.
public class BluetoothTest extends AppCompatActivity {
private ArrayList<BluetoothDevice> deviceList;
private BluetoothAdapter mBluetoothAdapter;
private ArrayList<DeviceItem> deviceItemList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.abc);
/**
* Do necessary coding to enable bluetooth
*/
registerReceiver();
startBluetoothDiscovery();
}
private void registerReceiver() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter dintentFilter = new IntentFilter();
dintentFilter.addAction(BluetoothDevice.ACTION_FOUND);
dintentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
dintentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mDiscoveryBroadcastReceiver, dintentFilter);
}
public void startBluetoothDiscovery() {
if (!mBluetoothAdapter.isDiscovering())
mBluetoothAdapter.startDiscovery();
}
public void setBluetoothDevice(BluetoothDevice device) {
if (!deviceList.contains(device))
deviceList.add(device);
}
public ArrayList<BluetoothDevice> getBluetoothDeviceList() {
return deviceList;
}
private void resetAll() {
deviceItemList.clear();
unregisterReceiver(mDiscoveryBroadcastReceiver);
}
private final BroadcastReceiver mDiscoveryBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Toast.makeText(getApplicationContext(), "Started discovery!!!", Toast.LENGTH_SHORT).show();
deviceList = new ArrayList<>();
deviceItemList.clear();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Toast.makeText(getApplicationContext(), "Finished discovery!!!", Toast.LENGTH_SHORT).show();
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
DeviceItem deviceItem = new DeviceItem(device.getName(),
device.getAddress(), device.getBluetoothClass(), device);
deviceItem.setBluetoothDevice(device);
/**
* To check if the device is in paired list or not
*/
if (mBluetoothAdapter.getBondedDevices().contains(device))
deviceItem.setPaired(true);
else
deviceItem.setPaired(false);
if (!deviceItemList.contains(deviceItem))
deviceItemList.add(deviceItem);
/**
* Once the device is found,it is added to a list
*/
setBluetoothDevice(device);
}
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
return id == R.id.action_settings;
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
}
In case of "service" you can make use of the binder or observer pattern for make the data available to the activity.

How to show the Bluetooth Le Device connected/Disconnected status constantly

I am trying to develop an application where the user can know the status of his/her Bluetooth Le device once he/she launches the app and the connection status is updated in text view in Home Fragment.I have tried to implement it by sending Broadcast from Ble service and catching it in onResume of Home fragment and subsequently updating it in status text view. The status does gets updated but if I change the fragment and come back to the home fragment the text view to show the status gets blank although the Bluetooth Le device is connected.How can I resolve this problem so that the status shows connected all through out if the device is connected and disconnected if it is disconnected?
Any Kind of guidance will be highly appreciated.
here are the code segments I have used to implement the above
In Bleservice.java
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
In HomeFragment.java
public class HomeFragment extends Fragment
{
private BroadcastReceiver mReceiver;
#Override
protected void onResume() {
super.onResume();
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Bleservice.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
} else if (Bleservice.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
}
}
};
getActivity().registerReceiver(mReceiver,makeGattUpdateIntentFilter());
}
private void updateConnectionState(final int resourceId) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
tv_connected_disconnected.setText(resourceId);
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
getActivity().unregisterReceiver(mReceiver);
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Bleservice.ACTION_GATT_CONNECTED);
intentFilter.addAction(Bleservice.ACTION_GATT_DISCONNECTED);
return intentFilter;
}
Connect to your BleService by bindService. Check out example with Activity and Service.
private BleService mBluetoothLeService;
private boolean isConnected;
#Override
protected void onStart() {
super.onStart();
Intent bindIntent = new Intent(this, BleService.class);
startService(bindIntent);
bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
registerServiceReceiver(); //register here your mGattCallback that get actions from BleService
}
#Override
protected void onStop() {
super.onStop();
unbindService(mServiceConnection);
mBluetoothLeService = null;
LocalBroadcastManager.getInstance(this).unregisterReceiver(mGattUpdateReceiver);
}
In method bindService you need to pass a ServiceConnection that manage Service Lifecycle.
// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BleService.LocalBinder) service).getService();
isConnected = (mBluetoothLeService.getConnectionState() != BleService.STATE_CONNECTED)
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
In Service you need to declare Binder.
private final IBinder mBinder = new LocalBinder();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public BleService getService() {
return BleService.this;
}
}
public int getConnectionState() {
return mConnectionState;
}
So now, after binding to BleService, you can get a connection state.

Categories