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