From 14608d2deb1765db5fc3d573163eb4cf82bd279e Mon Sep 17 00:00:00 2001 From: Andy2 Date: Mon, 12 Sep 2011 18:28:43 -0700 Subject: [PATCH] listen for SD card events via BroadcastReceiver registered in AndroidManifest rather than created programatically: only with this can I get EJECT events to work. Replacement class has static register/unregister methods which DictsActivity uses. --- xwords4/android/XWords4/AndroidManifest.xml | 12 +++ .../eehouse/android/xw4/DictsActivity.java | 29 ++++--- .../android/xw4/MountEventReceiver.java | 77 +++++++++++++++++++ .../eehouse/android/xw4/SDCardWatcher.java | 68 ---------------- 4 files changed, 107 insertions(+), 79 deletions(-) create mode 100644 xwords4/android/XWords4/src/org/eehouse/android/xw4/MountEventReceiver.java delete mode 100644 xwords4/android/XWords4/src/org/eehouse/android/xw4/SDCardWatcher.java diff --git a/xwords4/android/XWords4/AndroidManifest.xml b/xwords4/android/XWords4/AndroidManifest.xml index 656a01d67..9bd890a61 100644 --- a/xwords4/android/XWords4/AndroidManifest.xml +++ b/xwords4/android/XWords4/AndroidManifest.xml @@ -124,6 +124,18 @@ + + + + + + + + + + + + diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsActivity.java index b557af23f..da2e9bad7 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictsActivity.java @@ -27,6 +27,7 @@ import android.app.ListActivity; import android.app.ExpandableListActivity; import android.database.DataSetObserver; import android.os.Bundle; +import android.os.Handler; import android.widget.Button; import android.widget.TextView; import android.widget.AdapterView; @@ -57,7 +58,7 @@ import org.eehouse.android.xw4.jni.CommonPrefs; public class DictsActivity extends ExpandableListActivity implements View.OnClickListener, XWListItem.DeleteCallback, - SDCardWatcher.SDCardNotifiee, DlgDelegate.DlgClickNotify { + MountEventReceiver.SDCardNotifiee, DlgDelegate.DlgClickNotify { private static final String DICT_DOLAUNCH = "do_launch"; private static final String DICT_LANG_EXTRA = "use_lang"; @@ -88,7 +89,6 @@ public class DictsActivity extends ExpandableListActivity private long m_packedPosition; private DictUtils.DictLoc m_moveFromLoc; private DictUtils.DictLoc m_moveToLoc; - private SDCardWatcher m_cardWatcher; private LayoutInflater m_factory; @@ -375,7 +375,8 @@ public class DictsActivity extends ExpandableListActivity protected void onResume() { super.onResume(); - m_cardWatcher = new SDCardWatcher( this, this ); + MountEventReceiver.register( this ); + mkListAdapter(); expandGroups(); } @@ -418,10 +419,9 @@ public class DictsActivity extends ExpandableListActivity } @Override - protected void onPause() { - m_cardWatcher.close(); - m_cardWatcher = null; - super.onPause(); + protected void onStop() { + MountEventReceiver.unregister( this ); + super.onStop(); } public void onClick( View v ) @@ -564,11 +564,18 @@ public class DictsActivity extends ExpandableListActivity DELETE_DICT_ACTION ); } - // SDCardWatcher.SDCardNotifiee interface - public void cardMounted() + // MountEventReceiver.SDCardNotifiee interface + public void cardMounted( boolean nowMounted ) { - mkListAdapter(); - expandGroups(); + Utils.logf( "DictsActivity.cardMounted(%b)", nowMounted ); + // post so other SDCardNotifiee implementations get a chance + // to process first: avoid race conditions + new Handler().post( new Runnable() { + public void run() { + mkListAdapter(); + expandGroups(); + } + } ); } // DlgDelegate.DlgClickNotify interface diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MountEventReceiver.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MountEventReceiver.java new file mode 100644 index 000000000..fb49a8487 --- /dev/null +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MountEventReceiver.java @@ -0,0 +1,77 @@ +/* -*- compile-command: "cd ../../../../../; ant install"; -*- */ +/* + * Copyright 2009-2010 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.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import java.util.HashSet; +import java.util.Iterator; + +public class MountEventReceiver extends BroadcastReceiver { + + public interface SDCardNotifiee { + void cardMounted( boolean nowMounted ); + } + + private static HashSet s_procs = new HashSet(); + + @Override + public void onReceive( Context context, Intent intent ) + { + Utils.logf( "MountEventReceiver.onReceive(%s)", intent.getAction() ); + synchronized( s_procs ) { + do { + if ( s_procs.isEmpty() ) { + break; + } + + boolean mounted; + String action = intent.getAction(); + if ( action.equals( Intent.ACTION_MEDIA_MOUNTED ) ) { + mounted = true; + } else if ( action.equals( Intent.ACTION_MEDIA_EJECT ) ) { + mounted = false; + } else { + break; + } + Iterator iter = s_procs.iterator(); + while ( iter.hasNext() ) { + iter.next().cardMounted( mounted ); + } + } while ( false ); + } + } + + public static void register( SDCardNotifiee proc ) + { + synchronized( s_procs ) { + s_procs.add( proc ); + } + } + + public static void unregister( SDCardNotifiee proc ) + { + synchronized( s_procs ) { + s_procs.remove( proc ); + } + } +} diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SDCardWatcher.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/SDCardWatcher.java deleted file mode 100644 index 1492e9731..000000000 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/SDCardWatcher.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- compile-command: "cd ../../../../../; ant install"; -*- */ -/* - * Copyright 2009-2010 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.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -public class SDCardWatcher { - public interface SDCardNotifiee { - void cardMounted(); - } - - private UmountReceiver m_rcvr; - private Context m_context; - private SDCardNotifiee m_notifiee; - - private class UmountReceiver extends BroadcastReceiver { - @Override - public void onReceive( Context context, Intent intent ) - { - if ( intent.getAction(). - equals( Intent.ACTION_MEDIA_MOUNTED ) ) { - m_notifiee.cardMounted(); - } - } - } - - public SDCardWatcher( Context context, SDCardNotifiee notifiee ) - { - m_context = context; - m_rcvr = new UmountReceiver(); - m_notifiee = notifiee; - - IntentFilter filter = - new IntentFilter( Intent.ACTION_MEDIA_MOUNTED ); - // filter.addAction( Intent.ACTION_MEDIA_UNMOUNTED ); - // filter.addAction( Intent.ACTION_MEDIA_EJECT ); - filter.addDataScheme( "file" ); - - /*Intent intent = */context.getApplicationContext(). - registerReceiver( m_rcvr, filter ); - } - - public void close() - { - m_context.getApplicationContext().unregisterReceiver( m_rcvr ); - } -}