Android BLE devices not detecting each other - java

I am trying to use Google's Sample BLE library to send data between two LG Phoenix 4 phones, both running Android 7.1 and both BLE-compatible. I have successfully gotten the app onto both phones, but the phones cannot detect each other. I have tried this with 3 different phones so I know it's not a hardware issue. In the image below, I should see the other phone pop up on the list but when I run "Scan" on both devices, each screen pops up with a long list of devices in the area that doesn't include the other device. I have also tried pressing "Scan" on just one of the phones at a time, and I have done all of the above both while the phones are already paired over Bluetooth and while they are not already paired.
I have not changed Google's code. Looking through the library, it seems that the DeviceScanActivity.java file is probably where the issue is occurring:
package com.example.android.bluetoothlegatt;
import android.app.Activity;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
/**
* Activity for scanning and displaying available Bluetooth LE devices.
*/
public class DeviceScanActivity extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setTitle(R.string.title_devices);
mHandler = new Handler();
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (!mScanning) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
mLeDeviceListAdapter.clear();
scanLeDevice(true);
break;
case R.id.menu_stop:
scanLeDevice(false);
break;
}
return true;
}
#Override
protected void onResume() {
super.onResume();
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it.
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
// Initializes list view adapter.
mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter);
scanLeDevice(true);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onPause() {
super.onPause();
scanLeDevice(false);
mLeDeviceListAdapter.clear();
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
if (device == null) return;
final Intent intent = new Intent(this, DeviceControlActivity.class);
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
if (mScanning) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
mScanning = false;
}
startActivity(intent);
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
// Adapter for holding devices found through scanning.
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BluetoothDevice>();
mInflator = DeviceScanActivity.this.getLayoutInflater();
}
public void addDevice(BluetoothDevice device) {
if(!mLeDevices.contains(device)) {
mLeDevices.add(device);
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
#Override
public int getCount() {
return mLeDevices.size();
}
#Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.listitem_device, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
BluetoothDevice device = mLeDevices.get(i);
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
return view;
}
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
static class ViewHolder {
TextView deviceName;
TextView deviceAddress;
}
}

Be sure that your devices support Bluetooth LE multi broadcast.
Many devices support Bluetooth LE but not the multi broadcast feature.
You can install Beacon Simulator to be sure this feature is supported.
If yes, you should start the simulator to be discoverable.
See also this link
Android Beacon Library

Related

How do you merge the BluetoothLeGatt BLE Scanner with a map such that it is able to scan for BLE devices automatically at the backend?

I am working on this project where I am supposed to utilize Bluetooth beacons to create an indoor map with direction finding(mobile app). This is how the idea is supposed to go: mobile device interacting with BLE devices through BLE scanner, scanner gets the device information (MAC-address, rssi..etc) So far what I've done is I am able to make the scanner work and I have a map with an indoor floor plan layered.
What I am trying to do now is to integrate the BLE scanner with the map such that the scanner works at the backend automatically scanning and connecting to BLE devices, therefore using the information(specifically RSSI values) to work out the distance between the device and beacon. I am totally lost on what and how to do it as it is my first time developing a mobile application.
Here is the image of the map as stated above.
map with floor plan
So far I have only tried to copy the codes of the BLE scanner into the project of the map but I have no clue how to merge the two such that it gives me the above stated outcome
Here are the codes of the BLE scanner:
DeviceScanActivity.java
package com.example.android.bluetoothlegatt;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
/**
* Activity for scanning and displaying available Bluetooth LE devices.
*/
public class DeviceScanActivity extends ListActivity {
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 123;
private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setTitle(R.string.title_devices);
mHandler = new Handler();
//need to be able to access location before can scan
//for when build ver sdk 23+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (!mScanning) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
mLeDeviceListAdapter.clear();
scanLeDevice(true);
break;
case R.id.menu_stop:
scanLeDevice(false);
break;
}
return true;
}
#Override
protected void onResume() {
super.onResume();
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it.
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
// Initializes list view adapter.
mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter);
scanLeDevice(true);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onPause() {
super.onPause();
scanLeDevice(false);
mLeDeviceListAdapter.clear();
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
if (device == null) return;
final Intent intent = new Intent(this, DeviceControlActivity.class);
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
if (mScanning) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
mScanning = false;
}
startActivity(intent);
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
// Adapter for holding devices found through scanning.
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BluetoothDevice>();
mInflator = DeviceScanActivity.this.getLayoutInflater();
}
public void addDevice(BluetoothDevice device) {
if(!mLeDevices.contains(device)) {
mLeDevices.add(device);
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
#Override
public int getCount() {
return mLeDevices.size();
}
#Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.listitem_device, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
BluetoothDevice device = mLeDevices.get(i);
final String deviceName = device.getName();
final String deviceAddress = device.getAddress();
if (deviceName != null && deviceName.length() > 0 && deviceAddress.contains("00:15:88:07"))
viewHolder.deviceName.setText(device.getName());
else
viewHolder.deviceName.setText(R.string.unknown_device);
// viewHolder.deviceAddress.setText(R.string.invalid_address);
viewHolder.deviceAddress.setText(device.getAddress());
return view;
}
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
static class ViewHolder {
TextView deviceName;
TextView deviceAddress;
}
}
I would appreciate if anyone could help me with this problem I have been trying to solve for the past few days. Thank you very much!

