offer user a choice between using internal and external storage when

downloading dicts.  Still to do: check if external is available before
offering; and either remove ability to download from within config
dialog or offer that choice there.  Or just use a preference to
determine where storage happens.  Also, on emulator game hangs during
download when using external storage.
This commit is contained in:
Andy2 2011-04-30 14:28:35 -07:00
parent 8caefef406
commit e1e181949e
4 changed files with 135 additions and 23 deletions

View file

@ -239,6 +239,12 @@
<string name="peek_other_summary">Tapping on scoreboard name shows
that player\'s tiles</string>
<string name="storeWhereTitle">Dictionary storage</string>
<string name="storeWhereMsg">Store downloaded dictionaries using
internal or external (SD card) memory?</string>
<string name="button_internal">Internal</string>
<string name="button_sd">External</string>
<string name="phonies_ignore">Ignore phonies</string>
<string name="phonies_warn">Warn if phonies</string>
<string name="phonies_disallow">Disallow phonies</string>

View file

@ -36,6 +36,13 @@ import junit.framework.Assert;
public class DictImportActivity extends XWActivity {
private static boolean s_useSD = false;
public static void setUseSD( boolean useSD )
{
s_useSD = useSD;
}
private class DownloadFilesTask extends AsyncTask<Uri, Integer, Long> {
@Override
protected Long doInBackground( Uri... uris )
@ -108,8 +115,9 @@ public class DictImportActivity extends XWActivity {
private void saveDict( InputStream inputStream, String path )
{
String name = basename( path );
GameUtils.saveDict( this, name, inputStream );
DictLangCache.inval( this, name, true );
if ( GameUtils.saveDict( this, inputStream, name, s_useSD ) ) {
DictLangCache.inval( this, name, true );
}
}
private String basename( String path )

View file

@ -20,6 +20,8 @@
package org.eehouse.android.xw4;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.Button;
@ -44,7 +46,8 @@ import org.eehouse.android.xw4.jni.JNIUtilsImpl;
public class DictsActivity extends XWListActivity
implements View.OnClickListener,
XWListItem.DeleteCallback {
String[] m_dicts;
private String[] m_dicts;
private static final int PICK_STORAGE = 1;
private class DictListAdapter extends XWListAdapter {
private Context m_context;
@ -75,6 +78,36 @@ public class DictsActivity extends XWListActivity
}
}
@Override
protected Dialog onCreateDialog( int id )
{
Assert.assertTrue( PICK_STORAGE == id );
DialogInterface.OnClickListener lstnrSD;
DialogInterface.OnClickListener lstnrIntrnl;
lstnrSD = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) {
DictImportActivity.setUseSD( true );
startActivity( Utils.
mkDownloadActivity( DictsActivity.this ) );
}
};
lstnrIntrnl = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) {
DictImportActivity.setUseSD( false );
startActivity( Utils.
mkDownloadActivity( DictsActivity.this ) );
}
};
return new AlertDialog.Builder( this )
.setTitle( R.string.storeWhereTitle )
.setMessage( R.string.storeWhereMsg )
.setPositiveButton( R.string.button_internal, lstnrIntrnl )
.setNegativeButton( R.string.button_sd, lstnrSD )
.create();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
@ -98,8 +131,13 @@ public class DictsActivity extends XWListActivity
mkListAdapter();
}
public void onClick( View v ) {
startActivity( Utils.mkDownloadActivity( this ) );
public void onClick( View v )
{
if ( GameUtils.haveWriteableSD( this ) ) {
showDialog( PICK_STORAGE );
} else {
startActivity( Utils.mkDownloadActivity( this ) );
}
}
@Override

View file

@ -23,6 +23,7 @@ package org.eehouse.android.xw4;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -419,6 +420,12 @@ public class GameUtils {
}
}
for ( String file : getSDDir( context ).list() ) {
if ( isDict( file ) ) {
al.add( removeDictExtn( file ) );
}
}
return al.toArray( new String[al.size()] );
}
@ -455,7 +462,13 @@ public class GameUtils {
public static void deleteDict( Context context, String name )
{
context.deleteFile( addDictExtn( name ) );
name = addDictExtn( name );
File onSD = getSDPathFor( context, name );
if ( onSD.exists() ) {
onSD.delete();
} else {
context.deleteFile( name );
}
}
public static byte[] openDict( Context context, String name )
@ -482,14 +495,23 @@ public class GameUtils {
Utils.logf( "%s failed to open; likely not built-in", name );
}
// not an asset? Try storage
// not an asset? Try external and internal storage
if ( null == bytes ) {
try {
FileInputStream fis = context.openFileInput( name );
File sdFile = getSDPathFor( context, name );
FileInputStream fis;
if ( null != sdFile && sdFile.exists() ) {
Utils.logf( "loading %s from SD", name );
fis = new FileInputStream( sdFile );
} else {
Utils.logf( "loading %s from private storage", name );
fis = context.openFileInput( name );
}
int len = (int)fis.getChannel().size();
bytes = new byte[len];
fis.read( bytes, 0, len );
fis.close();
Utils.logf( "Successfully loaded %s", name );
} catch ( java.io.FileNotFoundException fnf ) {
Utils.logf( fnf.toString() );
} catch ( java.io.IOException ioe ) {
@ -521,24 +543,36 @@ public class GameUtils {
return result;
}
public static boolean saveDict( Context context, String name, InputStream in )
public static boolean saveDict( Context context, InputStream in,
String name, boolean useSD )
{
boolean success = false;
try {
FileOutputStream fos = context.openFileOutput( name,
Context.MODE_PRIVATE );
byte[] buf = new byte[1024];
int nRead;
while( 0 <= (nRead = in.read( buf, 0, buf.length )) ) {
fos.write( buf, 0, nRead );
File sdFile = null;
if ( useSD ) {
sdFile = getSDPathFor( context, name );
}
if ( null != sdFile || !useSD ) {
try {
FileOutputStream fos;
if ( null != sdFile ) {
fos = new FileOutputStream( sdFile );
} else {
fos = context.openFileOutput( name, Context.MODE_PRIVATE );
}
byte[] buf = new byte[1024];
int nRead;
while( 0 <= (nRead = in.read( buf, 0, buf.length )) ) {
fos.write( buf, 0, nRead );
}
fos.close();
success = true;
} catch ( java.io.FileNotFoundException fnf ) {
Utils.logf( "saveDict: FileNotFoundException: %s", fnf.toString() );
} catch ( java.io.IOException ioe ) {
Utils.logf( "saveDict: IOException: %s", ioe.toString() );
deleteDict( context, name );
}
fos.close();
success = true;
} catch ( java.io.FileNotFoundException fnf ) {
Utils.logf( "saveDict: FileNotFoundException: %s", fnf.toString() );
} catch ( java.io.IOException ioe ) {
Utils.logf( "saveDict: IOException: %s", ioe.toString() );
deleteDict( context, name );
}
return success;
}
@ -771,4 +805,30 @@ public class GameUtils {
}
}
public static boolean haveWriteableSD( Context context )
{
return true; // fixme :-)
}
private static File getSDDir( Context context )
{
File result = null;
File storage = Environment.getExternalStorageDirectory();
if ( null != storage ) {
String packdir = String.format( "Android/data/%s/files/",
context.getPackageName() );
result = new File( storage.getPath(), packdir );
if ( !result.exists() ) {
result.mkdirs();
}
}
return result;
}
private static File getSDPathFor( Context context, String name )
{
File dir = getSDDir( context );
return new File( dir, name );
}
}