mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-01 19:57:11 +01:00
Prune unpaired devs; accept uncatagorized devs
Some devices unpair themselves and needed to stop being listed so user'd know to fix. And my Nexus 5x is neither a PHONE nor a COMPUTER per BT, so accept a larger range of BT classes when scanning.
This commit is contained in:
parent
a9409f8cca
commit
fef7d2d544
2 changed files with 103 additions and 42 deletions
|
@ -22,6 +22,7 @@ package org.eehouse.android.xw4;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -42,6 +43,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -56,7 +58,7 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
private static final boolean ENABLE_FAKER = false;
|
private static final boolean ENABLE_FAKER = false;
|
||||||
private static final int SCAN_SECONDS = 5;
|
private static final int SCAN_SECONDS = 5;
|
||||||
|
|
||||||
private static Persisted sPersisted;
|
private static Persisted[] sPersistedRef = {null};
|
||||||
|
|
||||||
private Activity m_activity;
|
private Activity m_activity;
|
||||||
private ProgressBar mProgressBar;
|
private ProgressBar mProgressBar;
|
||||||
|
@ -168,10 +170,10 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
addButtonBar( R.layout.bt_buttons, BUTTONIDS );
|
addButtonBar( R.layout.bt_buttons, BUTTONIDS );
|
||||||
|
|
||||||
load( m_activity );
|
load( m_activity );
|
||||||
if ( sPersisted.empty() ) {
|
if ( sPersistedRef[0].empty() ) {
|
||||||
scan();
|
scan();
|
||||||
} else {
|
} else {
|
||||||
updateList( sPersisted.pairs );
|
updateList( sPersistedRef[0].pairs );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +207,7 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
public void run() {
|
public void run() {
|
||||||
hideProgress();
|
hideProgress();
|
||||||
|
|
||||||
if ( sPersisted.empty() || 0 == mNDevsThisScan ) {
|
if ( sPersistedRef[0].empty() || 0 == mNDevsThisScan ) {
|
||||||
makeNotAgainBuilder( R.string.not_again_emptybtscan,
|
makeNotAgainBuilder( R.string.not_again_emptybtscan,
|
||||||
R.string.key_notagain_emptybtscan )
|
R.string.key_notagain_emptybtscan )
|
||||||
.show();
|
.show();
|
||||||
|
@ -232,9 +234,9 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
String devName = ((TwoStringPair)data).str2;
|
String devName = ((TwoStringPair)data).str2;
|
||||||
|
|
||||||
String msg = null;
|
String msg = null;
|
||||||
if ( sPersisted.stamps.containsKey( devName ) ) {
|
if ( sPersistedRef[0].stamps.containsKey( devName ) ) {
|
||||||
CharSequence elapsed = DateUtils
|
CharSequence elapsed = DateUtils
|
||||||
.getRelativeTimeSpanString( sPersisted.stamps.get( devName ),
|
.getRelativeTimeSpanString( sPersistedRef[0].stamps.get( devName ),
|
||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
DateUtils.SECOND_IN_MILLIS );
|
DateUtils.SECOND_IN_MILLIS );
|
||||||
msg = getString( R.string.bt_scan_age_fmt, elapsed );
|
msg = getString( R.string.bt_scan_age_fmt, elapsed );
|
||||||
|
@ -257,7 +259,7 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
private void scan()
|
private void scan()
|
||||||
{
|
{
|
||||||
if ( ENABLE_FAKER && Utils.nextRandomInt() % 5 == 0 ) {
|
if ( ENABLE_FAKER && Utils.nextRandomInt() % 5 == 0 ) {
|
||||||
sPersisted.add( "00:00:00:00:00:00", "Do Not Invite Me" );
|
sPersistedRef[0].add( "00:00:00:00:00:00", "Do Not Invite Me" );
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = BTService.getPairedCount( m_activity );
|
int count = BTService.getPairedCount( m_activity );
|
||||||
|
@ -278,10 +280,10 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
DbgUtils.assertOnUIThread();
|
DbgUtils.assertOnUIThread();
|
||||||
|
|
||||||
++mNDevsThisScan;
|
++mNDevsThisScan;
|
||||||
sPersisted.add( dev.getAddress(), dev.getName() );
|
sPersistedRef[0].add( dev.getAddress(), dev.getName() );
|
||||||
store( m_activity );
|
store( m_activity );
|
||||||
|
|
||||||
updateList( sPersisted.pairs );
|
updateList( sPersistedRef[0].pairs );
|
||||||
tryEnable();
|
tryEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,23 +325,59 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
}, 1000 * inSeconds );
|
}, 1000 * inSeconds );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void removeNotPaired( Persisted prs )
|
||||||
|
{
|
||||||
|
Log.d( TAG, "removeNotPaired()" );
|
||||||
|
BluetoothAdapter adapter = BTService.getAdapterIf();
|
||||||
|
if ( null != adapter ) {
|
||||||
|
Set<BluetoothDevice> pairedDevs = adapter.getBondedDevices();
|
||||||
|
Set<String> paired = new HashSet<>();
|
||||||
|
for ( BluetoothDevice dev : pairedDevs ) {
|
||||||
|
Log.d( TAG, "removeNotPaired(): paired dev: %s", dev.getName() );
|
||||||
|
paired.add( dev.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> toRemove = new HashSet<>();
|
||||||
|
for ( TwoStringPair pair : prs.pairs ) {
|
||||||
|
String name = pair.str2;
|
||||||
|
if ( ! paired.contains( name ) ) {
|
||||||
|
Log.d( TAG, "%s no longer paired; removing", name );
|
||||||
|
toRemove.add( name );
|
||||||
|
} else {
|
||||||
|
Log.d( TAG, "%s STILL paired", name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! toRemove.isEmpty() ) {
|
||||||
|
prs.remove( toRemove );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e( TAG, "removeNotPaired(): adapter null" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized static void load( Context context )
|
private synchronized static void load( Context context )
|
||||||
{
|
{
|
||||||
if ( null == sPersisted ) {
|
if ( null == sPersistedRef[0] ) {
|
||||||
|
Persisted prs;
|
||||||
try {
|
try {
|
||||||
sPersisted = (Persisted)DBUtils.getSerializableFor( context, KEY_PERSIST );
|
prs = (Persisted)DBUtils.getSerializableFor( context, KEY_PERSIST );
|
||||||
sPersisted.removeNulls(); // clean up earlier mistakes
|
prs.removeNulls(); // clean up earlier mistakes
|
||||||
} catch ( Exception ex ) {} // NPE, de-serialization problems, etc.
|
removeNotPaired( prs );
|
||||||
|
} catch ( Exception ex ) {
|
||||||
|
prs = null;
|
||||||
|
} // NPE, de-serialization problems, etc.
|
||||||
|
|
||||||
if ( null == sPersisted ) {
|
if ( null == prs ) {
|
||||||
sPersisted = new Persisted();
|
prs = new Persisted();
|
||||||
}
|
}
|
||||||
|
sPersistedRef[0] = prs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized static void store( Context context )
|
private synchronized static void store( Context context )
|
||||||
{
|
{
|
||||||
DBUtils.setSerializableFor( context, KEY_PERSIST, sPersisted );
|
DBUtils.setSerializableFor( context, KEY_PERSIST, sPersistedRef[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// DlgDelegate.DlgClickNotify interface
|
// DlgDelegate.DlgClickNotify interface
|
||||||
|
@ -352,11 +390,11 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
BTService.openBTSettings( m_activity );
|
BTService.openBTSettings( m_activity );
|
||||||
break;
|
break;
|
||||||
case CLEAR_ACTION:
|
case CLEAR_ACTION:
|
||||||
sPersisted.remove( getChecked() );
|
sPersistedRef[0].remove( getChecked() );
|
||||||
store( m_activity );
|
store( m_activity );
|
||||||
|
|
||||||
clearChecked();
|
clearChecked();
|
||||||
updateList( sPersisted.pairs );
|
updateList( sPersistedRef[0].pairs );
|
||||||
tryEnable();
|
tryEnable();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -368,7 +406,7 @@ public class BTInviteDelegate extends InviteDelegate {
|
||||||
public static void onHeardFromDev( Context context, BluetoothDevice dev )
|
public static void onHeardFromDev( Context context, BluetoothDevice dev )
|
||||||
{
|
{
|
||||||
load( context );
|
load( context );
|
||||||
sPersisted.add( dev.getAddress(), dev.getName() );
|
sPersistedRef[0].add( dev.getAddress(), dev.getName() );
|
||||||
store( context );
|
store( context );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,21 +164,29 @@ public class BTService extends XWJIService {
|
||||||
|
|
||||||
private static int s_errCount = 0;
|
private static int s_errCount = 0;
|
||||||
|
|
||||||
|
public static BluetoothAdapter getAdapterIf()
|
||||||
|
{
|
||||||
|
// Later this will change to include at least a test whether we're
|
||||||
|
// running as background user account, a situation in which BT crashes
|
||||||
|
// a lot inside the OS.
|
||||||
|
return BluetoothAdapter.getDefaultAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean BTAvailable()
|
public static boolean BTAvailable()
|
||||||
{
|
{
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
return null != adapter;
|
return null != adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean BTEnabled()
|
public static boolean BTEnabled()
|
||||||
{
|
{
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
return null != adapter && adapter.isEnabled();
|
return null != adapter && adapter.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void enable()
|
public static void enable()
|
||||||
{
|
{
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
if ( null != adapter ) {
|
if ( null != adapter ) {
|
||||||
// Only do this after explicit action from user -- Android guidelines
|
// Only do this after explicit action from user -- Android guidelines
|
||||||
adapter.enable();
|
adapter.enable();
|
||||||
|
@ -187,7 +195,7 @@ public class BTService extends XWJIService {
|
||||||
|
|
||||||
public static String[] getBTNameAndAddress()
|
public static String[] getBTNameAndAddress()
|
||||||
{
|
{
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
return null == adapter ? null
|
return null == adapter ? null
|
||||||
: new String[] { adapter.getName(), adapter.getAddress() };
|
: new String[] { adapter.getName(), adapter.getAddress() };
|
||||||
}
|
}
|
||||||
|
@ -195,7 +203,7 @@ public class BTService extends XWJIService {
|
||||||
public static int getPairedCount( Activity activity )
|
public static int getPairedCount( Activity activity )
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
if ( null != adapter ) {
|
if ( null != adapter ) {
|
||||||
Set<BluetoothDevice> pairedDevs = adapter.getBondedDevices();
|
Set<BluetoothDevice> pairedDevs = adapter.getBondedDevices();
|
||||||
result = pairedDevs.size();
|
result = pairedDevs.size();
|
||||||
|
@ -212,7 +220,7 @@ public class BTService extends XWJIService {
|
||||||
|
|
||||||
public static String nameForAddr( String btAddr )
|
public static String nameForAddr( String btAddr )
|
||||||
{
|
{
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
return nameForAddr( adapter, btAddr );
|
return nameForAddr( adapter, btAddr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +354,7 @@ public class BTService extends XWJIService {
|
||||||
m_btMsgSink = new BTMsgSink();
|
m_btMsgSink = new BTMsgSink();
|
||||||
mHandler = new Handler();
|
mHandler = new Handler();
|
||||||
|
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
if ( null != adapter && adapter.isEnabled() ) {
|
if ( null != adapter && adapter.isEnabled() ) {
|
||||||
m_adapter = adapter;
|
m_adapter = adapter;
|
||||||
Log.i( TAG, "onCreate(); bt name = %s; bt addr = %s",
|
Log.i( TAG, "onCreate(); bt name = %s; bt addr = %s",
|
||||||
|
@ -542,7 +550,7 @@ public class BTService extends XWJIService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() { // receive thread
|
public void run() { // receive thread
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
String appName = XWApp.getAppName( XWApp.getContext() );
|
String appName = XWApp.getAppName( XWApp.getContext() );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -685,7 +693,7 @@ public class BTService extends XWJIService {
|
||||||
btAddr = null;
|
btAddr = null;
|
||||||
}
|
}
|
||||||
if ( null == btAddr ) {
|
if ( null == btAddr ) {
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
if ( null != adapter ) {
|
if ( null != adapter ) {
|
||||||
for ( BluetoothDevice dev : adapter.getBondedDevices() ) {
|
for ( BluetoothDevice dev : adapter.getBondedDevices() ) {
|
||||||
// Log.d( TAG, "%s => %s", dev.getName(), dev.getAddress() );
|
// Log.d( TAG, "%s => %s", dev.getName(), dev.getAddress() );
|
||||||
|
@ -706,21 +714,36 @@ public class BTService extends XWJIService {
|
||||||
Set<BluetoothDevice> pairedDevs = m_adapter.getBondedDevices();
|
Set<BluetoothDevice> pairedDevs = m_adapter.getBondedDevices();
|
||||||
Map<BluetoothDevice, PacketAccumulator> pas = new HashMap<>();
|
Map<BluetoothDevice, PacketAccumulator> pas = new HashMap<>();
|
||||||
for ( BluetoothDevice dev : pairedDevs ) {
|
for ( BluetoothDevice dev : pairedDevs ) {
|
||||||
// Skip things that can't host an Android app
|
// Skip things that can't host an Android app. BUT: one of my
|
||||||
|
// phones, and presumably lots of others, aren't listed as
|
||||||
|
// PHONE. So let's try negative testing instead
|
||||||
int clazz = dev.getBluetoothClass().getMajorDeviceClass();
|
int clazz = dev.getBluetoothClass().getMajorDeviceClass();
|
||||||
if ( Major.PHONE == clazz || Major.COMPUTER == clazz ) {
|
String reject = null;
|
||||||
PacketAccumulator pa =
|
switch ( clazz ) {
|
||||||
new PacketAccumulator( dev.getAddress(), timeoutMS )
|
case Major.AUDIO_VIDEO:
|
||||||
.addPing( 0 )
|
reject = "audio"; break;
|
||||||
.setExitWhenEmpty()
|
case Major.HEALTH:
|
||||||
.setLifetimeMS(timeoutMS)
|
reject = "health"; break;
|
||||||
.setService( this )
|
case Major.IMAGING:
|
||||||
;
|
reject = "imaging"; break;
|
||||||
pas.put( dev, pa );
|
case Major.TOY:
|
||||||
} else {
|
reject = "toy"; break;
|
||||||
Log.d( TAG, "skipping %s (clazz=%d); not an android device!",
|
case Major.PERIPHERAL:
|
||||||
dev.getName(), clazz );
|
reject = "peripheral"; break;
|
||||||
}
|
}
|
||||||
|
if ( null != reject ) {
|
||||||
|
Log.d( TAG, "sendPings(): %s is a %s; dropping", dev.getName(), reject );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Log.d( TAG, "sendPings(): sending to %s (a %d)", dev.getName(), clazz );
|
||||||
|
PacketAccumulator pa =
|
||||||
|
new PacketAccumulator( dev.getAddress(), timeoutMS )
|
||||||
|
.addPing( 0 )
|
||||||
|
.setExitWhenEmpty()
|
||||||
|
.setLifetimeMS(timeoutMS)
|
||||||
|
.setService( this )
|
||||||
|
;
|
||||||
|
pas.put( dev, pa );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( BluetoothDevice dev : pas.keySet() ) {
|
for ( BluetoothDevice dev : pas.keySet() ) {
|
||||||
|
@ -1414,7 +1437,7 @@ public class BTService extends XWJIService {
|
||||||
{
|
{
|
||||||
Assert.assertFalse( BOGUS_MARSHMALLOW_ADDR.equals( addr ) );
|
Assert.assertFalse( BOGUS_MARSHMALLOW_ADDR.equals( addr ) );
|
||||||
String result = "<unknown>";
|
String result = "<unknown>";
|
||||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
if ( null != adapter ) {
|
if ( null != adapter ) {
|
||||||
Set<BluetoothDevice> devs = adapter.getBondedDevices();
|
Set<BluetoothDevice> devs = adapter.getBondedDevices();
|
||||||
Iterator<BluetoothDevice> iter = devs.iterator();
|
Iterator<BluetoothDevice> iter = devs.iterator();
|
||||||
|
|
Loading…
Add table
Reference in a new issue