Media Player not playing sound properly in Android on charger connection

I am new to software developing and i am trying to make an application that will play a sound when it charges. The first time i connect it to the charging cable, it plays the sound two times, which is not expected. Also, when i connect and disconnect the cable too quick, it also plays it twice.
Does anyone know the solution to this problem?
package com.mccharginggimmick;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.BatteryManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
IntentFilter intentFilter;
BroadcastReceiver broadcastReceiver;
MediaPlayer mediaPlayerOff;
MediaPlayer mediaPlayerOn;
boolean playedOnceOn;
boolean playedOnceOff;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
if(isCharging){
onCharge();
}
else{
onDisconnect();
}
}
};
MainActivity.this.registerReceiver(broadcastReceiver, intentFilter);
}
public void onCharge(){
if(!playedOnceOn){
imageView.setVisibility(View.INVISIBLE);
mediaPlayerOn = MediaPlayer.create(this, R.raw.btnon);
mediaPlayerOn.start();
mediaPlayerOn.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayerOn.stop();
playedOnceOn = true;
playedOnceOff = false;
}
});
}
}
public void onDisconnect(){
if(!playedOnceOff){
imageView.setVisibility(View.VISIBLE);
mediaPlayerOff = MediaPlayer.create(this, R.raw.btnoff);
mediaPlayerOff.start();
mediaPlayerOff.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayerOff.stop();
playedOnceOff = true;
playedOnceOn = false;
}
});
}
}
}
define isCabelConnected inside class
boolean isCabelConnected = false;
then in your onClick
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING;
boolean isFullCharged = status == BatteryManager.BATTERY_STATUS_FULL;
if(isCharging && !isCabelConnected){
onCharge();
isCabelConnected = true;
} else if (isFullCharged && isCabelConnected){
onCharge();
}
else{
onDisconnect();
isCabelConnected = false;
}
this code will make a sound when cable connected and another sound when full charge

maketext is not applicable for arguments

