diff --git a/xwords4/android/app/src/main/AndroidManifest.xml b/xwords4/android/app/src/main/AndroidManifest.xml
index e294d9ebc..0eed7c5a7 100644
--- a/xwords4/android/app/src/main/AndroidManifest.xml
+++ b/xwords4/android/app/src/main/AndroidManifest.xml
@@ -134,8 +134,8 @@
android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
/>
-
+
+
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgDelegate.java
index ecad78260..c317ac9aa 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgDelegate.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgDelegate.java
@@ -113,6 +113,9 @@ public class DlgDelegate {
// DwnldDelegate && GamesListDelegate
STORAGE_CONFIRMED,
+ // Known Players
+ KNOWN_PLAYER_DELETE,
+
// classify me
ENABLE_NBS_ASK,
ENABLE_NBS_DO,
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgID.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgID.java
index be256ba2d..edff22d08 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgID.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgID.java
@@ -70,6 +70,7 @@ public enum DlgID {
, ASK_DUP_PAUSE
, CHOOSE_TILES
, SHOW_TILES
+ , RENAME_PLAYER
;
private boolean m_addToStack;
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java
index e24ae728b..f89fc98d6 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java
@@ -1715,6 +1715,9 @@ public class GamesListDelegate extends ListDelegateBase
enable = nothingSelected && XWPrefs.getStudyEnabled( m_activity );
Utils.setItemVisible( menu, R.id.games_menu_study, enable );
+ enable = BuildConfig.HAVE_KNOWN_PLAYERS && nothingSelected;
+ Utils.setItemVisible( menu, R.id.games_menu_knownplyrs, enable );
+
enable = nothingSelected &&
0 < DBUtils.getGamesWithSendsPending( m_activity ).size();
Utils.setItemVisible( menu, R.id.games_menu_resend, enable );
@@ -1806,6 +1809,10 @@ public class GamesListDelegate extends ListDelegateBase
StudyListDelegate.launchOrAlert( getDelegator(), StudyListDelegate.NO_LANG, this );
break;
+ case R.id.games_menu_knownplyrs:
+ KnownPlayersDelegate.launchOrAlert( getDelegator(), this );
+ break;
+
case R.id.games_menu_about:
show( AboutAlert.newInstance() );
break;
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersActivity.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersActivity.java
new file mode 100644
index 000000000..1ac512731
--- /dev/null
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersActivity.java
@@ -0,0 +1,33 @@
+/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
+/*
+ * Copyright 2020 by Eric House (xwords@eehouse.org). All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package org.eehouse.android.xw4;
+
+import android.os.Bundle;
+
+public class KnownPlayersActivity extends XWActivity {
+
+ @Override
+ protected void onCreate( Bundle savedInstanceState )
+ {
+ KnownPlayersDelegate dlgt =
+ new KnownPlayersDelegate( this, savedInstanceState );
+ super.onCreate( savedInstanceState, dlgt );
+ }
+}
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java
new file mode 100644
index 000000000..60578a910
--- /dev/null
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java
@@ -0,0 +1,189 @@
+/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
+/*
+ * Copyright 2020 by Eric House (xwords@eehouse.org). All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package org.eehouse.android.xw4;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.ClipboardManager;
+import android.text.TextUtils;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+import android.widget.ListView;
+
+import org.eehouse.android.xw4.DlgDelegate.Action;
+import org.eehouse.android.xw4.ExpandImageButton.ExpandChangeListener;
+import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
+import org.eehouse.android.xw4.jni.CommsAddrRec;
+import org.eehouse.android.xw4.jni.GameSummary;
+import org.eehouse.android.xw4.jni.XwJNI;
+import org.eehouse.android.xw4.loc.LocUtils;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class KnownPlayersDelegate extends DelegateBase {
+ private static final String TAG = KnownPlayersDelegate.class.getSimpleName();
+
+ private Activity mActivity;
+ private ViewGroup mList;
+
+ protected KnownPlayersDelegate( Delegator delegator, Bundle sis )
+ {
+ super( delegator, sis, R.layout.knownplayrs );
+ mActivity = delegator.getActivity();
+ }
+
+ @Override
+ protected void init( Bundle sis )
+ {
+ mList = (ViewGroup)findViewById( R.id.players_list );
+
+ String[] players = XwJNI.kplr_getPlayers();
+ for ( String player : players ) {
+ View child = makePlayerElem( player );
+ if ( null != child ) {
+ mList.addView( child );
+ }
+ }
+ }
+
+ @Override
+ public boolean onPosButton( Action action, Object[] params )
+ {
+ boolean handled = true;
+ switch ( action ) {
+ case KNOWN_PLAYER_DELETE:
+ Utils.notImpl( mActivity );
+ break;
+ default:
+ handled = super.onPosButton( action, params );
+ break;
+ }
+ return handled;
+ }
+
+ private View makePlayerElem( final String player )
+ {
+ View view = null;
+ CommsAddrRec addr = XwJNI.kplr_getAddr( player );
+ if ( null != addr ) {
+ final ViewGroup item = (ViewGroup)LocUtils.inflate( mActivity, R.layout.knownplayrs_item );
+ TextView tv = (TextView)item.findViewById( R.id.player_name );
+ tv.setText( player );
+ view = item;
+
+ // Iterate over address types
+ CommsConnTypeSet conTypes = addr.conTypes;
+ ViewGroup list = (ViewGroup)item.findViewById( R.id.items );
+ if ( BuildConfig.NON_RELEASE ) {
+ if ( conTypes.contains( CommsAddrRec.CommsConnType.COMMS_CONN_MQTT ) ) {
+ addListing( list, R.string.knowns_mqtt_fmt, addr.mqtt_devID );
+ }
+ // if ( conTypes.contains( CommsAddrRec.CommsConnType.COMMS_CONN_RELAY ) ) {
+ // addListing( item, R.string.knowns_relay_fmt, addr.relay_devID );
+ // }
+ }
+ if ( conTypes.contains( CommsAddrRec.CommsConnType.COMMS_CONN_BT ) ) {
+ addListing( list, R.string.knowns_bt_fmt, addr.bt_hostName );
+ }
+ if ( conTypes.contains( CommsAddrRec.CommsConnType.COMMS_CONN_SMS ) ) {
+ addListing( list, R.string.knowns_smsphone_fmt, addr.sms_phone );
+ }
+
+ item.findViewById( R.id.player_edit_name )
+ .setOnClickListener( new View.OnClickListener() {
+ @Override
+ public void onClick( View view ) {
+ Utils.notImpl( mActivity );
+ }
+ } );
+ item.findViewById( R.id.player_delete )
+ .setOnClickListener( new View.OnClickListener() {
+ @Override
+ public void onClick( View view ) {
+ confirmAndDelete( player );
+ }
+ } );
+
+ ExpandImageButton eib = (ExpandImageButton)item.findViewById( R.id.expander );
+ eib.setOnExpandChangedListener( new ExpandChangeListener() {
+ @Override
+ public void expandedChanged( boolean nowExpanded )
+ {
+ item.findViewById(R.id.hidden_part)
+ .setVisibility(nowExpanded?View.VISIBLE:View.GONE);
+ }
+ } );
+
+ }
+ return view;
+ }
+
+ private void addListing( ViewGroup parent, int fmtID, String elem )
+ {
+ String content = LocUtils.getString( mActivity, fmtID, elem );
+ TextView item = (TextView)LocUtils.inflate( mActivity, R.layout.knownplayrs_item_line );
+ item.setText( content );
+ parent.addView( item );
+ }
+
+ private void editName( String name )
+ {
+ Log.d( TAG, "editName(%s) not implemented yet", name );
+ }
+
+ private void confirmAndDelete( String name )
+ {
+ String msg = LocUtils.getString( mActivity,
+ R.string.player_delete_confirm_fmt,
+ name );
+ makeConfirmThenBuilder( msg, Action.KNOWN_PLAYER_DELETE )
+ .show();
+ }
+
+ public static void launchOrAlert( Delegator delegator,
+ DlgDelegate.HasDlgDelegate dlg )
+ {
+ Activity activity = delegator.getActivity();
+
+ if ( XwJNI.hasKnownPlayers() ) {
+ if ( delegator.inDPMode() ) {
+ delegator.addFragment( KnownPlayersFrag.newInstance( delegator ),
+ null );
+ } else {
+ Intent intent = new Intent( activity, KnownPlayersActivity.class );
+ activity.startActivity( intent );
+ }
+ } else {
+ dlg.makeOkOnlyBuilder( R.string.no_knowns_expl )
+ .show();
+ }
+ }
+}
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersFrag.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersFrag.java
new file mode 100644
index 000000000..eb51d94f1
--- /dev/null
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersFrag.java
@@ -0,0 +1,39 @@
+/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
+/*
+ * Copyright 2014 - 2020 by Eric House (xwords@eehouse.org). All rights
+ * reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package org.eehouse.android.xw4;
+
+import android.os.Bundle;
+
+public class KnownPlayersFrag extends XWFragment {
+
+ public KnownPlayersFrag() {}
+
+ public static XWFragment newInstance( Delegator parent )
+ {
+ return new KnownPlayersFrag().setParentName( parent );
+ }
+
+ @Override
+ public void onCreate( Bundle sis )
+ {
+ super.onCreate( new KnownPlayersDelegate( this, sis ), sis, true );
+ }
+}
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/StudyListDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/StudyListDelegate.java
index 3d5b1a01b..cc269310d 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/StudyListDelegate.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/StudyListDelegate.java
@@ -65,7 +65,6 @@ public class StudyListDelegate extends ListDelegateBase
private Set m_checkeds;
private int m_langPosition;
private SLWordsAdapter m_adapter;
- private ListView m_list;
private String m_origTitle;
protected StudyListDelegate( Delegator delegator, Bundle sis )
@@ -77,8 +76,6 @@ public class StudyListDelegate extends ListDelegateBase
@Override
protected void init( Bundle sis )
{
- m_list = (ListView)findViewById( android.R.id.list );
-
m_pickView = (LabeledSpinner)findViewById( R.id.pick_lang );
m_spinner = m_pickView.getSpinner();
m_checkeds = new HashSet<>();
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWActivity.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWActivity.java
index 6bbdfbadb..12f5e3a85 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWActivity.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWActivity.java
@@ -39,7 +39,6 @@ import android.widget.ListView;
import org.eehouse.android.xw4.DlgDelegate.Action;
-
public class XWActivity extends FragmentActivity
implements Delegator, DlgDelegate.DlgClickNotify {
private static final String TAG = XWActivity.class.getSimpleName();
@@ -257,11 +256,13 @@ public class XWActivity extends FragmentActivity
return false;
}
+ @Override
public void addFragment( XWFragment fragment, Bundle extras )
{
Assert.failDbg();
}
+ @Override
public void addFragmentForResult( XWFragment fragment, Bundle extras,
RequestCode request )
{
diff --git a/xwords4/android/app/src/main/res/layout/knownplayrs.xml b/xwords4/android/app/src/main/res/layout/knownplayrs.xml
new file mode 100644
index 000000000..764e0f158
--- /dev/null
+++ b/xwords4/android/app/src/main/res/layout/knownplayrs.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/xwords4/android/app/src/main/res/layout/knownplayrs_item.xml b/xwords4/android/app/src/main/res/layout/knownplayrs_item.xml
new file mode 100644
index 000000000..b77b5ddf0
--- /dev/null
+++ b/xwords4/android/app/src/main/res/layout/knownplayrs_item.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xwords4/android/app/src/main/res/layout/knownplayrs_item_line.xml b/xwords4/android/app/src/main/res/layout/knownplayrs_item_line.xml
new file mode 100644
index 000000000..10250f2fe
--- /dev/null
+++ b/xwords4/android/app/src/main/res/layout/knownplayrs_item_line.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/xwords4/android/app/src/main/res/menu/games_list_menu.xml b/xwords4/android/app/src/main/res/menu/games_list_menu.xml
index f3d96ca06..4aa2287f0 100644
--- a/xwords4/android/app/src/main/res/menu/games_list_menu.xml
+++ b/xwords4/android/app/src/main/res/menu/games_list_menu.xml
@@ -36,6 +36,9 @@
+
- MQTT Invitation
I’m experimenting with this
as a replacement for the relay.
+
+
+ Known Players…
+
+
+ There haven’t been any Known Players
+ saved yet. Known Players are harvested from networked games after
+ they connect successfully. Give it time.
+
+ MQTT DevID: %1$s
+ Bluetooth name: %1$s
+ SMS Phone: %1$s
+
+
+ Change name
+
+
+ Are you sure you want to
+ delete the Known Player “%1$s”?\n\n(This action cannot be
+ undone.)
+