You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

358 lines
11 KiB
Java

package com.waveshare.epaperesp32loader;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.waveshare.epaperesp32loader.communication.BluetoothHelper;
import com.waveshare.epaperesp32loader.communication.BluetoothScanner;
import com.waveshare.epaperesp32loader.communication.PermissionHelper;
import java.util.ArrayList;
/**
* <h1>Scanning activity</h1>
* The activity offers to select one of available bluetooth devices.
*
* @author Waveshare team
* @version 1.0
* @since 8/11/2018
*/
public class ScanningActivity extends AppCompatActivity implements BluetoothScanner.ScanningHandler
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.onCreate(savedInstanceState);
setContentView(R.layout.scanning_activity);
getSupportActionBar().setTitle(R.string.scan);
// Device list
//-------------------------
deviceList = findViewById(R.id.device_list);
deviceList.setAdapter(btListAdapter = new ListAdapter());
deviceList.setOnItemClickListener(new OnDevListItemClick());
// Bluetooth scanner
//-------------------------
if (!BluetoothScanner.initialize(this))
{
Intent intent = new Intent();
intent.putExtra("COMMENT", "Bluetooth is not supported on this device");
setResult(RESULT_CANCELED);
finish();
}
}
@Override
protected void onResume()
{
super.onResume();
BluetoothScanner.stopScanning(this, false);
}
@Override
protected void onPause()
{
BluetoothScanner.stopScanning(this, false);
super.onPause();
}
@Override
protected void onDestroy()
{
BluetoothScanner.stopScanning(this, true);
super.onDestroy();
}
@Override
public void onBackPressed()
{
super.onBackPressed();
BluetoothScanner.stopScanning(this, true);
}
//------------------------------------------
// Result of permission request
//------------------------------------------
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
BluetoothScanner.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
//---------------------------------------------------------
// Main menu
//---------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.scanning_menu, menu);
if (BluetoothScanner.isScanning())
{
menu.findItem(R.id.menu_item_ring).setActionView(R.layout.scanning_ring);
menu.findItem(R.id.menu_item_scan).setVisible(false);
menu.findItem(R.id.menu_item_stop).setVisible(true);
}
else
{
menu.findItem(R.id.menu_item_ring).setActionView(null);
menu.findItem(R.id.menu_item_scan).setVisible(true);
menu.findItem(R.id.menu_item_stop).setVisible(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();
switch (id)
{
// Start scanning
//-------------------------------------------------
case R.id.menu_item_scan:
// If scanning is started
//---------------------------------------------
if (BluetoothScanner.startScanning())
// Just update option menu's view
//-----------------------------------------
invalidateOptionsMenu();
// ... otherwise send request permission
//---------------------------------------------
else BluetoothScanner.sendRequestPermission();
break;
// Stop scanning and update menu
//-------------------------------------------------
case R.id.menu_item_stop:
BluetoothScanner.stopScanning(this, false);
invalidateOptionsMenu();
break;
}
return super.onOptionsItemSelected(item);
}
//---------------------------------------------------------
// Device list
//---------------------------------------------------------
private ListView deviceList;
private ListAdapter btListAdapter;
static class ViewHolder
{
public TextView text;
public TextView addr;
}
private class ListAdapter extends BaseAdapter
{
private ArrayList<BluetoothDevice> btDevices;
public ListAdapter()
{
super();
btDevices = new ArrayList<>();
}
public void addDevice(BluetoothDevice device)
{
btDevices.add(device);
}
public BluetoothDevice getDevice(int position)
{
return btDevices.get(position);
}
public void clear()
{
btDevices.clear();
}
public boolean contains(BluetoothDevice device)
{
// The device is already in the list
//-------------------------------------------------
if (btDevices.contains(device))
return true;
// Every device must have unique MAC address
//-------------------------------------------------
for (int i = 0; i < btDevices.size(); i++)
if (btDevices.get(i).getAddress().equals(device.getAddress()))
return true;
return false;
}
@Override
public int getCount()
{
return btDevices.size();
}
@Override
public Object getItem(int i)
{
return btDevices.get(i);
}
@Override
public long getItemId(int i)
{
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup)
{
ViewHolder viewHolder;
if (view == null)
{
view = ScanningActivity.this.getLayoutInflater().inflate(R.layout.scanning_list_item, null);
viewHolder = new ViewHolder();
viewHolder.text = view.findViewById(R.id.bt_dev_name);
viewHolder.addr = view.findViewById(R.id.bt_dev_addr);
view.setTag(viewHolder);
}
else viewHolder = (ScanningActivity.ViewHolder) view.getTag();
BluetoothDevice device = btDevices.get(i);
String name = device.getName();
if (device.getBondState() == BluetoothDevice.BOND_BONDED) name += " (BONDED)";
viewHolder.text.setText((name != null) && (name.length() > 0) ? name : "unknown");
viewHolder.addr.setText(device.getAddress());
return view;
}
}
private class OnDevListItemClick implements AdapterView.OnItemClickListener
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
// Stop scanning and broadcast receiving
//-------------------------------------------------
BluetoothScanner.stopScanning(ScanningActivity.this, true);
// Return name and address of the selected device
//-------------------------------------------------
Intent intent = new Intent();
intent.putExtra("DEVICE", btListAdapter.getDevice(position));
setResult(RESULT_OK, intent);
finish();
}
}
//---------------------------------------------------------
// Scanning message handler
//---------------------------------------------------------
public void handleMessage(int cmd, Intent data)
{
runOnUiThread(new ScanHandler(cmd, data));
}
private class ScanHandler implements Runnable
{
public int cmd;
public Intent data;
public ScanHandler(int cmd, Intent data)
{
this.cmd = cmd;
this.data = data;
}
@Override
public void run()
{
BluetoothDevice device;
int state;
switch (cmd)
{
case BluetoothScanner.BT_DEVICE_FOUND:
// Found bluetooth device
//-----------------------------------------
device = data.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Check if the device is unique
//-----------------------------------------
if (btListAdapter.contains(device)) break;
// Add the device into devices list
//-----------------------------------------
btListAdapter.addDevice(device);
// Update devices list's view
//-----------------------------------------
btListAdapter.notifyDataSetChanged();
break;
case BluetoothScanner.BT_SCANNING_ON:
// Update the options menu's view
//-----------------------------------------
invalidateOptionsMenu();
// Clear devices list
//-----------------------------------------
btListAdapter.clear();
// Update devices list's view
//-----------------------------------------
btListAdapter.notifyDataSetChanged();
break;
case BluetoothScanner.BT_SCANNING_OFF:
// Just update the options menu's view
//-----------------------------------------
invalidateOptionsMenu();
break;
case BluetoothScanner.BT_IS_CHANGED:
// Current state of the bluetooth adapter
//-----------------------------------------
state = data.getIntExtra(
BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
// Update the options menu's view
// if the adapter is turned off
//-----------------------------------------
if (state == BluetoothAdapter.STATE_OFF)
invalidateOptionsMenu();
break;
default:
break;
}
}
}
}