From 5ef7697c05e5a3e05e71f3c7c7de04322e8fa9d4 Mon Sep 17 00:00:00 2001 From: eehouse Date: Sat, 13 Mar 2010 23:10:58 +0000 Subject: [PATCH] download dicts under app control (with new activity) and save them locally rather than leave them in the browser's downloads directory. Fix code that expects all files in local storage to be games (since dicts are now there too.) --- xwords4/android/XWords4/AndroidManifest.xml | 15 ++- .../android/xw4/DictImportActivity.java | 98 +++++++++++++++++++ .../org/eehouse/android/xw4/GameConfig.java | 11 +-- .../eehouse/android/xw4/GameListAdapter.java | 14 +-- .../org/eehouse/android/xw4/GamesList.java | 7 +- .../src/org/eehouse/android/xw4/Utils.java | 70 +++++++++---- .../org/eehouse/android/xw4/XWConstants.java | 1 + 7 files changed, 175 insertions(+), 41 deletions(-) create mode 100644 xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportActivity.java diff --git a/xwords4/android/XWords4/AndroidManifest.xml b/xwords4/android/XWords4/AndroidManifest.xml index 1763ef74c..e9b6d8f4a 100644 --- a/xwords4/android/XWords4/AndroidManifest.xml +++ b/xwords4/android/XWords4/AndroidManifest.xml @@ -57,8 +57,6 @@ android:screenOrientation="sensor" android:configChanges="keyboardHidden|orientation" > - @@ -86,6 +84,19 @@ > + + + + + + + + + + + diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportActivity.java new file mode 100644 index 000000000..024b47577 --- /dev/null +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictImportActivity.java @@ -0,0 +1,98 @@ +/* -*- compile-command: "cd ../../../../../; ant install"; -*- */ + +package org.eehouse.android.xw4; + +import android.app.Activity; +import android.os.Bundle; +import android.os.AsyncTask; +import android.content.Intent; +import android.net.Uri; +import android.view.Window; +import android.widget.ProgressBar; +import java.io.InputStream; +import java.net.URI; + +import junit.framework.Assert; + +public class DictImportActivity extends Activity { + + private class DownloadFilesTask extends AsyncTask { + @Override + protected Long doInBackground( Uri... uris ) + { + int count = uris.length; + Assert.assertTrue( 1 == count ); + long totalSize = 0; + for ( int ii = 0; ii < count; ii++ ) { + Uri uri = uris[ii]; + Utils.logf( "trying %s", uri ); + + try { + URI jUri = new URI( uri.getScheme(), + uri.getSchemeSpecificPart(), + uri.getFragment() ); + InputStream is = jUri.toURL().openStream(); + saveDict( is, uri.getPath() ); + } catch ( java.net.URISyntaxException use ) { + Utils.logf( "URISyntaxException: %s" + use.toString() ); + } catch ( java.net.MalformedURLException mue ) { + Utils.logf( "MalformedURLException: %s" + mue.toString() ); + } catch ( java.io.IOException ioe ) { + Utils.logf( "IOException: %s" + ioe.toString() ); + } + } + return totalSize; + } + + @Override + protected void onPostExecute( Long result ) + { + Utils.logf( "onPostExecute passed %d", result ); + finish(); + } + } // class DownloadFilesTask + + @Override + protected void onCreate( Bundle savedInstanceState ) + { + super.onCreate( savedInstanceState ); + + requestWindowFeature( Window.FEATURE_LEFT_ICON ); + setContentView( R.layout.import_dict ); + getWindow().setFeatureDrawableResource( Window.FEATURE_LEFT_ICON, + R.drawable.icon48x48 ); + + ProgressBar progressBar = (ProgressBar)findViewById( R.id.progress_bar ); + + Intent intent = getIntent(); + Uri uri = intent.getData(); + if ( null != uri) { + if ( null != intent.getType() + && intent.getType().equals( "application/x-xwordsdict" ) ) { + Utils.logf( "based on MIME type" ); + new DownloadFilesTask().execute( uri ); + } else if ( uri.toString().endsWith( ".xwd" ) ) { + Utils.logf( "based on file extn" ); + new DownloadFilesTask().execute( uri ); + } else { + Utils.logf( "bogus intent: %s/%s", intent.getType(), uri ); + finish(); + } + } + } + + private void saveDict( InputStream inputStream, String path ) + { + int slashLoc = path.lastIndexOf('/'); + String name = path.substring( slashLoc + 1 ); + try { + Utils.saveDict( this, name, inputStream ); + inputStream.close(); + } catch ( java.io.IOException ioe ) { + Utils.logf( "IOException: %s" + ioe.toString() ); + } + } + +} + + diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java index bc465a2eb..37120688b 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameConfig.java @@ -385,7 +385,10 @@ public class GameConfig extends Activity implements View.OnClickListener { View selectedItemView, int position, long id) { if ( position == m_browsePosition ) { - launchDictBrowser(); + Uri uri = Uri.parse( getString( R.string.dict_url )); + Intent intent = new Intent( Intent.ACTION_VIEW, uri ); + intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK ); + startActivity (intent ); } else { m_gi.dictName = m_dicts[position]; Utils.logf( "assigned dictName: " + m_gi.dictName ); @@ -634,12 +637,6 @@ public class GameConfig extends Activity implements View.OnClickListener { return curSel; } - private void launchDictBrowser() - { - Intent intent = new Intent( this, DictActivity.class ); - startActivity( intent ); - } - private void configConnectSpinner() { m_connectSpinner = (Spinner)findViewById( R.id.connect_spinner ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java index 4d9ef8c1d..a199649e7 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameListAdapter.java @@ -9,6 +9,8 @@ import android.view.ViewGroup; import android.widget.TextView; import android.database.DataSetObserver; import java.io.FileInputStream; +import junit.framework.Assert; + import org.eehouse.android.xw4.jni.*; import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole; @@ -29,20 +31,12 @@ public class GameListAdapter implements ListAdapter { } public int getCount() { - int count = 0; - for ( String file : m_context.fileList() ) { - if ( ! file.endsWith(XWConstants.GAME_EXTN) ) { - ++count; - } - } - - return count; + return Utils.gamesList(m_context).length; } public Object getItem( int position ) { TextView view = new TextView(m_context); - - byte[] stream = open( m_context.fileList()[position] ); + byte[] stream = open( Utils.gamesList(m_context)[position] ); if ( null != stream ) { CurGameInfo gi = new CurGameInfo( m_context ); XwJNI.gi_from_stream( gi, stream ); 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 392143ed2..ec6fae256 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java @@ -106,7 +106,7 @@ public class GamesList extends ListActivity implements View.OnClickListener { return false; } - String path = fileList()[info.position]; + String path = Utils.gamesList( this )[info.position]; int id = item.getItemId(); switch ( id ) { @@ -169,8 +169,7 @@ public class GamesList extends ListActivity implements View.OnClickListener { switch (item.getItemId()) { case R.id.gamel_menu_delete_all: - String[] files = fileList(); - for( String file : files ) { + for( String file : Utils.gamesList( this ) ) { if ( deleteFile( file ) ) { Utils.logf( "deleted " + file ); } else { @@ -212,7 +211,7 @@ public class GamesList extends ListActivity implements View.OnClickListener { } private void doOpen( int indx ) { - String path = fileList()[indx]; + String path = Utils.gamesList(this)[indx]; File file = new File( path ); Uri uri = Uri.fromFile( file ); Intent intent = new Intent( Intent.ACTION_EDIT, uri, diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java index ada526d10..787705ac8 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java @@ -9,6 +9,8 @@ import android.content.Context; import java.io.File; import java.io.FileOutputStream; import java.io.FileInputStream; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.util.ArrayList; import android.content.res.AssetManager; import android.os.Environment; @@ -33,7 +35,6 @@ public class Utils { static final int DIALOG_ABOUT = 1; static final int DIALOG_LAST = DIALOG_ABOUT; - // private static JNIThread s_jniThread = null; private static Time s_time = new Time(); private Utils() {} @@ -132,6 +133,17 @@ public class Utils { XwJNI.game_dispose( gamePtr ); } + public static String[] gamesList( Context context ) + { + ArrayList al = new ArrayList(); + for ( String file : context.fileList() ) { + if ( isGame( file ) ){ + al.add( file ); + } + } + return al.toArray( new String[al.size()] ); + } + public static void resetGame( Context context, String pathIn ) { resetGame( context, pathIn, newName( context ) ); @@ -183,7 +195,7 @@ public class Utils { { saveGame( context, bytes, newName( context ) ); } - + public static String newName( Context context ) { String name = null; @@ -192,7 +204,7 @@ public class Utils { String[] files = context.fileList(); while ( name == null ) { - name = "game " + num.toString(); + name = "game " + num.toString() + XWConstants.GAME_EXTN; for ( ii = 0; ii < files.length; ++ii ) { if ( files[ii].equals(name) ) { ++num; @@ -205,7 +217,7 @@ public class Utils { private static void tryFile( ArrayList al, String name ) { - if ( name.endsWith( ".xwd" ) ) { + if ( isDict( name ) ) { al.add( name ); } } @@ -236,22 +248,14 @@ public class Utils { Utils.logf( ioe.toString() ); } - File files[] = Environment.getExternalStorageDirectory().listFiles(); - for ( File file : files ) { - if ( al.size() >= enough ) { - break; - } - if ( file.isDirectory() ) { // go down one level - tryDir( al, file ); - } else { - tryFile( al, file.getAbsolutePath() ); - } + for ( String file : context.fileList() ) { + tryFile( al, file ); } return al.toArray( new String[al.size()] ); } - public static byte[] openDict( Context context, String name ) + public static byte[] openDict( Context context, final String name ) { byte[] bytes = null; InputStream dict = null; @@ -268,13 +272,13 @@ public class Utils { + len + " bytes." ); } } catch ( java.io.IOException ee ){ - Utils.logf( "failed to open" ); + Utils.logf( "%s failed to open; likely not built-in", name ); } // not an asset? Try storage if ( null == bytes ) { try { - FileInputStream fis = new FileInputStream( new File(name) ); + FileInputStream fis = context.openFileInput( name ); int len = fis.available(); bytes = new byte[len]; fis.read( bytes, 0, len ); @@ -286,10 +290,29 @@ public class Utils { } } - return bytes; } + public static void saveDict( Context context, String name, InputStream in ) + { + int totalRead = 0; + 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 ); + totalRead += nRead; + } + fos.close(); + } catch ( java.io.FileNotFoundException fnf ) { + Utils.logf( "saveDict: FileNotFoundException: %s", fnf.toString() ); + } catch ( java.io.IOException ioe ) { + Utils.logf( "saveDict: IOException: %s", ioe.toString() ); + } + } + public static void setChecked( Activity activity, int id, boolean value ) { CheckBox cbx = (CheckBox)activity.findViewById( id ); @@ -373,4 +396,15 @@ public class Utils { return 0; } } + + private static boolean isGame( String file ) + { + return file.endsWith( XWConstants.GAME_EXTN ); + } + + private static boolean isDict( String file ) + { + return file.endsWith( XWConstants.DICT_EXTN ); + } + } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWConstants.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWConstants.java index 0bf93c2e0..01464cd22 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWConstants.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/XWConstants.java @@ -4,4 +4,5 @@ package org.eehouse.android.xw4; public interface XWConstants { public static final String GAME_EXTN = ".xwg"; + public static final String DICT_EXTN = ".xwd"; }