take
@@ -25,8 +26,10 @@
New with this release
- - Fix crash when invitation requires a wordlist you don't have
- - Include latest Portuguese translations
+ - Fix delays bringing up the Invite dialog for new games
+ - Explicitly specify application "theme" to fix a Samsung
+ "upgrade" turning the titlebar white and so making menu
+ icons disappear
(The full changelog
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java
index d5460275f..78e963232 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java
@@ -126,6 +126,7 @@ public class BoardDelegate extends DelegateBase
private boolean m_overNotShown;
private boolean m_dropOnDismiss;
private DBAlert m_inviteAlert;
+ private boolean m_haveStartedShowing;
public class TimerRunnable implements Runnable {
private int m_why;
@@ -2225,6 +2226,7 @@ public class BoardDelegate extends DelegateBase
// Assert.assertFalse( BuildConfig.DEBUG );
}
m_inviteAlert = null;
+ m_haveStartedShowing = false;
}
}
@@ -2304,9 +2306,14 @@ public class BoardDelegate extends DelegateBase
showDialogFragment( dlgID, dlgTitle, txt );
}
+ // This is failing sometimes, and so the null == m_inviteAlert test means
+ // we never post it. BUT on a lot of devices without the test we wind up
+ // trying over and over to put the thing up.
private void showInviteAlertIf()
{
- if ( /* null == m_inviteAlert && */m_mySIS.nMissing > 0 && !isFinishing() ) {
+ DbgUtils.assertOnUIThread();
+ if ( ! m_haveStartedShowing && null == m_inviteAlert
+ && m_mySIS.nMissing > 0 && !isFinishing() ) {
InviteAlertState ias = new InviteAlertState();
ias.summary = m_summary;
ias.gi = m_gi;
@@ -2315,6 +2322,7 @@ public class BoardDelegate extends DelegateBase
ias.rowid = m_rowid;
ias.nMissing = m_mySIS.nMissing;
showDialogFragment( DlgID.DLG_INVITE, ias );
+ m_haveStartedShowing = true;
}
}
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/ConnStatusHandler.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/ConnStatusHandler.java
index bfcac0c2a..c2d0b9795 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/ConnStatusHandler.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/ConnStatusHandler.java
@@ -84,14 +84,24 @@ public class ConnStatusHandler {
public String newerStr( Context context )
{
- s_time.set( successNewer? lastSuccess : lastFailure );
- return format( context, s_time );
+ String result = null;
+ long time = successNewer? lastSuccess : lastFailure;
+ if ( time > 0 ) {
+ s_time.set( time );
+ result = format( context, s_time );
+ }
+ return result;
}
public String olderStr( Context context )
{
- s_time.set( successNewer? lastFailure : lastSuccess );
- return format( context, s_time );
+ String result = null;
+ long time = successNewer? lastFailure : lastSuccess;
+ if ( time > 0 ) {
+ s_time.set( time );
+ result = format( context, s_time );
+ }
+ return result;
}
public void update( boolean success )
@@ -175,13 +185,20 @@ public class ConnStatusHandler {
String did = addDebugInfo( context, typ );
sb.append( String.format( "\n\n*** %s %s***\n",
typ.longName( context ), did ) );
+
+ // For sends we list failures too.
SuccessRecord record = recordFor( typ, false );
tmp = LocUtils.getString( context, record.successNewer?
R.string.connstat_succ :
R.string.connstat_unsucc );
- sb.append( LocUtils
- .getString( context, R.string.connstat_lastsend_fmt,
- tmp, record.newerStr( context ) ) );
+
+ String timeStr = record.newerStr( context );
+ if ( null != timeStr ) {
+ sb.append( LocUtils
+ .getString( context, R.string.connstat_lastsend_fmt,
+ tmp, timeStr ) )
+ .append( "\n" );
+ }
int fmtId = 0;
if ( record.successNewer ) {
@@ -193,11 +210,12 @@ public class ConnStatusHandler {
fmtId = R.string.connstat_lastother_unsucc_fmt;
}
}
- if ( 0 != fmtId ) {
- sb.append( LocUtils.getString( context, fmtId,
- record.olderStr( context )));
+ timeStr = record.olderStr( context );
+ if ( 0 != fmtId && null != timeStr ) {
+ sb.append( LocUtils.getString( context, fmtId, timeStr ))
+ .append( "\n" );
}
- sb.append( "\n\n" );
+ sb.append( "\n" );
record = recordFor( typ, true );
if ( record.haveSuccess() ) {
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java
index f54ee142e..5b9f4da1b 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java
@@ -290,7 +290,7 @@ public class DelegateBase implements DlgClickNotify,
if ( main.inDPMode() ) {
if ( !m_finishCalled ) {
m_finishCalled = true;
- main.finishFragment();
+ main.finishFragment( (XWFragment)m_delegator );
}
handled = true;
}
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 5d0e31166..265e4b7d6 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
@@ -32,6 +32,8 @@ import android.os.Bundle;
import android.os.Handler;
import android.view.View;
+import java.io.Serializable;
+
import junit.framework.Assert;
import org.eehouse.android.xw4.DBUtils.SentInvitesInfo;
@@ -126,13 +128,29 @@ public class DlgDelegate {
SET_GOT_LANGDICT,
}
- public static class ActionPair {
+ public static class ActionPair implements Serializable {
public ActionPair( Action act, int str ) {
buttonStr = str; action = act;
}
public int buttonStr;
public Action action;
- public Object[] params; // null for now
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ boolean result;
+ if ( BuildConfig.DEBUG ) {
+ result = null != obj && obj instanceof ActionPair;
+ if ( result ) {
+ ActionPair other = (ActionPair)obj;
+ result = buttonStr == other.buttonStr
+ && action == other.action;
+ }
+ } else {
+ result = super.equals( obj );
+ }
+ return result;
+ }
}
public abstract class DlgDelegateBuilder {
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgState.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgState.java
index 82dd9a65f..e3ce8f217 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgState.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgState.java
@@ -164,6 +164,7 @@ public class DlgState implements Parcelable {
out.writeInt( m_titleId );
out.writeString( m_msg );
out.writeSerializable( m_params );
+ out.writeSerializable( m_pair );
}
private void testCanParcelize()
@@ -197,6 +198,7 @@ public class DlgState implements Parcelable {
int titleId = in.readInt();
String msg = in.readString();
Object[] params = (Object[])in.readSerializable();
+ ActionPair pair = (ActionPair)in.readSerializable();
DlgState state = new DlgState(id)
.setMsg( msg )
.setPosButton( posButton )
@@ -206,6 +208,7 @@ public class DlgState implements Parcelable {
.setOnNA( onNA )
.setTitle(titleId)
.setParams(params)
+ .setActionPair(pair)
;
return state;
}
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 cd004bf1a..e98aecd9f 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
@@ -24,19 +24,20 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
@@ -1926,8 +1927,19 @@ public class GamesListDelegate extends ListDelegateBase
{
m_mySIS.nextIsSolo = solo;
- int count = m_adapter.getCount();
- boolean skipOffer = 6 > count || XWPrefs.getHideNewgameButtons( m_activity );
+ boolean skipOffer = XWPrefs.getHideNewgameButtons( m_activity );
+ if ( ! skipOffer ) {
+ // If the API's availble, offer to hide buttons as soon as there
+ // are enough games that the list is scrollable. Otherwise fall
+ // back to there being at least four games.
+ if ( Build.VERSION.SDK_INT >= 19 ) {
+ ListView list = getListView();
+ skipOffer = !list.canScrollList( 1 ) && !list.canScrollList( -1 );
+ } else {
+ skipOffer = 4 > m_adapter.getCount();
+ }
+ }
+
if ( skipOffer ) {
handleNewGame( solo );
} else {
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java
index ccd43ad95..d4142fc47 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java
@@ -298,11 +298,12 @@ public class MainActivity extends XWActivity
resultCode, data );
}
- protected void finishFragment()
+ protected void finishFragment( XWFragment fragment )
{
- // Assert.assertTrue( fragment instanceof XWFragment );
// Log.d( TAG, "finishFragment()" );
- getSupportFragmentManager().popBackStack/*Immediate*/();
+ int ID = fragment.getCommitID();
+ getSupportFragmentManager()
+ .popBackStack( ID, FragmentManager.POP_BACK_STACK_INCLUSIVE );
}
//////////////////////////////////////////////////////////////////////
@@ -453,14 +454,14 @@ public class MainActivity extends XWActivity
return frag;
}
- private void addFragmentImpl( Fragment fragment, Bundle bundle,
+ private void addFragmentImpl( XWFragment fragment, Bundle bundle,
String parentName )
{
fragment.setArguments( bundle );
addFragmentImpl( fragment, parentName );
}
- private void addFragmentImpl( final Fragment fragment,
+ private void addFragmentImpl( final XWFragment fragment,
final String parentName )
{
if ( m_safeToCommit ) {
@@ -497,7 +498,7 @@ public class MainActivity extends XWActivity
}
}
- private void safeAddFragment( Fragment fragment, String parentName )
+ private void safeAddFragment( XWFragment fragment, String parentName )
{
Assert.assertTrue( m_safeToCommit );
String newName = fragment.getClass().getSimpleName();
@@ -505,10 +506,11 @@ public class MainActivity extends XWActivity
popUnneeded( fm, newName, parentName );
- fm.beginTransaction()
+ int ID = fm.beginTransaction()
.add( R.id.main_container, fragment, newName )
.addToBackStack( newName )
.commit();
+ fragment.setCommitID( ID );
// Don't do this. It causes an exception if e.g. from fragment.start()
// I wind up launching another fragment and calling into this code
// again. If I need executePendingTransactions() I'm doing something
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java
index 44d92c058..f8b043aba 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayInviteDelegate.java
@@ -75,6 +75,7 @@ public class RelayInviteDelegate extends InviteDelegate {
// private RelayDevsAdapter m_adapter;
private boolean m_immobileConfirmed;
private Activity m_activity;
+ private String m_devIDStr;
public static void launchForResult( Activity activity, int nMissing,
RequestCode requestCode )
@@ -101,6 +102,8 @@ public class RelayInviteDelegate extends InviteDelegate {
super.init( msg, R.string.empty_relay_inviter );
addButtonBar( R.layout.relay_buttons, BUTTONIDS );
+ m_devIDStr = String.format( "%d", DevID.getRelayDevIDInt(m_activity) );
+
// getBundledData( savedInstanceState );
// m_addButton = (ImageButton)findViewById( R.id.manual_add_button );
@@ -437,6 +440,21 @@ public class RelayInviteDelegate extends InviteDelegate {
// }
// } // addPhoneNumbers
+ private void addSelf()
+ {
+ boolean hasSelf = false;
+ for ( DevIDRec rec : m_devIDRecs ) {
+ if ( rec.m_devID.equals( m_devIDStr ) ) {
+ hasSelf = true;
+ break;
+ }
+ }
+ if ( !hasSelf ) {
+ DevIDRec rec = new DevIDRec( "me", m_devIDStr );
+ m_devIDRecs.add( rec );
+ }
+ }
+
private void rebuildList( boolean checkIfAll )
{
Collections.sort( m_devIDRecs, new Comparator() {
@@ -444,15 +462,9 @@ public class RelayInviteDelegate extends InviteDelegate {
return rec1.m_opponent.compareTo(rec2.m_opponent);
}
});
+
+ addSelf();
updateListAdapter( m_devIDRecs.toArray( new DevIDRec[m_devIDRecs.size()] ) );
- // m_adapter = new RelayDevsAdapter();
- // setListAdapter( m_adapter );
- // if ( checkIfAll && m_devIDRecs.size() <= m_nMissing ) {
- // Iterator iter = m_devIDRecs.iterator();
- // while ( iter.hasNext() ) {
- // iter.next().m_isChecked = true;
- // }
- // }
tryEnable();
}
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/UpdateCheckReceiver.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/UpdateCheckReceiver.java
index 572c8178e..1dbd678bc 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/UpdateCheckReceiver.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/UpdateCheckReceiver.java
@@ -177,7 +177,7 @@ public class UpdateCheckReceiver extends BroadcastReceiver {
params.put( k_STRINGSHASH, BuildConfig.STRINGS_HASH );
params.put( k_NAME, packageName );
params.put( k_AVERS, versionCode );
- Log.d( TAG, "current update: %s", params.toString() );
+ // Log.d( TAG, "current update: %s", params.toString() );
new UpdateQueryTask( context, params, fromUI, pm,
packageName, dals ).execute();
} catch ( org.json.JSONException jse ) {
@@ -278,6 +278,7 @@ public class UpdateCheckReceiver extends BroadcastReceiver {
{
boolean gotOne = false;
try {
+ // Log.d( TAG, "makeNotificationsIf(response=%s)", jstr );
JSONObject jobj = new JSONObject( jstr );
if ( null != jobj ) {
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Utils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Utils.java
index b4d98e644..e76107259 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Utils.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Utils.java
@@ -511,8 +511,7 @@ public class Utils {
new ObjectInputStream( new ByteArrayInputStream(bytes) );
result = ois.readObject();
} catch ( Exception ex ) {
- Log.ex( TAG, ex );
- Assert.assertFalse( BuildConfig.DEBUG );
+ Log.d( TAG, ex.getMessage() );
}
return result;
}
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java
index eeec3d7da..db4b076c7 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java
@@ -41,10 +41,12 @@ import junit.framework.Assert;
abstract class XWFragment extends Fragment implements Delegator {
private static final String TAG = XWFragment.class.getSimpleName();
private static final String PARENT_NAME = "PARENT_NAME";
+ private static final String COMMIT_ID = "COMMIT_ID";
private DelegateBase m_dlgt;
private String m_parentName;
private boolean m_hasOptionsMenu = false;
+ private int m_commitID;
private static Set sActiveFrags = new HashSet();
public static XWFragment findOwnsView( View view )
@@ -75,6 +77,9 @@ abstract class XWFragment extends Fragment implements Delegator {
return m_parentName;
}
+ public void setCommitID( int id ) { m_commitID = id; }
+ public int getCommitID() { return m_commitID; }
+
protected void onCreate( DelegateBase dlgt, Bundle sis, boolean hasOptionsMenu )
{
m_hasOptionsMenu = hasOptionsMenu;
@@ -87,6 +92,7 @@ abstract class XWFragment extends Fragment implements Delegator {
Log.d( TAG, "%s.onSaveInstanceState() called", getClass().getSimpleName() );
Assert.assertNotNull( m_parentName );
outState.putString( PARENT_NAME, m_parentName );
+ outState.putInt( COMMIT_ID, m_commitID );
m_dlgt.onSaveInstanceState( outState );
super.onSaveInstanceState( outState );
}
@@ -98,6 +104,7 @@ abstract class XWFragment extends Fragment implements Delegator {
if ( null != sis ) {
m_parentName = sis.getString( PARENT_NAME );
Assert.assertNotNull( m_parentName );
+ m_commitID = sis.getInt( COMMIT_ID );
}
Assert.assertNull( m_dlgt );
m_dlgt = dlgt;
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java
index 57cba9739..49a83d74d 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java
@@ -749,10 +749,11 @@ public class JNIThread extends Thread {
public void handle( JNICmd cmd, Object... args )
{
- m_queue.add( new QueueElem( cmd, true, args ) );
if ( m_stopped && ! JNICmd.CMD_NONE.equals(cmd) ) {
- Log.w( TAG, "adding %s to stopped thread!!!", cmd.toString() );
+ Log.w( TAG, "NOT adding %s to stopped thread!!!", cmd.toString() );
DbgUtils.printStack( TAG );
+ } else {
+ m_queue.add( new QueueElem( cmd, true, args ) );
}
}
diff --git a/xwords4/android/app/src/main/res/values/styles.xml b/xwords4/android/app/src/main/res/values/styles.xml
index 48152edba..8ffaf87a8 100644
--- a/xwords4/android/app/src/main/res/values/styles.xml
+++ b/xwords4/android/app/src/main/res/values/styles.xml
@@ -1,5 +1,7 @@
+
+