I want my app to be a viewer and send target for PDFs but don't want it to create new instances everytime. How do I catch the view intent action in my MainActivity? I tried OnNewIntent() but it doesn't get called. Only if the app wasn't already running, I get the action in OnCreate(). What am I missing?
[Activity (Theme = "@style/MainTheme", Label = "MyPdfViewer", Icon = "@drawable/icon", /*MainLauncher = true, --> SplashActivity is now the MainLauncher */LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
[IntentFilter(new[] { Intent.ActionSend }, Categories = new[] { Intent.CategoryDefault }, DataMimeType = @"application/pdf")]
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataMimeType = @"application/pdf")]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
LoadApplication (new App ());
// handle clipboard data "send to" or "view document" actions
if (Intent.Type == "application/pdf")
{
HandleSendOrViewAction();
}
}
protected virtual void OnNewIntent()
{
var data = this.Intent.Data; // <-- never called
// do similar thing like in HandleSendOrViewAction()
}
private bool HandleSendOrViewAction()
{
// Get the info from ClipData
var pdf = Intent.ClipData.GetItemAt(0);
// Open a stream from the URI
byte[] bytes;
Stream inputStream;
if (Intent.Action == Intent.ActionSend)
inputStream = ContentResolver.OpenInputStream(pdf.Uri);
else if (Intent.Action == Intent.ActionView)
inputStream = ContentResolver.OpenInputStream(Intent.Data);
else
return false;
using (StreamReader sr = new StreamReader(inputStream))
{
MemoryStream ms = new MemoryStream();
inputStream.CopyTo(ms);
bytes = ms.ToArray();
}
Services.PdfReceiver.Base64Data = Convert.ToBase64String(bytes);
return true;
}
The
standardandsingleTopof Launch Mode would create multiple instances. if you do not want create instance every time, you could usesingleTaskandsingleInstanceinstead.For
singleTopLaunch Mode, you need to know, if an instance of the activity already exists at the top of the target task, the system routes the intent to that instance through a call to itsonNewIntent()method, rather than creating a new instance of the activity. If the instance of the activity which already exists is not at the top, it would not callonNewIntent()method.That's why i suggest to use
singleTask. The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one.