I am writing one app to display user's current address based on latitude and longitude but i am getting one error in this code on line Toast.makeText(this, "No address found try again", Toast.LENGTH_SHORT).show(); It's saying makeText in the type toast is not applicable for arguments. I am unbable to resolve this error.
Any help??
I am trying to display user address in a TextView, but i am not sure whether i am doing good or some runtime error may occur in future.
Here is my Main activity java code:
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationServices;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnItemSelectedListener, ConnectionCallbacks, OnConnectionFailedListener{
private static final int REQUEST_RESOLVE_ERROR = 1001;
private static final String DIALOG_ERROR = "dialog_error";
private static final String STATE_RESOLVING_ERROR = "resolving_error";
GoogleApiClient mGoogleApiClient;
protected Location mLastLocation;
private boolean mResolvingError=false;
private AddressResultReceiver mResultReceiver;
// Request code to use when launching the resolution activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner = (Spinner) findViewById(R.id.shop_category);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.shop_category, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
mResolvingError = savedInstanceState != null
&& savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
TextView mytext = (TextView) view;
Toast.makeText(this,"You selected "+mytext.getText(),Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
protected void startIntentService() {
Intent intent = new Intent(this, FetchAddressIntentService.class);
intent.putExtra(Constants.RECEIVER, mResultReceiver);
intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation);
startService(intent);
}
#Override
public void onConnected(Bundle arg0) {
boolean mAddressRequested=false;
// TODO Auto-generated method stub
TextView myLatitude = (TextView)findViewById(R.id.lat_value);
TextView myLongitude = (TextView)findViewById(R.id.lang_value);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
myLatitude.setText(String.valueOf(mLastLocation.getLatitude()));
myLongitude.setText(String.valueOf(mLastLocation.getLongitude()));
if (!Geocoder.isPresent()) {
Toast.makeText(this, R.string.no_geocoder_available,
Toast.LENGTH_LONG).show();
return;
}
else{
mAddressRequested=true;
if (mAddressRequested) {
startIntentService();
}
}
}
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
if (mResolvingError) {
Toast.makeText(this, "Resolving errors", Toast.LENGTH_SHORT).show();
return;
} else if (result.hasResolution()) {
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GoogleApiAvailability.getErrorDialog()
showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}
private void showErrorDialog(int errorCode) {
// Create a fragment for the error dialog
ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
// Pass the error that should be displayed
Bundle args = new Bundle();
args.putInt(DIALOG_ERROR, errorCode);
dialogFragment.setArguments(args);
dialogFragment.show(getFragmentManager(), "errordialog");
}
public void onDialogDismissed() {
mResolvingError = false;
}
public static class ErrorDialogFragment extends DialogFragment {
public ErrorDialogFragment() { }
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the error code and retrieve the appropriate dialog
int errorCode = this.getArguments().getInt(DIALOG_ERROR);
return GoogleApiAvailability.getInstance().getErrorDialog(
this.getActivity(), errorCode, REQUEST_RESOLVE_ERROR);
}
#Override
public void onDismiss(DialogInterface dialog) {
((MainActivity) getActivity()).onDialogDismissed();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_RESOLVE_ERROR) {
mResolvingError = false;
if (resultCode == RESULT_OK) {
if (!mGoogleApiClient.isConnecting() &&
!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
class AddressResultReceiver extends ResultReceiver {
public AddressResultReceiver(Handler handler) {
super(handler);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// Display the address string
// or an error message sent from the intent service.
String mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
// Show a toast message if an address was found.
if (resultCode == Constants.SUCCESS_RESULT) {
TextView myaddress=(TextView) findViewById(R.id.myaddress);
myaddress.setText(mAddressOutput);
}
else{
Toast.makeText(this, "No address found try again", Toast.LENGTH_SHORT).show();
}
}
}
}
Thank you in advance.
Replace this with MainActivity.this as the first parameter to your makeText() call. this is an instance of your AddressResultReceiver inner class. It is not your activity, and makeText() needs a Context, like an Activity.
Use getApplicationContext() instead of this. Use:
Toast.makeText(getApplicationContext(), "message", Toast.LENGTH_SHORT).show();
this refers to AddressResultReceiver which is not subclass of Context.
Toast.makeText() needs Context.

BLE (Bluetooth Low Energy) not able to find another BLE device

I am trying to scan another BLE device, but it is not finding another BLE device.
Instead, it scanned a Bluetooth device with api <18.
This is my code :
package com.example.blescan;
import java.util.ArrayList;
import android.app.Activity;
import android.app.ListActivity;
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.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class DeviceScanActivity extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setTitle(getString(R.string.app_name));
mHandler = new Handler();
// Use this check to determine whether BLE is supported on the device.
// Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT)
.show();
finish();
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a
// reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported,
Toast.LENGTH_SHORT).show();
finish();
return;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (!mScanning) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
mLeDeviceListAdapter.clear();
scanLeDevice(true);
break;
case R.id.menu_stop:
scanLeDevice(false);
break;
}
return true;
}
#Override
protected void onResume() {
super.onResume();
// Ensures Bluetooth is enabled on the device. If Bluetooth is not
// currently enabled,
// fire an intent to display a dialog asking the user to grant
// permission to enable it.
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
// Initializes list view adapter.
mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter);
scanLeDevice(true);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT
&& resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onPause() {
super.onPause();
scanLeDevice(false);
mLeDeviceListAdapter.clear();
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
// Adapter for holding devices found through scanning.
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BluetoothDevice>();
mInflator = DeviceScanActivity.this.getLayoutInflater();
}
public void addDevice(BluetoothDevice device) {
if (!mLeDevices.contains(device)) {
mLeDevices.add(device);
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
#Override
public int getCount() {
return mLeDevices.size();
}
#Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.listitem_device, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView) view
.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView) view
.findViewById(R.id.device_name);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
BluetoothDevice device = mLeDevices.get(i);
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
return view;
}
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
static class ViewHolder {
TextView deviceName;
TextView deviceAddress;
}
// ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
// ACTION_DATA_AVAILABLE: received data from the device. This can be
// result of read or notification operations.
}
These are the requested permissions:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Please help me.

