when sd card is umounted, android sends a message to apps. I can't

figure out how to get that so I ignore it and am killed then
relaunched if I have a dict file open on the SD.  On relauch, don't
crash.  Instead, check if any dicts used by the game is unreachable
and put up an alert with only one choice: Close game.  Thought about
using the missing-dicts stuff from GamesList, but this is a special
case that should be seen only when user umounts while a BoardActivity
instance is frontmost.
This commit is contained in:
Andy2 2011-08-18 07:54:00 -07:00
parent 7a1346e530
commit fd4e627628
3 changed files with 125 additions and 80 deletions

View file

@ -389,13 +389,18 @@
<string name="subst_dict_title">Substitute dictionary (wordcount)</string> <string name="subst_dict_title">Substitute dictionary (wordcount)</string>
<string name="button_substdict">Substitute</string> <string name="button_substdict">Substitute</string>
<string name="button_close_game">Close game</string>
<string name="no_dict_finish">A dictionary this game is using has
disappeared. (Usually this means it\'s on an external card that
is no longer available.)</string>
<string name="no_dictf">Unable to open game \"%1$s\" because no <string name="no_dictf">Unable to open game \"%1$s\" because no
%2$s dictionary found. (It may have been deleted, or stored on %2$s dictionary found. (It may have been deleted, or stored on
an an SD card that\'s been unmounted.)</string> an external card that is no longer available.)</string>
<string name="no_dict_substf">Unable to open game \"%1$s\" because <string name="no_dict_substf">Unable to open game \"%1$s\" because
dictionary %2$s not found. (It may have been deleted, or stored dictionary %2$s not found. (It may have been deleted, or stored
on an an SD card that\'s been unmounted.) You can download a on an external card that is no longer available.) You can
replacement or substitute another %3$s dictionary.</string> download a replacement or substitute another %3$s
dictionary.</string>
<string name="msg_ask_password">Password for \"%s\":</string> <string name="msg_ask_password">Password for \"%s\":</string>

View file

@ -38,6 +38,7 @@ import android.app.Dialog;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.EditText; import android.widget.EditText;
@ -68,6 +69,7 @@ public class BoardActivity extends XWActivity
private static final int QUERY_ENDGAME = DLG_OKONLY + 7; private static final int QUERY_ENDGAME = DLG_OKONLY + 7;
private static final int DLG_DELETED = DLG_OKONLY + 8; private static final int DLG_DELETED = DLG_OKONLY + 8;
private static final int DLG_INVITE = DLG_OKONLY + 9; private static final int DLG_INVITE = DLG_OKONLY + 9;
private static final int DLG_NODICT = DLG_OKONLY + 10;
private static final int CHAT_REQUEST = 1; private static final int CHAT_REQUEST = 1;
private static final int SCREEN_ON_TIME = 10 * 60 * 1000; // 10 mins private static final int SCREEN_ON_TIME = 10 * 60 * 1000; // 10 mins
@ -80,7 +82,7 @@ public class BoardActivity extends XWActivity
private int m_jniGamePtr; private int m_jniGamePtr;
private GameUtils.GameLock m_gameLock; private GameUtils.GameLock m_gameLock;
private CurGameInfo m_gi; private CurGameInfo m_gi;
CommsTransport m_xport; private CommsTransport m_xport;
private Handler m_handler = null; private Handler m_handler = null;
private TimerRunnable[] m_timers; private TimerRunnable[] m_timers;
private Runnable m_screenTimer; private Runnable m_screenTimer;
@ -286,6 +288,21 @@ public class BoardActivity extends XWActivity
.create(); .create();
} }
break; break;
case DLG_NODICT:
dialog = new AlertDialog.Builder( this )
.setTitle( R.string.no_dict_title )
.setMessage( R.string.no_dict_finish )
.setPositiveButton( R.string.button_close_game, null )
.create();
OnDismissListener dlstnr;
dlstnr = new OnDismissListener() {
public void onDismiss( DialogInterface di ) {
// removeDialog( DLG_NODICT );
finish();
}
};
dialog.setOnDismissListener( dlstnr );
break;
default: default:
// just drop it; super.onCreateDialog likely failed // just drop it; super.onCreateDialog likely failed
break; break;
@ -1044,15 +1061,21 @@ public class BoardActivity extends XWActivity
private void loadGame() private void loadGame()
{ {
if ( 0 == m_jniGamePtr ) { if ( 0 == m_jniGamePtr ) {
String[] dictNames = m_gi.dictNames();
GameUtils.DictPairs pairs = GameUtils.openDicts( this, dictNames );
if ( pairs.anyMissing( dictNames ) ) {
showDialog( DLG_NODICT );
} else {
String langName = m_gi.langName();
Assert.assertNull( m_gameLock ); Assert.assertNull( m_gameLock );
m_gameLock = new GameUtils.GameLock( m_rowid, true ).lock(); m_gameLock = new GameUtils.GameLock( m_rowid, true ).lock();
byte[] stream = GameUtils.savedGame( this, m_gameLock ); byte[] stream = GameUtils.savedGame( this, m_gameLock );
XwJNI.gi_from_stream( m_gi, stream ); XwJNI.gi_from_stream( m_gi, stream );
String[] dictNames = m_gi.dictNames();
GameUtils.DictPairs pairs = GameUtils.openDicts( this, dictNames );
String langName = m_gi.langName();
m_jniGamePtr = XwJNI.initJNI(); m_jniGamePtr = XwJNI.initJNI();
if ( m_gi.serverRole != DeviceRole.SERVER_STANDALONE ) { if ( m_gi.serverRole != DeviceRole.SERVER_STANDALONE ) {
@ -1128,6 +1151,7 @@ public class BoardActivity extends XWActivity
trySendChats(); trySendChats();
} }
}
} // loadGame } // loadGame
private void checkAndHandle( JNIThread.JNICmd cmd ) private void checkAndHandle( JNIThread.JNICmd cmd )
@ -1209,9 +1233,9 @@ public class BoardActivity extends XWActivity
}); });
} // populateToolbar } // populateToolbar
private DialogInterface.OnDismissListener makeODLforBlocking( final int id ) private OnDismissListener makeODLforBlocking( final int id )
{ {
return new DialogInterface.OnDismissListener() { return new OnDismissListener() {
public void onDismiss( DialogInterface di ) { public void onDismiss( DialogInterface di ) {
releaseIfBlocking(); releaseIfBlocking();
removeDialog( id ); removeDialog( id );

View file

@ -158,7 +158,23 @@ public class GameUtils {
public DictPairs( byte[][] bytes, String[] paths ) { public DictPairs( byte[][] bytes, String[] paths ) {
m_bytes = bytes; m_paths = paths; m_bytes = bytes; m_paths = paths;
} }
public boolean anyMissing( final String[] names )
{
boolean missing = false;
for ( int ii = 0; ii < m_paths.length; ++ii ) {
if ( names[ii] != null ) {
// It's ok for there to be no dict IFF there's no
// name. That's a player using the default dict.
if ( null == m_paths[ii] && null == m_bytes[ii] ) {
missing = true;
break;
} }
}
}
return missing;
}
} // DictPairs
private static Object s_syncObj = new Object(); private static Object s_syncObj = new Object();