Xamarin.android通知onClick不会进入新活动

时间:2017-08-22 03:30:15

标签: xamarin xamarin.android xamarin.forms android-notifications altbeacon

这将是一个很长的帖子! (拿一杯咖啡/爆米花)

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

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

这里有一个核心逻辑所在的Application类。

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 NotificationActivity 是一个基本的活动类。

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

现在,当我点击通知时,我不会去NotificationActivity。我试图从ApplicationClass调用一个活动。这是执行此类操作的正确方法吗?请提供详细信息。

感谢。

修改:添加了NotificationActivity 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;
    }
}

1 个答案:

答案 0 :(得分:1)

您需要做的第一件事是在通知构建器中设置待处理意图,它将启动NotificationActivity启动:

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

第二个是从你发布的内容中获取你的后台堆栈我不知道流程应该是什么,因为如果用户使用后退按钮,用户将退出应用程序。

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

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

因此行:

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

MainActivity添加到后台堆栈。