Finding Miracast connections with Android

I am trying to build an Android app that scans for local Miracast connections and connects to them to mirror the screen automatically. I also want the ability to save connections that the user has already connected to before and give them nicknames so the user can recognize them easier. I don't have hardly any experience with Android development, but I have years of experience with Java and other languages.
Right now, the problem I have is my ListView returns a null pointer exception when I try to set the Adapter in the OnCreate method of my MainActivity.
MainActivity.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import android.app.Fragment;
import android.app.Presentation;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.hardware.display.DisplayManager;
import android.media.MediaRouter;
import android.net.NetworkInfo;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.ChannelListener;
import android.net.wifi.p2p.WifiP2pManager.GroupInfoListener;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends FragmentActivity implements OnSharedPreferenceChangeListener{
public static final String TAG = "MainActivity";
private MediaRouter mMediaRouter;
private WifiP2pManager wifimngr;
protected Channel channel;
private boolean paused = false;
private boolean connected = false;
private boolean scanning = false;
protected boolean isWifiEnabled;
protected boolean onCharge;
protected boolean onAlways;
protected MyBroadcastReceiver receiver;
protected ArrayList<WifiP2pDevice> connectionList;
protected int listsize;
private DisplayManager mDisplayManager;
protected ConnectionAdapter adapter;
protected ArrayList<WifiP2pDevice> devices;
private final IntentFilter intentFilter = new IntentFilter();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connectionList = new ArrayList<WifiP2pDevice>();
adapter = new ConnectionAdapter(this, devices);
ListView listview = (ListView) findViewById(R.id.list);
listview.setAdapter(adapter);
//Connection newCon = new Connection("My address", "My nickname", false);
//adapter.add(newCon);
//newCon = new Connection("My address2", "My nickname2", true);
//adapter.add(newCon);
// Indicates a change in the Wi-Fi P2P status.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
// Indicates a change in the list of available peers.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
// Indicates the state of Wi-Fi P2P connectivity has changed.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
// Indicates this device's details have changed.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
mDisplayManager = (DisplayManager)this.getSystemService(Context.DISPLAY_SERVICE);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
wifimngr = (WifiP2pManager)getSystemService(Context.WIFI_P2P_SERVICE);
channel = wifimngr.initialize(this, getMainLooper(), new ChannelListener() {
public void onChannelDisconnected() {
channel = null;
}
});
}
PeerListListener myPeerListListener =
new PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
// Out with the old, in with the new.
devices.clear();
devices.addAll(peerList.getDeviceList());
// If an AdapterView is backed by this data, notify it
// of the change. For instance, if you have a ListView of available
// peers, trigger an update.
//((ConnectionAdapter) getListAdapter()).notifyDataSetChanged();
if (devices.size() == 0) {
Log.d("TAG", "No devices found");
return;
}
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
openSettings();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
public void updateStatus(String input)
{
TextView edit = (TextView) findViewById(R.id.statusText);
edit.setText(input);
}
//What happens when the pause button is clicked
public void pauseConnections(View view)
{
if(!paused)
{
updateStatus("Streaming");
mMediaRouter = (MediaRouter) this.getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(mMediaRouter.ROUTE_TYPE_LIVE_VIDEO);
if (route != null) {
Display presentationDisplay = route.getPresentationDisplay();
if (presentationDisplay != null) {
Presentation presentation = new Presentation(this, presentationDisplay, 0);
presentation.show();
}
}
ProgressBar pg = (ProgressBar) findViewById(R.id.progressBar1);
pg.setVisibility(View.VISIBLE);
Button edit = (Button) findViewById(R.id.pauseButton);
edit.setText("Pause");
edit = (Button) findViewById(R.id.scanbutton);
edit.setEnabled(false);
}else
{
updateStatus("Paused");
MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(mMediaRouter.ROUTE_TYPE_LIVE_VIDEO);
if (route != null) {
Display presentationDisplay = route.getPresentationDisplay();
if (presentationDisplay != null) {
Presentation presentation = new Presentation(this, presentationDisplay, 0);
presentation.show();
}
}
ProgressBar pg = (ProgressBar) findViewById(R.id.progressBar1);
pg.setVisibility(View.INVISIBLE);
Button edit = (Button) findViewById(R.id.pauseButton);
edit.setText("Stream");
edit = (Button) findViewById(R.id.scanbutton);
edit.setEnabled(true);
}
paused=!paused;
}
//What happens when the scan button is clicked
public void scanConnections(View view)
{
if(!scanning)
{
updateStatus("Scanning...");
ProgressBar pg = (ProgressBar) findViewById(R.id.progressBar1);
pg.setVisibility(View.VISIBLE);
wifimngr.setMiracastMode(1);
wifimngr.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
}
#Override
public void onFailure(int reason) {
if(reason == 1)
{
updateStatus("Failed to get devices. Device not supported");
}else if(reason == 2)
{
updateStatus("Failed to get devices. Busy");
}else
{
updateStatus("Failed to get devices. Error");
}
ProgressBar pg = (ProgressBar) findViewById(R.id.progressBar1);
pg.setVisibility(View.INVISIBLE);
Button edit = (Button) findViewById(R.id.scanbutton);
edit.setText("Scan");
edit = (Button) findViewById(R.id.pauseButton);
edit.setEnabled(true);
scanning=!scanning;
}
});
Button edit = (Button) findViewById(R.id.scanbutton);
edit.setText("Stop");
edit = (Button) findViewById(R.id.pauseButton);
edit.setEnabled(false);
}else
{
ProgressBar pg = (ProgressBar) findViewById(R.id.progressBar1);
pg.setVisibility(View.INVISIBLE);
wifimngr.removeGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
}
#Override
public void onFailure(int reason) {
if(reason == 1)
{
updateStatus("Failed to disconnect. Device not supported");
}else if(reason == 2)
{
updateStatus("Failed to disconnect. Busy");
}else
{
updateStatus("Failed to disconnect. Error");
}
ProgressBar pg = (ProgressBar) findViewById(R.id.progressBar1);
pg.setVisibility(View.INVISIBLE);
}
});
updateStatus("Waiting");
Button edit = (Button) findViewById(R.id.scanbutton);
edit.setText("Scan");
edit = (Button) findViewById(R.id.pauseButton);
edit.setEnabled(true);
}
scanning=!scanning;
}
public void openSettings()
{
Intent intent = new Intent(this, SettingsActivity.class);
intent.putExtra("onCharge", onCharge);
intent.putExtra("onAlways", onAlways);
startActivity(intent);
}
public void onCheckboxClicked(View view)
{
boolean checked = ((CheckBox) view).isChecked();
}
public void onConnectionClick(View view)
{
DialogFragment dialog = new ConnDialogFragment();
dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key.equals("pref_onCharge")) {
// Set summary to be the user-description for the selected value
onCharge = sharedPreferences.getBoolean(key, true);
}else if (key.equals("pref_onAlways")) {
// Set summary to be the user-description for the selected value
onAlways = sharedPreferences.getBoolean(key, false);
}else if(key.equals("pref_listsize"))
{
listsize = sharedPreferences.getInt(key, 0);
}
}
private void onPeersChanged(Intent intent)
{
wifimngr.requestPeers(channel, myPeerListListener);
}
private void onConnectionChanged(Intent intent) {
WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
NetworkInfo netInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (netInfo.isConnected())
{
updateInfos();
useNetwork(p2pInfo);
} else
{
//resetInfos();
}
}
public void connect() {
// Picking the first device found on the network.
WifiP2pDevice device = devices.get(0);
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
wifimngr.connect(channel, config, new ActionListener() {
#Override
public void onSuccess() {
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
#Override
public void onFailure(int reason) {
Toast.makeText(MainActivity.this, "Connect failed. Retry.",
Toast.LENGTH_SHORT).show();
}
});
}
public void onConnectionInfoAvailable(final WifiP2pInfo info) {
// InetAddress from WifiP2pInfo struct.
InetAddress groupOwnerAddress = info.groupOwnerAddress;
// After the group negotiation, we can determine the group owner.
if (info.groupFormed && info.isGroupOwner) {
// Do whatever tasks are specific to the group owner.
// One common case is creating a server thread and accepting
// incoming connections.
} else if (info.groupFormed) {
// The other device acts as the client. In this case,
// you'll want to create a client thread that connects to the group
// owner.
}
}
private void updateInfos() {
wifimngr.requestGroupInfo(channel,
new GroupInfoListener() {
#Override
public void onGroupInfoAvailable(WifiP2pGroup group)
{
String name = group.getNetworkName();
String passphrase = group.getPassphrase();
Collection<WifiP2pDevice> devices = group.getClientList();
// do stuff with devices
// but ... No way to get their IP addresses :(
}
});
}
private void useNetwork(WifiP2pInfo p2pInfo) {
if (!p2pInfo.isGroupOwner) {
InetAddress addr = p2pInfo.groupOwnerAddress;
try
{
Socket s = new Socket(addr, 1234);
}catch(IOException e)
{
e.printStackTrace();
}
//use the socket
} else {
try{
//groupOwnerAddress is our local address
ServerSocket serverSocket = new ServerSocket(1234);
Socket s = serverSocket.accept();
}catch(IOException e)
{
e.printStackTrace();
}
//use the socket
}
}
private void connect(WifiP2pDevice device) {
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC; // choose between what is available on the device.
wifimngr.connect(channel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
}
#Override
public void onFailure(int reason) {
}
});
}
protected void setIsWifiP2pEnabled(boolean isEnabled)
{
isWifiEnabled = isEnabled;
}
/** register the BroadcastReceiver with the intent values to be matched */
#Override
public void onResume() {
super.onResume();
receiver = new MyBroadcastReceiver(wifimngr, channel, this);
registerReceiver(receiver, intentFilter);
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
}
ConnectionAdapter.java
import java.util.ArrayList;
import android.content.Context;
import android.net.wifi.p2p.WifiP2pDevice;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class ConnectionAdapter extends ArrayAdapter<WifiP2pDevice> {
public ConnectionAdapter(Context context, ArrayList<WifiP2pDevice> connections)
{
super(context, R.layout.connection, connections);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
WifiP2pDevice con = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.connection, parent, false);
viewHolder.name = (TextView) convertView.findViewById(R.id.conName);
viewHolder.nickname = (TextView) convertView.findViewById(R.id.conNickname);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data into the template view using the data object
viewHolder.name.setText(con.deviceName);
viewHolder.nickname.setText(con.primaryDeviceType);
// Return the completed view to render on screen
return convertView;
}
private static class ViewHolder {
TextView name;
TextView nickname;
}
}
**BroadcastReceiver.java**
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.util.Log;
public class MyBroadcastReceiver extends BroadcastReceiver{
protected WifiP2pManager wifimngr;
protected Channel channel;
protected MainActivity activity;
public MyBroadcastReceiver(WifiP2pManager iwifimngr, Channel ichannel, MainActivity iactivity)
{
super();
wifimngr=iwifimngr;
channel=ichannel;
activity=iactivity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// Determine if Wifi P2P mode is enabled or not, alert
// the Activity.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
activity.setIsWifiP2pEnabled(true);
} else {
activity.setIsWifiP2pEnabled(false);
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// Request available peers from the wifi p2p manager. This is an
// asynchronous call and the calling activity is notified with a
// callback on PeerListListener.onPeersAvailable()
if (wifimngr != null) {
wifimngr.requestPeers(channel, (PeerListListener) activity.getFragmentManager()
.findFragmentById(R.id.list));
}
Log.d(MainActivity.TAG, "P2P peers changed");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
if (wifimngr == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// we are connected with the other device, request connection
// info to find group owner IP
//DeviceDetailFragment fragment = (DeviceDetailFragment) activity
// .getFragmentManager().findFragmentById(R.id.frag_detail);
//wifimngr.requestConnectionInfo(channel, fragment);
} else {
// It's a disconnect
//activity.resetData();
}
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager()
.findFragmentById(R.id.list);
fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
}
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hpconcept.miracastconnector.MainActivity"
tools:ignore="MergeRootFrame" >
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="250dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:paddingTop="0dp"
android:textSize="20sp" >
</ListView>
<View android:id="#+id/strut"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="200dp"
android:layout_below="#android:id/list"
android:layout_centerHorizontal="true"/>
<Button
android:id="#+id/scanbutton"
android:text="#string/scan_string"
android:layout_height="wrap_content"
android:layout_below="#android:id/list"
android:layout_width="0dp"
android:layout_alignParentBottom="true"
android:onClick="scanConnections"
android:layout_alignRight="#id/strut"
android:layout_alignParentLeft="true"
/>
<Button
android:id="#+id/pauseButton"
android:text="#string/stream_string"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="pauseConnections"
android:layout_gravity="bottom"
android:layout_alignLeft="#id/strut"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_below="#android:id/list"
android:layout_toRightOf="#+id/scanbutton" />
<TextView
android:id="#+id/statusText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/pauseButton"
android:layout_alignLeft="#+id/pauseButton"
android:layout_marginLeft="42dp"
android:gravity="center"
android:text="#string/waiting_string" />
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/statusText"
android:layout_alignLeft="#+id/pauseButton"
android:layout_marginLeft="24dp"
android:visibility="invisible" />
</RelativeLayout>
So this whole project is basically turning into me trying to duct-tape together various pieces of sample code from around the internet. I could really use some help. I'm trying to use Google's Android development pages, but I don't always know where to put their snippets of code. I was trying to make my own Connection class, that would hold the WifiP2pDevice's in an arraylist along with the nicknames and other data, but I couldn't get it to work for some reason. So now my priority is just getting the program to run and find connections. I did finish the GUI to the best of my knowledge. I might need to change it or something though.
This is not all of my code. If I posted it all, this question would be huge. lol If you want to see it all, let me know.
So I found this code for anyone interested and this works perfectly:
try
{
Log.d("DEBUG", "open WiFi display settings in HTC");
startActivity(new Intent("com.htc.wifidisplay.CONFIGURE_MODE_NORMAL"));
} catch (Exception e)
{
try
{
Log.d("DEBUG", "open WiFi display settings in Samsung");
startActivity(new Intent("com.samsung.wfd.LAUNCH_WFD_PICKER_DLG"));
}catch (Exception e2)
{
Log.d("DEBUG", "open WiFi display settings in stock Android");
startActivity(new Intent("android.settings.WIFI_DISPLAY_SETTINGS"));
}
}
I got rid of the listview for now since I don't need to scan for devices with WifiP2p anymore. When this setting opens, it will connect to a nearby display automatically.
The only thing I need is to figure out a way for the settings screen to close after it has connected to a display. I have tried emulating a back button press but it only gets emulated when the user returns to the app himself. Then it backs out of the app.

Categories

Resources