diff --git a/xwords4/android/XWords4/build.xml b/xwords4/android/XWords4/build.xml
index b1d8ad988..d1536010c 100644
--- a/xwords4/android/XWords4/build.xml
+++ b/xwords4/android/XWords4/build.xml
@@ -61,6 +61,7 @@
diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml
index 1ce1ffc86..9db8836f9 100644
--- a/xwords4/android/XWords4/res/values/strings.xml
+++ b/xwords4/android/XWords4/res/values/strings.xml
@@ -2127,6 +2127,10 @@
play Crosswords using the wordlist %2$s (for play in %3$s), but it
is not installed. Would you like to download the wordlist or
decline the invitation?
+ You have been invited to
+ play Crosswords using the wordlist %2$s (for play in %3$s), but it
+ is not installed. Would you like to download the wordlist or
+ decline the invitation?DeclineDownloading %s...
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java
index 9f9f5089a..e45f64e3e 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java
@@ -816,9 +816,8 @@ public class BoardActivity extends XWActivity
if ( DlgDelegate.DISMISS_BUTTON != which ) {
GameUtils.launchInviteActivity( BoardActivity.this,
DlgDelegate.EMAIL_BTN == which,
- m_room, null,
- m_gi.dictLang,
- m_gi.nPlayers );
+ m_room, null, m_gi.dictLang,
+ m_gi.dictName, m_gi.nPlayers );
}
} else if ( AlertDialog.BUTTON_POSITIVE == which ) {
JNICmd cmd = JNICmd.CMD_NONE;
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java
index 426e5dd23..f0a09b78c 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java
@@ -547,7 +547,7 @@ public class DBUtils {
DBHelper.ROOMNAME, nli.room,
DBHelper.INVITEID, nli.inviteID,
DBHelper.DICTLANG, nli.lang,
- DBHelper.NUM_PLAYERS, nli.nPlayers );
+ DBHelper.NUM_PLAYERS, nli.nPlayersT );
Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns,
selection, null, null, null, null );
if ( 1 == cursor.getCount() && cursor.moveToFirst() ) {
@@ -563,7 +563,7 @@ public class DBUtils {
{
long rowid = ROWID_NOTFOUND;
NetLaunchInfo nli = new NetLaunchInfo( data );
- if ( null != nli ) {
+ if ( null != nli && nli.isValid() ) {
rowid = getRowIDForOpen( context, nli );
}
return rowid;
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DispatchNotify.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DispatchNotify.java
index a82d1addc..57d674d62 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DispatchNotify.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DispatchNotify.java
@@ -64,11 +64,30 @@ public class DispatchNotify extends Activity {
if ( !tryHandle( gameID ) ) {
mustLaunch = true;
}
- } else if ( null != data ) {
- long rowid = DBUtils.getRowIDForOpen( this, data );
+ } else if ( null != data ) { // relay invite redirected URL case
+ NetLaunchInfo nli = new NetLaunchInfo( data );
+ long rowid = DBUtils.getRowIDForOpen( this, nli );
if ( DBUtils.ROWID_NOTFOUND == rowid ) {
- if ( !tryHandle( data ) ) {
- mustLaunch = true;
+ boolean haveDict;
+ if ( null == nli.dict ) { // can only test for language support
+ haveDict =
+ 0 < DictLangCache.getHaveLang( this, nli.lang ).length;
+ } else {
+ haveDict = DictLangCache.haveDict( this, nli.lang, nli.dict );
+ }
+ if ( haveDict ) {
+ if ( !tryHandle( data ) ) {
+ mustLaunch = true;
+ }
+ } else {
+ Intent intent = MultiService.makeMissingDictIntent( this,
+ nli );
+ intent.putExtra( MultiService.OWNER,
+ MultiService.OWNER_RELAY );
+ // do we have gameID?
+ MultiService.
+ postMissingDictNotification( this, intent,
+ nli.inviteID.hashCode() );
}
} else {
DbgUtils.logf( "DispatchNotify: dropping duplicate invite" );
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java
index 2ab40f4bc..1fc22e503 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GCMIntentService.java
@@ -74,7 +74,7 @@ public class GCMIntentService extends GCMBaseIntentService {
public static void init( Application app )
{
int sdkVersion = Integer.valueOf( android.os.Build.VERSION.SDK );
- if ( 8 <= sdkVersion ) {
+ if ( 8 <= sdkVersion && 0 < GCMConsts.SENDER_ID.length() ) {
try {
GCMRegistrar.checkDevice( app );
// GCMRegistrar.checkManifest( app );
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java
index e5977edc7..ed9e46bb5 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java
@@ -24,15 +24,8 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import android.os.Environment;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
import java.util.Arrays;
-import android.content.res.AssetManager;
import java.util.concurrent.locks.Lock;
import java.util.HashMap;
import java.util.HashSet;
@@ -432,7 +425,7 @@ public class GameUtils {
}
private static long makeNewMultiGame( Context context, CommsAddrRec addr,
- int[] lang, String dict,
+ int[] lang, String[] dict,
int nPlayersT, int nPlayersH,
String inviteID, int gameID,
boolean isHost )
@@ -440,8 +433,9 @@ public class GameUtils {
long rowid = -1;
CurGameInfo gi = new CurGameInfo( context, true );
- gi.setLang( lang[0], dict );
+ gi.setLang( lang[0], dict[0] );
lang[0] = gi.dictLang;
+ dict[0] = gi.dictName;
gi.setNPlayers( nPlayersT, nPlayersH );
gi.juggle();
if ( 0 != gameID ) {
@@ -466,7 +460,8 @@ public class GameUtils {
public static long makeNewNetGame( Context context, String room,
String inviteID, int[] lang,
- int nPlayersT, int nPlayersH )
+ String[] dict, int nPlayersT,
+ int nPlayersH )
{
long rowid = -1;
String relayName = XWPrefs.getDefaultRelayHost( context );
@@ -474,21 +469,24 @@ public class GameUtils {
CommsAddrRec addr = new CommsAddrRec( relayName, relayPort );
addr.ip_relay_invite = room;
- return makeNewMultiGame( context, addr, lang, null, nPlayersT,
+ return makeNewMultiGame( context, addr, lang, dict, nPlayersT,
nPlayersH, inviteID, 0, false );
}
public static long makeNewNetGame( Context context, String room,
- String inviteID, int lang, int nPlayers )
+ String inviteID, int lang, String dict,
+ int nPlayers )
{
int[] langarr = { lang };
- return makeNewNetGame( context, room, inviteID, langarr, nPlayers, 1 );
+ String[] dictArr = { dict };
+ return makeNewNetGame( context, room, inviteID, langarr, dictArr,
+ nPlayers, 1 );
}
public static long makeNewNetGame( Context context, NetLaunchInfo info )
{
return makeNewNetGame( context, info.room, info.inviteID, info.lang,
- info.nPlayers );
+ info.dict, info.nPlayersT );
}
public static long makeNewBTGame( Context context, int gameID,
@@ -512,11 +510,12 @@ public class GameUtils {
{
long rowid = -1;
int[] langa = { lang };
+ String[] dicta = { dict };
boolean isHost = null == addr;
if ( isHost ) {
addr = new CommsAddrRec(CommsAddrRec.CommsConnType.COMMS_CONN_SMS);
}
- return makeNewMultiGame( context, addr, langa, dict, nPlayersT,
+ return makeNewMultiGame( context, addr, langa, dicta, nPlayersT,
nPlayersH, null, gameID, isHost );
}
@@ -539,13 +538,14 @@ public class GameUtils {
public static void launchInviteActivity( Context context,
boolean choseEmail,
String room, String inviteID,
- int lang, int nPlayers )
+ int lang, String dict,
+ int nPlayers )
{
if ( null == inviteID ) {
inviteID = makeRandomID();
}
Uri gameUri = NetLaunchInfo.makeLaunchUri( context, room, inviteID,
- lang, nPlayers );
+ lang, dict, nPlayers );
if ( null != gameUri ) {
int fmtId = choseEmail? R.string.invite_htmf : R.string.invite_txtf;
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java
index ff2ef90b5..04be68eaa 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java
@@ -88,7 +88,7 @@ public class GamesList extends XWExpandableListActivity
private GameListAdapter m_adapter;
private String m_missingDict;
- private String[] m_missingDictNames;
+ private String m_missingDictName;
private long m_missingDictRowId;
private String[] m_sameLangDicts;
private int m_missingDictLang;
@@ -115,10 +115,15 @@ public class GamesList extends XWExpandableListActivity
lstnr = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) {
// just do one
- NetUtils.downloadDictInBack( GamesList.this,
- m_missingDictLang,
- m_missingDictNames[0],
- GamesList.this );
+ if ( null == m_missingDictName ) {
+ DictsActivity.launchAndDownload( GamesList.this,
+ m_missingDictLang );
+ } else {
+ NetUtils.downloadDictInBack( GamesList.this,
+ m_missingDictLang,
+ m_missingDictName,
+ GamesList.this );
+ }
}
};
String message;
@@ -130,7 +135,7 @@ public class GamesList extends XWExpandableListActivity
gameName, langName );
} else {
message = getString( R.string.no_dict_substf,
- gameName, m_missingDictNames[0],
+ gameName, m_missingDictName,
langName );
}
@@ -163,8 +168,10 @@ public class GamesList extends XWExpandableListActivity
dict = DictLangCache.stripCount( dict );
GameUtils.replaceDicts( GamesList.this,
m_missingDictRowId,
- m_missingDictNames[0],
+ m_missingDictName,
dict );
+ GameUtils.launchGame( GamesList.this,
+ m_missingDictRowId );
}
};
dialog = new AlertDialog.Builder( this )
@@ -404,7 +411,7 @@ public class GamesList extends XWExpandableListActivity
super.onSaveInstanceState( outState );
outState.putLong( SAVE_ROWID, m_rowid );
outState.putLong( SAVE_GROUPID, m_groupid );
- outState.putStringArray( SAVE_DICTNAMES, m_missingDictNames );
+ outState.putString( SAVE_DICTNAMES, m_missingDictName );
if ( null != m_netLaunchInfo ) {
m_netLaunchInfo.putSelf( outState );
}
@@ -416,7 +423,7 @@ public class GamesList extends XWExpandableListActivity
m_rowid = bundle.getLong( SAVE_ROWID );
m_groupid = bundle.getLong( SAVE_GROUPID );
m_netLaunchInfo = new NetLaunchInfo( bundle );
- m_missingDictNames = bundle.getStringArray( SAVE_DICTNAMES );
+ m_missingDictName = bundle.getString( SAVE_DICTNAMES );
}
}
@@ -834,13 +841,21 @@ public class GamesList extends XWExpandableListActivity
missingNames,
missingLang );
if ( !hasDicts ) {
- m_missingDictNames = missingNames[0];
m_missingDictLang = missingLang[0];
+ if ( 0 < missingNames[0].length ) {
+ m_missingDictName = missingNames[0][0];
+ } else {
+ m_missingDictName = null;
+ }
m_missingDictRowId = rowid;
if ( 0 == DictLangCache.getLangCount( this, m_missingDictLang ) ) {
showDialog( WARN_NODICT );
- } else {
+ } else if ( null != m_missingDictName ) {
showDialog( WARN_NODICT_SUBST );
+ } else {
+ String dict = DictLangCache.getHaveLang( this, m_missingDictLang)[0];
+ GameUtils.replaceDicts( this, m_missingDictRowId, null, dict );
+ GameUtils.launchGame( this, m_missingDictRowId );
}
}
return hasDicts;
@@ -911,13 +926,18 @@ public class GamesList extends XWExpandableListActivity
private void startNewNetGame( Intent intent )
{
- Uri data = intent.getData();
- if ( null != data ) {
- NetLaunchInfo info = new NetLaunchInfo( data );
- if ( info.isValid() ) {
- startNewNetGame( info );
+ NetLaunchInfo info = null;
+ if ( MultiService.isMissingDictIntent( intent ) ) {
+ info = new NetLaunchInfo( intent );
+ } else {
+ Uri data = intent.getData();
+ if ( null != data ) {
+ info = new NetLaunchInfo( data );
}
}
+ if ( null != info && info.isValid() ) {
+ startNewNetGame( info );
+ }
} // startNewNetGame
private void startHasGameID( int gameID )
@@ -972,4 +992,9 @@ public class GamesList extends XWExpandableListActivity
return dialog;
}
+ public static void onGameDictDownload( Context context, Intent intent )
+ {
+ intent.setClass( context, GamesList.class );
+ context.startActivity( intent );
+ }
}
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiService.java
index 8c06598b0..4e4d21686 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiService.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiService.java
@@ -31,6 +31,8 @@ public class MultiService {
public static final String LANG = "LANG";
public static final String DICT = "DICT";
public static final String GAMEID = "GAMEID";
+ public static final String INVITEID = "INVITEID"; // relay only
+ public static final String ROOM = "ROOM";
public static final String GAMENAME = "GAMENAME";
public static final String NPLAYERST = "NPLAYERST";
public static final String NPLAYERSH = "NPLAYERSH";
@@ -38,6 +40,7 @@ public class MultiService {
public static final String OWNER = "OWNER";
public static final int OWNER_SMS = 1;
+ public static final int OWNER_RELAY = 2;
private BTEventListener m_li;
@@ -84,11 +87,39 @@ public class MultiService {
}
}
+ public static void fillInviteIntent( Intent intent, String gameName,
+ int lang, String dict,
+ int nPlayersT, int nPlayersH )
+ {
+ intent.putExtra( GAMENAME, gameName );
+ intent.putExtra( LANG, lang );
+ intent.putExtra( DICT, dict );
+ intent.putExtra( NPLAYERST, nPlayersT ); // both of these used
+ intent.putExtra( NPLAYERSH, nPlayersH );
+ }
+
+ public static Intent makeMissingDictIntent( Context context, String gameName,
+ int lang, String dict,
+ int nPlayersT, int nPlayersH )
+ {
+ Intent intent = new Intent( context, DictsActivity.class );
+ fillInviteIntent( intent, gameName, lang, dict, nPlayersT, nPlayersH );
+ return intent;
+ }
+
+ public static Intent makeMissingDictIntent( Context context, NetLaunchInfo nli )
+ {
+ Intent intent = makeMissingDictIntent( context, null, nli.lang, nli.dict,
+ nli.nPlayersT, 1 );
+ intent.putExtra( ROOM, nli.room );
+ return intent;
+ }
+
public static boolean isMissingDictIntent( Intent intent )
{
return intent.hasExtra( LANG )
- && intent.hasExtra( DICT )
- && intent.hasExtra( GAMEID )
+ // && intent.hasExtra( DICT )
+ && (intent.hasExtra( GAMEID ) || intent.hasExtra( ROOM ))
&& intent.hasExtra( GAMENAME )
&& intent.hasExtra( NPLAYERST )
&& intent.hasExtra( NPLAYERSH );
@@ -102,8 +133,10 @@ public class MultiService {
String langStr = DictLangCache.getLangName( context, lang );
String dict = intent.getStringExtra( DICT );
String inviter = intent.getStringExtra( INVITER );
- String msg = context.getString( R.string.invite_dict_missing_bodyf,
- inviter, dict, langStr );
+ int msgID = (null == inviter) ? R.string.invite_dict_missing_body_nonamef
+ : R.string.invite_dict_missing_bodyf;
+ String msg = context.getString( msgID, inviter, dict, langStr );
+
return new AlertDialog.Builder( context )
.setTitle( R.string.invite_dict_missing_title )
.setMessage( msg)
@@ -112,6 +145,13 @@ public class MultiService {
.create();
}
+ public static void postMissingDictNotification( Context content,
+ Intent intent, int id )
+ {
+ Utils.postNotification( content, intent, R.string.missing_dict_title,
+ R.string.missing_dict_detail, id );
+ }
+
// resend the intent, but only if the dict it names is here. (If
// it's not, we may need to try again later, e.g. because our cue
// was a focus gain.)
@@ -123,11 +163,15 @@ public class MultiService {
String dict = intent.getStringExtra( DICT );
downloaded = DictLangCache.haveDict( context, lang, dict );
if ( downloaded ) {
- int owner = intent.getIntExtra( OWNER, -1 );
- if ( owner == OWNER_SMS ) {
+ switch ( intent.getIntExtra( OWNER, -1 ) ) {
+ case OWNER_SMS:
SMSService.onGameDictDownload( context, intent );
- } else {
- DbgUtils.logf( "unexpected OWNER: %d", owner );
+ break;
+ case OWNER_RELAY:
+ GamesList.onGameDictDownload( context, intent );
+ break;
+ default:
+ DbgUtils.logf( "unexpected OWNER" );
}
}
}
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetLaunchInfo.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetLaunchInfo.java
index d73370d79..53a9c61ab 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetLaunchInfo.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetLaunchInfo.java
@@ -21,8 +21,9 @@
package org.eehouse.android.xw4;
import android.content.Context;
-import android.net.Uri;
+import android.content.Intent;
import android.net.Uri.Builder;
+import android.net.Uri;
import android.os.Bundle;
import java.net.URLEncoder;
@@ -30,11 +31,13 @@ import java.net.URLEncoder;
public class NetLaunchInfo {
public String room;
public String inviteID;
+ public String dict;
public int lang;
- public int nPlayers;
+ public int nPlayersT;
private static final String LANG = "netlaunchinfo_lang";
private static final String ROOM = "netlaunchinfo_room";
+ private static final String DICT = "netlaunchinfo_dict";
private static final String INVITEID = "netlaunchinfo_inviteid";
private static final String NPLAYERS = "netlaunchinfo_nplayers";
private static final String VALID = "netlaunchinfo_valid";
@@ -46,7 +49,8 @@ public class NetLaunchInfo {
bundle.putInt( LANG, lang );
bundle.putString( ROOM, room );
bundle.putString( INVITEID, inviteID );
- bundle.putInt( NPLAYERS, nPlayers );
+ bundle.putString( DICT, dict );
+ bundle.putInt( NPLAYERS, nPlayersT );
bundle.putBoolean( VALID, m_valid );
}
@@ -54,8 +58,9 @@ public class NetLaunchInfo {
{
lang = bundle.getInt( LANG );
room = bundle.getString( ROOM );
+ dict = bundle.getString( DICT );
inviteID = bundle.getString( INVITEID );
- nPlayers = bundle.getInt( NPLAYERS );
+ nPlayersT = bundle.getInt( NPLAYERS );
m_valid = bundle.getBoolean( VALID );
}
@@ -66,10 +71,11 @@ public class NetLaunchInfo {
try {
room = data.getQueryParameter( "room" );
inviteID = data.getQueryParameter( "id" );
+ dict = data.getQueryParameter( "wl" );
String langStr = data.getQueryParameter( "lang" );
lang = Integer.decode( langStr );
String np = data.getQueryParameter( "np" );
- nPlayers = Integer.decode( np );
+ nPlayersT = Integer.decode( np );
m_valid = true;
} catch ( Exception e ) {
DbgUtils.logf( "unable to parse \"%s\"", data.toString() );
@@ -77,8 +83,21 @@ public class NetLaunchInfo {
}
}
+ public NetLaunchInfo( Intent intent )
+ {
+ room = intent.getStringExtra( MultiService.ROOM );
+ inviteID = intent.getStringExtra( MultiService.INVITEID );
+ lang = intent.getIntExtra( MultiService.LANG, -1 );
+ dict = intent.getStringExtra( MultiService.DICT );
+ nPlayersT = intent.getIntExtra( MultiService.NPLAYERST, -1 );
+ m_valid = null != room
+ && -1 != lang
+ && -1 != nPlayersT;
+ }
+
public static Uri makeLaunchUri( Context context, String room,
- String inviteID, int lang, int nPlayers )
+ String inviteID, int lang,
+ String dict, int nPlayersT )
{
Builder ub = new Builder();
ub.scheme( "http" );
@@ -86,9 +105,12 @@ public class NetLaunchInfo {
XWPrefs.getDefaultRedirHost( context ) ) );
ub.appendQueryParameter( "lang", String.format("%d", lang ) );
- ub.appendQueryParameter( "np", String.format( "%d", nPlayers ) );
+ ub.appendQueryParameter( "np", String.format( "%d", nPlayersT ) );
ub.appendQueryParameter( "room", room );
ub.appendQueryParameter( "id", inviteID );
+ if ( null != dict ) {
+ ub.appendQueryParameter( "wl", dict );
+ }
return ub.build();
}
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java
index 3cfee37c9..039aaa23d 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java
@@ -318,13 +318,14 @@ public class NewGameActivity extends XWActivity {
String inviteID = null;
long rowid;
int[] lang = {0};
+ String[] dict = {null};
final int nPlayers = 2; // hard-coded for no-configure case
if ( networked ) {
room = GameUtils.makeRandomID();
inviteID = GameUtils.makeRandomID();
rowid = GameUtils.makeNewNetGame( this, room, inviteID, lang,
- nPlayers, 1 );
+ dict, nPlayers, 1 );
} else {
rowid = GameUtils.saveNew( this, new CurGameInfo( this ) );
}
@@ -333,7 +334,8 @@ public class NewGameActivity extends XWActivity {
GameUtils.launchGame( this, rowid, networked );
if ( networked ) {
GameUtils.launchInviteActivity( this, choseEmail, room,
- inviteID, lang[0], nPlayers );
+ inviteID, lang[0], dict[0],
+ nPlayers );
}
} else {
GameUtils.doConfig( this, rowid, GameConfig.class );
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java
index 6121e7196..18cbd8c88 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SMSService.java
@@ -424,17 +424,15 @@ public class SMSService extends Service {
makeForInvite( phone, gameID, gameName, lang, dict,
nPlayersT, nPlayersH );
} else {
- Intent intent = new Intent( this, DictsActivity.class );
- fillInviteIntent( intent, phone, gameID, gameName, lang, dict,
- nPlayersT, nPlayersH );
+ Intent intent = MultiService
+ .makeMissingDictIntent( this, gameName, lang, dict,
+ nPlayersT, nPlayersH );
+ intent.putExtra( PHONE, phone );
intent.putExtra( MultiService.OWNER,
MultiService.OWNER_SMS );
intent.putExtra( MultiService.INVITER,
Utils.phoneToContact( this, phone, true ) );
- Utils.postNotification( this, intent,
- R.string.missing_dict_title,
- R.string.missing_dict_detail,
- gameID );
+ MultiService.postMissingDictNotification( this, intent, gameID );
}
break;
case DATA:
@@ -591,11 +589,8 @@ public class SMSService extends Service {
{
intent.putExtra( PHONE, phone );
intent.putExtra( MultiService.GAMEID, gameID );
- intent.putExtra( MultiService.GAMENAME, gameName );
- intent.putExtra( MultiService.LANG, lang );
- intent.putExtra( MultiService.DICT, dict );
- intent.putExtra( MultiService.NPLAYERST, nPlayersT );
- intent.putExtra( MultiService.NPLAYERSH, nPlayersH );
+ MultiService.fillInviteIntent( intent, gameName, lang, dict,
+ nPlayersT, nPlayersH );
}
private void feedMessage( int gameID, byte[] msg, CommsAddrRec addr )
diff --git a/xwords4/android/scripts/gen_gcmid.sh b/xwords4/android/scripts/gen_gcmid.sh
index 9ca58833a..bf719f2ab 100755
--- a/xwords4/android/scripts/gen_gcmid.sh
+++ b/xwords4/android/scripts/gen_gcmid.sh
@@ -1,8 +1,11 @@
#!/bin/sh
+set -e -u
+
+GCM_SENDER_ID=${GCM_SENDER_ID:-""}
+
if [ -z "$GCM_SENDER_ID" ]; then
- echo "GCM_SENDER_ID not in env"
- exit 1
+ echo "GCM_SENDER_ID empty; GCM use will be disabled" >&2
fi
cat <
";
+ }
+}
+
+$g_androidStrings = array( "android", );
$scheme = "newxwgame";
$host = "10.0.2.2";
@@ -10,33 +34,46 @@ $lang = $_REQUEST["lang"];
$room = $_REQUEST["room"];
$np = $_REQUEST["np"];
$id = $_REQUEST["id"];
+$wl = $_REQUEST["wl"];
-$content = "0; url=$scheme://$host?room=$room&lang=$lang&np=$np";
+$agent = $_SERVER['HTTP_USER_AGENT'];
+$onAndroid = false;
+for ( $ii = 0; $ii < count($g_androidStrings) && !$onAndroid; ++$ii ) {
+ $needle = $g_androidStrings[$ii];
+ $onAndroid = 0 != stripos( $agent, $needle );
+}
+$onFire = 0 != stripos( $agent, 'silk' );
+
+$localurl = "$scheme://$host?room=$room&lang=$lang&np=$np";
if ( $id != "" ) {
- $content .= "&id=$id";
+ $localurl .= "&id=$id";
+}
+if ( $wl != "" ) {
+ $localurl .= "&wl=$wl";
}
+if ( $onAndroid || $onFire ) {
print <<
-Crosswords SMS redirect
-
+Crosswords Invite redirect
-
+
-
redirecting to Crosswords....
-
-
This page is meant to be viewed (briefly) on your Android device after which Crosswords should launch.
- If this fails it's probably because you don't have a new enough version of Crosswords installed.
+
It appears you're running on a Kindle Fire, whose non-standard (from
+an Android perspective) OS doesn't support the custom schemes on which
+Crosswords invitations depend. If you want to accept this invitation
+you'll need to do it the manual way:
+
+
+
Open Crosswords, and navigate to the main Games List screen
+
Choose "Add game", either from the menu or the button at the bottom.
+
Under "New Networked game", choose "Configure first".
+
$langText
+
As the room name, enter "$room".
+
Make sure the total number of players shown is $np and that only one of them is not an "Off-device player".
+
Now tap the "Play game" button at the bottom (above the keyboard). Your new game should open and connect.
+
+
I'm sorry this is so complicated. I'm trying to find a
+workaround for this limitation in the Kindle Fire's operating system
+but for now this is all I can offer.
+
+
(Just in case Amazon's fixed the
+problem, here is the link that should open
+your new game.)
+
+
+EOF;
+} else {
+$subject = "Android device not identified";
+
+$body = htmlentities("My browser is running on an android device but"
+. " says its user agent is: \"$agent\". Please fix your script to recognize"
+. " this as an Android browser.");
+
+print <<
+
+
+Crosswords Invite redirect
+
+
+
+
+
+
This page is meant to be viewed on a browser on your Android
+ device. Please open the email that sent you here on that device and
+ revisit this link to complete the invitation process.
+
+
+
(If you are viewing this on an Android device, you've
+ found a bug! Please email me (and be
+ sure to leave the user agent string in the email body.)
+