Xamarin.android 通知 onClick 不会带到新的 activity

Xamarin.android Notification onClick doesn't take to new activity

这会很长post! (来一杯coffee/popcorn)

我在我的代码中使用 AltBeacon Xamarin 示例来显示信标。

我遇到了 this 在 Xamarin 中创建通知的示例。

这是核心逻辑所在的应用程序 class。

public class AltBeaconSampleApplication : Application, IBootstrapNotifier
{
    private const string TAG = "AltBeaconSampleApplication";

    BeaconManager _beaconManager;

    private RegionBootstrap regionBootstrap;
    private Region _backgroundRegion;
    private BackgroundPowerSaver backgroundPowerSaver;
    private bool haveDetectedBeaconsSinceBoot = false;

    private string nearbyMessageString = "A beacon is nearby.";
    private string nearbyTitleString = "AltBeacon Reference Application";

    private MainActivity mainActivity = null;
    public MainActivity MainActivity
    {
        get { return mainActivity; }
        set { mainActivity = value; }
    }

    private NotificationActivity notificationActivity = null;

    public NotificationActivity NotificationActivity
    {
        get { return notificationActivity; }
        set { notificationActivity = value; }
    }

    public AltBeaconSampleApplication() : base() { }
    public AltBeaconSampleApplication(IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) : base(javaReference, transfer) { }


    public override void OnCreate()
    {
        base.OnCreate();

        _beaconManager = BeaconManager.GetInstanceForApplication(this);

        var iBeaconParser = new BeaconParser();
        //  Estimote > 2013
        iBeaconParser.SetBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
        _beaconManager.BeaconParsers.Add(iBeaconParser);

        Log.Debug(TAG, "setting up background monitoring for beacons and power saving");
        // wake up the app when a beacon is seen
        _backgroundRegion = new Region("backgroundRegion", null, null, null);
        regionBootstrap = new RegionBootstrap(this, _backgroundRegion);

        // simply constructing this class and holding a reference to it in your custom Application
        // class will automatically cause the BeaconLibrary to save battery whenever the application
        // is not visible.  This reduces bluetooth power usage by about 60%
        backgroundPowerSaver = new BackgroundPowerSaver(this);

        PerformHttpRequest();
    }

    public void DidDetermineStateForRegion(int state, AltBeaconOrg.BoundBeacon.Region region)
    {
    }

    public async void PerformHttpRequest()
    {
        try
        {
            using (var client = new HttpClient())
            {
                var uri = "http://exampleuri";
                var result = await client.GetStringAsync(uri);
                var response = JsonConvert.DeserializeObject<BeaconURL>(result);
                SendNotificationFromBeacon(response);

            }
        }
        catch(Exception ex)
        {
            throw ex;
        }            
    }

    private void SendNotificationFromBeacon(BeaconURL receivedNotification)
    {
        // Setup an intent for SecondActivity:
        Intent notificationIntent = new Intent(this, typeof(NotificationActivity));

        // Pass some information to SecondActivity:
        notificationIntent.PutExtra("CompaignUrl", receivedNotification.CompaignUrl);
        notificationIntent.PutExtra("MediaUrl", receivedNotification.MediaUrl);
        notificationIntent.PutExtra("titleText", receivedNotification.Title);
        notificationIntent.SetFlags(ActivityFlags.NewTask);

        // Create a task stack builder to manage the back stack:
        Android.App.TaskStackBuilder stackBuilder = Android.App.TaskStackBuilder.Create(this);

        // Add all parents of SecondActivity to the stack: 
        stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(NotificationActivity)));

        // Push the intent that starts SecondActivity onto the stack:
        stackBuilder.AddNextIntent(notificationIntent);

        // Obtain the PendingIntent for launching the task constructed by
        // stackbuilder. The pending intent can be used only once (one shot):
        const int pendingIntentId = 0;
        PendingIntent pendingIntent =
            stackBuilder.GetPendingIntent(pendingIntentId, PendingIntentFlags.OneShot);

        // Instantiate the builder and set notification elements, including 
        // the pending intent:
        var builder =
            new NotificationCompat.Builder(this)
                .SetContentTitle(receivedNotification.Title)
                .SetContentText(receivedNotification.Text)
                .SetSmallIcon(Android.Resource.Drawable.IcDialogInfo);

        // Build the notification:
        Notification notification = builder.Build();

        // Get the notification manager:
        NotificationManager notificationManager =
            GetSystemService(Context.NotificationService) as NotificationManager;

        // Publish the notification:
        const int notificationId = 0;
        notificationManager.Notify(notificationId, notification);
    }
}

BeaconURL 是一个 POCO class 通知Activity是基本的Activityclass.

我执行HttpClient 请求并获取数据。我创建一个通知并将其显示在我的屏幕上。它是这样的

现在当我点击通知时,我不会转到通知Activity。我正在尝试从 ApplicationClass 调用 activity。这是执行此类操作的正确方法吗?请提供详细信息。

谢谢。

编辑:添加通知Activity Class

[Activity(Label = "NotificationActivity")]
public class NotificationActivity : MainActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Create your application here
        SetContentView(Resource.Layout.NotificationLayout);

        TextView titleTextView = FindViewById<TextView>(Resource.Id.txtTitle);
        titleTextView.Text = Intent.Extras.GetString("titleText", "");

        ImageView mediaImage = FindViewById<ImageView>(Resource.Id.imgViewMedia);
        mediaImage.SetImageBitmap(GetImageBitmapFromUrl(Intent.Extras.GetString("MediaUrl", "")));
    }

    private Bitmap GetImageBitmapFromUrl(string url)
    {
        Bitmap imageBitmap = null;

        using (var webClient = new WebClient())
        {
            var imageBytes = webClient.DownloadData(url);
            if (imageBytes != null && imageBytes.Length > 0)
            {
                imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
            }
        }

        return imageBitmap;
    }
}

您需要做的第一件事是在通知生成器中设置您的待定意图,它会让您的 NotificationActivity 启动:

var builder =
    new NotificationCompat.Builder(this)
        .SetContentTitle("receivedNotification.Title")
        .SetContentText("receivedNotification.Text")
        .SetSmallIcon(Android.Resource.Drawable.IcDialogInfo)
        .SetContentIntent(pendingIntent);

第二个是获取您的返回堆栈设置,根据您发布的内容,我不确定流程应该是什么,因为如果用户使用后退按钮,他们将退出应用程序。

如果您希望用户在按下后退按钮时返回到 MainActivity,则可以将 ParentActivity 添加到 NotificationActivity activity 属性, 即:

[Activity(Label = "NotificationActivity", ParentActivity = typeof(MainActivity))]

因此这一行:

stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(NotificationActivity)));

会将 MainActivity 添加到返回堆栈。