Use the downloader with an infinite progress indicator instead of the

status-bar notifier (which is removed) for dict downloads.
This commit is contained in:
Eric House 2012-11-26 20:19:25 -08:00
parent b1f54a67ed
commit 30377908df
6 changed files with 108 additions and 159 deletions

View file

@ -57,7 +57,7 @@ import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
public class BoardActivity extends XWActivity public class BoardActivity extends XWActivity
implements TransportProcs.TPMsgHandler, View.OnClickListener, implements TransportProcs.TPMsgHandler, View.OnClickListener,
NetUtils.DownloadFinishedListener { DictImportActivity.DownloadFinishedListener {
public static final String INTENT_KEY_CHAT = "chat"; public static final String INTENT_KEY_CHAT = "chat";
@ -259,7 +259,8 @@ public class BoardActivity extends XWActivity
if ( DLG_USEDICT == id ) { if ( DLG_USEDICT == id ) {
setGotGameDict( m_getDict ); setGotGameDict( m_getDict );
} else { } else {
NetUtils.downloadDictInBack( BoardActivity.this, DictImportActivity
.downloadDictInBack( BoardActivity.this,
m_gi.dictLang, m_gi.dictLang,
m_getDict, m_getDict,
BoardActivity.this ); BoardActivity.this );
@ -1051,7 +1052,7 @@ public class BoardActivity extends XWActivity
} }
////////////////////////////////////////////////// //////////////////////////////////////////////////
// NetUtils.DownloadFinishedListener interface // DictImportActivity.DownloadFinishedListener interface
////////////////////////////////////////////////// //////////////////////////////////////////////////
public void downloadFinished( final String name, final boolean success ) public void downloadFinished( final String name, final boolean success )
{ {

View file

@ -21,6 +21,7 @@
package org.eehouse.android.xw4; package org.eehouse.android.xw4;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -32,15 +33,36 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.net.URI; import java.net.URI;
import java.util.HashMap;
import junit.framework.Assert; import junit.framework.Assert;
public class DictImportActivity extends XWActivity { public class DictImportActivity extends XWActivity {
// URIs coming in in intents
public static final String APK_EXTRA = "APK"; public static final String APK_EXTRA = "APK";
private static final String DICT_EXTRA = "XWD";
public interface DownloadFinishedListener {
void downloadFinished( String name, boolean success );
}
// Track callbacks for downloads.
private static class ListenerData {
public ListenerData( String dictName, DownloadFinishedListener lstnr )
{
m_dictName = dictName;
m_lstnr = lstnr;
}
public String m_dictName;
public DownloadFinishedListener m_lstnr;
}
private static HashMap<String,ListenerData> s_listeners =
new HashMap<String,ListenerData>();
private class DownloadFilesTask extends AsyncTask<Uri, Integer, Long> { private class DownloadFilesTask extends AsyncTask<Uri, Integer, Long> {
private String m_saved = null; private String m_savedDict = null;
private String m_url = null;
private boolean m_isApp = false; private boolean m_isApp = false;
private File m_appFile = null; private File m_appFile = null;
@ -50,10 +72,16 @@ public class DictImportActivity extends XWActivity {
m_isApp = isApp; m_isApp = isApp;
} }
public DownloadFilesTask( String url, boolean isApp )
{
this( isApp );
m_url = url;
}
@Override @Override
protected Long doInBackground( Uri... uris ) protected Long doInBackground( Uri... uris )
{ {
m_saved = null; m_savedDict = null;
m_appFile = null; m_appFile = null;
int count = uris.length; int count = uris.length;
@ -71,7 +99,7 @@ public class DictImportActivity extends XWActivity {
if ( m_isApp ) { if ( m_isApp ) {
m_appFile = saveToDownloads( is, name ); m_appFile = saveToDownloads( is, name );
} else { } else {
m_saved = saveDict( is, name ); m_savedDict = saveDict( is, name );
} }
is.close(); is.close();
} catch ( java.net.URISyntaxException use ) { } catch ( java.net.URISyntaxException use ) {
@ -89,15 +117,19 @@ public class DictImportActivity extends XWActivity {
protected void onPostExecute( Long result ) protected void onPostExecute( Long result )
{ {
DbgUtils.logf( "onPostExecute passed %d", result ); DbgUtils.logf( "onPostExecute passed %d", result );
if ( null != m_saved ) { if ( null != m_savedDict ) {
DictUtils.DictLoc loc = DictUtils.DictLoc loc =
XWPrefs.getDefaultLoc( DictImportActivity.this ); XWPrefs.getDefaultLoc( DictImportActivity.this );
DictLangCache.inval( DictImportActivity.this, m_saved, DictLangCache.inval( DictImportActivity.this, m_savedDict,
loc, true ); loc, true );
callListener( m_url, true );
} else if ( null != m_appFile ) { } else if ( null != m_appFile ) {
// launch the installer // launch the installer
Intent intent = Utils.makeInstallIntent( m_appFile ); Intent intent = Utils.makeInstallIntent( m_appFile );
startActivity( intent ); startActivity( intent );
} else {
// we failed at something....
callListener( m_url, false );
} }
finish(); finish();
} }
@ -120,9 +152,13 @@ public class DictImportActivity extends XWActivity {
Uri uri = intent.getData(); Uri uri = intent.getData();
if ( null == uri ) { if ( null == uri ) {
String url = intent.getStringExtra( APK_EXTRA ); String url = intent.getStringExtra( APK_EXTRA );
boolean isApp = null != url;
if ( !isApp ) {
url = intent.getStringExtra( DICT_EXTRA );
}
if ( null != url ) { if ( null != url ) {
dft = new DownloadFilesTask( true ); dft = new DownloadFilesTask( url, isApp );
uri = Uri.parse(url); uri = Uri.parse( url );
} }
} else if ( null != intent.getType() } else if ( null != intent.getType()
&& intent.getType().equals( "application/x-xwordsdict" ) ) { && intent.getType().equals( "application/x-xwordsdict" ) ) {
@ -132,7 +168,7 @@ public class DictImportActivity extends XWActivity {
basename( uri.getPath()) ); basename( uri.getPath()) );
TextView view = (TextView)findViewById( R.id.dwnld_message ); TextView view = (TextView)findViewById( R.id.dwnld_message );
view.setText( txt ); view.setText( txt );
dft = new DownloadFilesTask( false ); dft = new DownloadFilesTask( uri.toString(), false );
} }
if ( null == dft ) { if ( null == dft ) {
@ -183,6 +219,49 @@ public class DictImportActivity extends XWActivity {
{ {
return new File(path).getName(); return new File(path).getName();
} }
private static void rememberListener( String url, String name,
DownloadFinishedListener lstnr )
{
ListenerData ld = new ListenerData( name, lstnr );
synchronized( s_listeners ) {
s_listeners.put( url, ld );
}
}
private static void callListener( String url, boolean success )
{
if ( null != url ) {
ListenerData ld;
synchronized( s_listeners ) {
ld = s_listeners.get( url );
if ( null != ld ) {
s_listeners.remove( url );
}
}
if ( null != ld ) {
ld.m_lstnr.downloadFinished( ld.m_dictName, success );
}
}
}
public static void downloadDictInBack( Context context, int lang,
String name,
DownloadFinishedListener lstnr )
{
String url = Utils.makeDictUrl( context, lang, name );
if ( null != lstnr ) {
rememberListener( url, name, lstnr );
}
downloadDictInBack( context, url );
}
public static void downloadDictInBack( Context context, String url )
{
Intent intent = new Intent( context, DictImportActivity.class );
intent.putExtra( DICT_EXTRA, url );
context.startActivity( intent );
}
} }

View file

@ -61,7 +61,7 @@ import org.eehouse.android.xw4.DictUtils.DictLoc;
public class DictsActivity extends ExpandableListActivity public class DictsActivity extends ExpandableListActivity
implements View.OnClickListener, XWListItem.DeleteCallback, implements View.OnClickListener, XWListItem.DeleteCallback,
MountEventReceiver.SDCardNotifiee, DlgDelegate.DlgClickNotify, MountEventReceiver.SDCardNotifiee, DlgDelegate.DlgClickNotify,
NetUtils.DownloadFinishedListener { DictImportActivity.DownloadFinishedListener {
private static final String DICT_DOLAUNCH = "do_launch"; private static final String DICT_DOLAUNCH = "do_launch";
private static final String DICT_LANG_EXTRA = "use_lang"; private static final String DICT_LANG_EXTRA = "use_lang";
@ -339,7 +339,8 @@ public class DictsActivity extends ExpandableListActivity
String name = intent.getStringExtra( MultiService.DICT ); String name = intent.getStringExtra( MultiService.DICT );
m_launchedForMissing = true; m_launchedForMissing = true;
m_handler = new Handler(); m_handler = new Handler();
NetUtils.downloadDictInBack( DictsActivity.this, lang, DictImportActivity
.downloadDictInBack( DictsActivity.this, lang,
name, DictsActivity.this ); name, DictsActivity.this );
} }
}; };
@ -555,10 +556,9 @@ public class DictsActivity extends ExpandableListActivity
{ {
int loci = intent.getIntExtra( UpdateCheckReceiver.NEW_DICT_LOC, 0 ); int loci = intent.getIntExtra( UpdateCheckReceiver.NEW_DICT_LOC, 0 );
if ( 0 < loci ) { if ( 0 < loci ) {
DictLoc loc = DictLoc.values()[loci];
String url = String url =
intent.getStringExtra( UpdateCheckReceiver.NEW_DICT_URL ); intent.getStringExtra( UpdateCheckReceiver.NEW_DICT_URL );
NetUtils.downloadDictInBack( this, url, loc, null ); DictImportActivity.downloadDictInBack( this, url );
finish(); finish();
} }
} }
@ -769,7 +769,7 @@ public class DictsActivity extends ExpandableListActivity
launchAndDownload( activity, 0, null ); launchAndDownload( activity, 0, null );
} }
// NetUtils.DownloadFinishedListener interface // DictImportActivity.DownloadFinishedListener interface
public void downloadFinished( String name, final boolean success ) public void downloadFinished( String name, final boolean success )
{ {
if ( m_launchedForMissing ) { if ( m_launchedForMissing ) {

View file

@ -54,7 +54,7 @@ public class GamesList extends XWListActivity
implements DispatchNotify.HandleRelaysIface, implements DispatchNotify.HandleRelaysIface,
DBUtils.DBChangeListener, DBUtils.DBChangeListener,
GameListAdapter.LoadItemCB, GameListAdapter.LoadItemCB,
NetUtils.DownloadFinishedListener { DictImportActivity.DownloadFinishedListener {
private static final int WARN_NODICT = DlgDelegate.DIALOG_LAST + 1; private static final int WARN_NODICT = DlgDelegate.DIALOG_LAST + 1;
private static final int WARN_NODICT_SUBST = WARN_NODICT + 1; private static final int WARN_NODICT_SUBST = WARN_NODICT + 1;
@ -103,12 +103,13 @@ public class GamesList extends XWListActivity
case WARN_NODICT_SUBST: case WARN_NODICT_SUBST:
lstnr = new DialogInterface.OnClickListener() { lstnr = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) { public void onClick( DialogInterface dlg, int item ) {
// just do one // no name, so user must pick
if ( null == m_missingDictName ) { if ( null == m_missingDictName ) {
DictsActivity.launchAndDownload( GamesList.this, DictsActivity.launchAndDownload( GamesList.this,
m_missingDictLang ); m_missingDictLang );
} else { } else {
NetUtils.downloadDictInBack( GamesList.this, DictImportActivity
.downloadDictInBack( GamesList.this,
m_missingDictLang, m_missingDictLang,
m_missingDictName, m_missingDictName,
GamesList.this ); GamesList.this );
@ -623,7 +624,7 @@ public class GamesList extends XWListActivity
return handled; return handled;
} }
// NetUtils.DownloadFinishedListener interface // DictImportActivity.DownloadFinishedListener interface
public void downloadFinished( String name, final boolean success ) public void downloadFinished( String name, final boolean success )
{ {
post( new Runnable() { post( new Runnable() {

View file

@ -21,17 +21,11 @@
package org.eehouse.android.xw4; package org.eehouse.android.xw4;
import android.content.Context; import android.content.Context;
import android.os.Handler;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -50,10 +44,6 @@ public class NetUtils {
public static byte PRX_GET_MSGS = 4; public static byte PRX_GET_MSGS = 4;
public static byte PRX_PUT_MSGS = 5; public static byte PRX_PUT_MSGS = 5;
public interface DownloadFinishedListener {
void downloadFinished( String name, boolean success );
}
public static Socket makeProxySocket( Context context, public static Socket makeProxySocket( Context context,
int timeoutMillis ) int timeoutMillis )
{ {
@ -273,68 +263,4 @@ public class NetUtils {
DbgUtils.logf( "sendToRelay: null msgs" ); DbgUtils.logf( "sendToRelay: null msgs" );
} }
} // sendToRelay } // sendToRelay
static void downloadDictInBack( Context context, int lang, String name,
DownloadFinishedListener lstnr )
{
DictUtils.DictLoc loc = XWPrefs.getDefaultLoc( context );
downloadDictInBack( context, lang, name, loc, lstnr );
}
static void downloadDictInBack( Context context, int lang, String name,
DictUtils.DictLoc loc,
DownloadFinishedListener lstnr )
{
String url = Utils.makeDictUrl( context, lang, name );
downloadDictInBack( context, url, loc, lstnr );
}
static void downloadDictInBack( final Context context, final String urlStr,
final DictUtils.DictLoc loc,
final DownloadFinishedListener lstnr )
{
String tmp = Utils.dictFromURL( context, urlStr );
final String name = DictUtils.removeDictExtn( tmp );
String msg = context.getString( R.string.downloadingf, name );
final StatusNotifier sno =
new StatusNotifier( context, msg, R.string.download_done );
new Thread( new Runnable() {
public void run() {
boolean success = false;
HttpURLConnection urlConn = null;
try {
URL url = new URL( urlStr );
urlConn = (HttpURLConnection)url.openConnection();
InputStream in = new
BufferedInputStream( urlConn.getInputStream(),
1024*8 );
success = DictUtils.saveDict( context, in,
name, loc );
} catch ( java.net.MalformedURLException mue ) {
DbgUtils.loge( mue );
} catch ( java.io.IOException ioe ) {
DbgUtils.loge( ioe );
} catch ( Exception ce ) {
// E.g. java.net.ConnectException; we failed
// to download, ok.
} finally {
if ( null != urlConn ) {
urlConn.disconnect();
}
}
sno.close();
if ( success ) {
DictLangCache.inval( context, name, loc, true );
}
if ( null != lstnr ) {
lstnr.downloadFinished( name, success );
}
}
} ).start();
}
} }

View file

@ -1,58 +0,0 @@
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
/*
* Copyright 2012 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
public class StatusNotifier {
private int m_id;
private NotificationManager m_mgr;
private Context m_context;
public StatusNotifier( Context context, String msg, int id )
{
m_context = context;
m_id = id;
Notification notification =
new Notification( R.drawable.icon48x48, msg,
System.currentTimeMillis() );
notification.flags = notification.flags |= Notification.FLAG_AUTO_CANCEL;
PendingIntent pi = PendingIntent.getActivity( context, 0,
new Intent(), 0 );
notification.setLatestEventInfo( context, "", "", pi );
m_mgr = (NotificationManager)
context.getSystemService( Context.NOTIFICATION_SERVICE );
m_mgr.notify( id, notification );
}
// Will likely be called from background thread
public void close()
{
m_mgr.cancel( m_id );
}
}