Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
117 views
in Technique[技术] by (71.8m points)

Android: associating an app with a file extension causes a new copy to start

I have arranged for my app to start when a file with the correct extension is chosen in a file manager. I have this in my manifest:

        <intent-filter>
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="file" />
            <data android:scheme="content" />
            <data android:host="*" />
            <data android:mimeType="application/vnd.google-earth.kmz" />
        </intent-filter>

and in OnCreate() I call this method, to tell the app what to do with the chosen file:

private void associateFile()
{
    Intent intent = getIntent();
    if (intent.getAction().equals(Intent.ACTION_MAIN))
    {
        // this is a normal start, not a file manager start
       return;
    }
    Uri uri = intent.getData();
    if (uri == null)
    {
        return;
    }
    String filePath = FileLoader.LoadFile(this, uri);
    processFile(filePath);
}

and it all works fine....until I use the file manager method to start when the app is already running. This causes another copy to start, giving disastrous results with background tasks.

So how to I catch the fact that the app is already running, and just gracefully exit the second attempt at opening, with perhaps an appropriate message to the user? I have tried

    ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.AppTask> taskInfo = am.getAppTasks();

to see if the app is already running, but the count of taskInfo is always one, not two as I would expect for the second attempt at opening.

question from:https://stackoverflow.com/questions/65869444/android-associating-an-app-with-a-file-extension-causes-a-new-copy-to-start

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

After a much experimentation I have arrived at the following, using a new 'ParentActivity' to control what happens:

public class ParentActivity extends AppCompatActivity
{
Intent parentIntent;

@Override
protected void onCreate(Bundle savedInstanceState)
{

    String filePath = null;
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_parent);
    parentIntent = getIntent();
    if (parentIntent.getAction() == null)
    {
        finish();
        return;
    }
    Uri uri = parentIntent.getData();
    if (uri != null)
        filePath = FileLoader.LoadFile(this, uri);

    // find out if MainActivity is already running
    ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.AppTask> tasks = am.getAppTasks();
    for (ActivityManager.AppTask task : tasks) {
        String strTask = String.valueOf(task.getTaskInfo().baseActivity);
        if (strTask.contains("MainActivity") && filePath != null)
        {
            // MainActivity already running while file manager used to select another file
            // tell MainActivity what file to deal with
            Intent fileIntent = new Intent("openFile");
            fileIntent.putExtra("openFile", filePath);
            LocalBroadcastManager.getInstance(this).sendBroadcast(fileIntent);
            finish();
            return;
        }
    }
    // we need to start a new MainActivity
    Intent mainIntent = new Intent(this, MainActivity.class);
    if (filePath != null)
    {
        //new start from file (chosen from file manager)
        mainIntent.putExtra("startWithFile",filePath);
    }
    startActivity (mainIntent);
    finish();
  }
}

I still don't understand why it works. In the loop checking the tasks, there is only ever one task found. So in the case of the app being started 'normally' (not from a file manager) the task info relates to ParentActivity, as expected. When the app is already running and the file manager used used to start a new instance, I would expect to see two tasks in this list: ParentActivity (for the new one) and MainActivity for the existing one. But there's only one task, MainActivity. What's happened to ParentActivity in the task list?

@CommonsWare, apologies if I haven't used the correct terminology in this analysis. I hope you (and others) get the gist.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...