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"; }