mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-04 20:46:28 +01:00
fix, I think, problems with launch mode and non-main activities.
singleTop is necessary, as with singleTask we get the whole actvity stack nuked on every launch. Open a game into BoardActivity then background Crosswords; when you re-launch from the launcher or hold the home key you're back to GamesList. But with singleTop incoming invite schemes would launch a second instance because though there was one running it wasn't in the same task as the browser firing the url to redir.php. The solution there is to move the scheme intent from GamesList to DispatchNotify, which is already handling notifications. There the addition of a second launch flag means that an existing instance will always see the launch through its onNewIntent -- under tests I've come up with so far, anyway.
This commit is contained in:
parent
ea205ebf97
commit
cd15a9e6e3
3 changed files with 104 additions and 73 deletions
|
@ -41,19 +41,12 @@
|
|||
|
||||
<activity android:name="GamesList"
|
||||
android:label="@string/title_games_list"
|
||||
android:launchMode="singleTask"
|
||||
android:launchMode="singleTop"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.intent.action.EDIT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="newxwgame"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="DictsActivity"
|
||||
|
@ -92,7 +85,16 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity android:name="DispatchNotify" />
|
||||
<activity android:name="DispatchNotify"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.intent.action.EDIT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="newxwgame"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- downloading dicts -->
|
||||
<activity android:name=".DictImportActivity"
|
||||
|
|
|
@ -21,13 +21,14 @@
|
|||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.Context;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.widget.Toast;
|
||||
import android.os.Bundle;
|
||||
import java.util.HashSet;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.jni.CommonPrefs;
|
||||
|
||||
|
@ -37,6 +38,7 @@ public class DispatchNotify extends Activity {
|
|||
|
||||
public interface HandleRelaysIface {
|
||||
void HandleRelaysIDs( final String[] relayIDs );
|
||||
void HandleInvite( final Uri invite );
|
||||
}
|
||||
|
||||
private static HashSet<Activity> s_running = new HashSet<Activity>();
|
||||
|
@ -45,29 +47,40 @@ public class DispatchNotify extends Activity {
|
|||
@Override
|
||||
protected void onCreate( Bundle savedInstanceState )
|
||||
{
|
||||
Utils.logf( "DispatchNotify.onCreate()" );
|
||||
boolean mustLaunch = false;
|
||||
super.onCreate( savedInstanceState );
|
||||
|
||||
Intent intent = getIntent();
|
||||
String[] relayIDs = intent.getStringArrayExtra( RELAYIDS_EXTRA );
|
||||
String[] relayIDs = getIntent().getStringArrayExtra( RELAYIDS_EXTRA );
|
||||
Uri data = getIntent().getData();
|
||||
|
||||
if ( !tryHandle( this, relayIDs ) ) {
|
||||
if ( null != relayIDs ) {
|
||||
if ( !tryHandle( relayIDs ) ) {
|
||||
mustLaunch = true;
|
||||
}
|
||||
} else if ( null != data ) {
|
||||
if ( !tryHandle( data ) ) {
|
||||
mustLaunch = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mustLaunch ) {
|
||||
Utils.logf( "DispatchNotify: nothing running" );
|
||||
intent = new Intent( this, GamesList.class );
|
||||
intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );
|
||||
intent.putExtra( RELAYIDS_EXTRA, relayIDs );
|
||||
Intent intent = new Intent( this, GamesList.class );
|
||||
intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
| Intent.FLAG_ACTIVITY_NEW_TASK );
|
||||
if ( null != relayIDs ) {
|
||||
intent.putExtra( RELAYIDS_EXTRA, relayIDs );
|
||||
} else if ( null != data ) {
|
||||
intent.setData( data );
|
||||
} else {
|
||||
Assert.fail();
|
||||
}
|
||||
startActivity( intent );
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent( Intent intent )
|
||||
{
|
||||
Utils.logf( "DispatchNotify.onNewIntent() called" );
|
||||
}
|
||||
|
||||
public static void SetRunning( Activity running )
|
||||
{
|
||||
s_running.add( running );
|
||||
|
@ -83,13 +96,31 @@ public class DispatchNotify extends Activity {
|
|||
s_handler = iface;
|
||||
}
|
||||
|
||||
public static boolean tryHandle( Context context, String[] relayIDs )
|
||||
private static boolean tryHandle( Uri data )
|
||||
{
|
||||
boolean handled = false;
|
||||
if ( null != s_handler ) {
|
||||
// This means the GamesList activity is frontmost
|
||||
s_handler.HandleInvite( data );
|
||||
handled = true;
|
||||
} else {
|
||||
for ( Activity activity : s_running ) {
|
||||
if ( activity instanceof DispatchNotify.HandleRelaysIface ) {
|
||||
DispatchNotify.HandleRelaysIface iface =
|
||||
(DispatchNotify.HandleRelaysIface)activity;
|
||||
iface.HandleInvite( data );
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
public static boolean tryHandle( String[] relayIDs )
|
||||
{
|
||||
Utils.logf( "tryHandle()" );
|
||||
boolean handled = false;
|
||||
if ( null != s_handler ) {
|
||||
// This means the GamesList activity is frontmost
|
||||
Utils.logf( "calling m_handler" );
|
||||
s_handler.HandleRelaysIDs( relayIDs );
|
||||
handled = true;
|
||||
} else {
|
||||
|
@ -102,7 +133,6 @@ public class DispatchNotify extends Activity {
|
|||
}
|
||||
}
|
||||
}
|
||||
Utils.logf( "DispatchNotify.tryHandle()=>%s", handled?"true":"false" );
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,7 +230,6 @@ public class GamesList extends XWListActivity
|
|||
|
||||
Intent intent = getIntent();
|
||||
startFirstHasDict( intent );
|
||||
startNewNetGameIf( intent );
|
||||
askDefaultNameIf();
|
||||
|
||||
DBUtils.setDBChangeListener( this );
|
||||
|
@ -245,7 +244,7 @@ public class GamesList extends XWListActivity
|
|||
invalRelayIDs( intent.
|
||||
getStringArrayExtra( DispatchNotify.RELAYIDS_EXTRA ) );
|
||||
startFirstHasDict( intent );
|
||||
startNewNetGameIf( intent );
|
||||
startNewNetGame( intent );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -302,6 +301,19 @@ public class GamesList extends XWListActivity
|
|||
} );
|
||||
}
|
||||
|
||||
public void HandleInvite( final Uri invite )
|
||||
{
|
||||
final NetLaunchInfo nli = new NetLaunchInfo( invite );
|
||||
if ( nli.isValid() ) {
|
||||
m_handler.post( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startNewNetGame( nli );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
// DBUtils.DBChangeListener interface
|
||||
public void pathSaved( final String path )
|
||||
{
|
||||
|
@ -582,53 +594,40 @@ public class GamesList extends XWListActivity
|
|||
startActivity( new Intent( this, NewGameActivity.class ) );
|
||||
}
|
||||
|
||||
private void startNewNetGameIf( Intent intent )
|
||||
private void startNewNetGame( final NetLaunchInfo info )
|
||||
{
|
||||
if ( null != intent ) {
|
||||
Uri data = intent.getData();
|
||||
if ( null != data ) {
|
||||
String path = DBUtils.getPathForOpen( this, info.room, info.lang,
|
||||
info.nPlayers );
|
||||
|
||||
NetLaunchInfo info = new NetLaunchInfo( data );
|
||||
if ( info.isValid() ) {
|
||||
|
||||
// Find out if the game already exists. If it does,
|
||||
// just open it. Otherwise create a new one and open
|
||||
// that. NOTE: this test makes it impossible to start
|
||||
// two halves of the same game on one device using
|
||||
// this feature. But it'd be worse to have a bunch of
|
||||
// games stacking up when somebody taps the same URL
|
||||
// multiple times.
|
||||
|
||||
// No. If the game already exists, warn the user, but
|
||||
// give him choice to open new or existing game.
|
||||
|
||||
String path =
|
||||
DBUtils.getPathForOpen( this, info.room, info.lang,
|
||||
info.nPlayers );
|
||||
|
||||
if ( null == path ) {
|
||||
path = GameUtils.makeNewNetGame( this, info );
|
||||
GameUtils.launchGame( this, path, true );
|
||||
} else {
|
||||
final NetLaunchInfo finfo = info;
|
||||
DialogInterface.OnClickListener then =
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlg,
|
||||
int ii ) {
|
||||
String path = GameUtils.
|
||||
makeNewNetGame( GamesList.this, finfo );
|
||||
GameUtils.launchGame( GamesList.this,
|
||||
path, true );
|
||||
}
|
||||
};
|
||||
String fmt = getString( R.string.dup_game_queryf );
|
||||
String msg = String.format( fmt, finfo.room );
|
||||
showConfirmThen( msg, then );
|
||||
if ( null == path ) {
|
||||
path = GameUtils.makeNewNetGame( this, info );
|
||||
GameUtils.launchGame( this, path, true );
|
||||
} else {
|
||||
DialogInterface.OnClickListener then =
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dlg,
|
||||
int ii ) {
|
||||
String path = GameUtils.
|
||||
makeNewNetGame( GamesList.this, info );
|
||||
GameUtils.launchGame( GamesList.this,
|
||||
path, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
String fmt = getString( R.string.dup_game_queryf );
|
||||
String msg = String.format( fmt, info.room );
|
||||
showConfirmThen( msg, then );
|
||||
}
|
||||
} // startNewNetGameIf
|
||||
} // startNewNetGame
|
||||
|
||||
private void startNewNetGame( Intent intent )
|
||||
{
|
||||
Uri data = intent.getData();
|
||||
Assert.assertNotNull( intent );
|
||||
NetLaunchInfo info = new NetLaunchInfo( data );
|
||||
if ( info.isValid() ) {
|
||||
startNewNetGame( info );
|
||||
}
|
||||
} // startNewNetGame
|
||||
|
||||
private void askDefaultNameIf()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue