2

这将是一个很长的文章! (抢一杯咖啡/爆米花)Xamarin.android通知onClick不采取新的活动

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

我碰到过在Xamarin中创建通知的示例。

这里有一个应用程序类,其中的核心逻辑去。

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); 
    } 
} 

BeaconURLPOCONotificationActivity是一个基本活动类。

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

现在,当我点击通知,我不去NotificationActivity。我试图从ApplicationClass调用一个活动。这是执行这种事情的正确方法。请提供详细信息。

谢谢。

编辑:新增NotificationActivity类

[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; 
    } 
} 
+0

您的'NotificationActivity'活动中的Activity属性中是否设置了'ParentActivity'名称(或者如果您在'Activity'属性中手动分配'Name',则清单中的正确条目?) – SushiHangover

+0

NotificationActivity类是Activity的子类,我添加了相同类的代码。你能否好好研究它@SushiHangover。谢谢 – Xander

+0

我在谈论该类的[Activity(....)]'属性,而不是类本身。 – SushiHangover

回答

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添加到后退堆栈。

+0

这个缺失的部分 SetContentIntent(pendingIntent)取得了诀窍。真棒! – Xander