how to set the Activity in titanium when I send message to wechat? - titanium-mobile

I already registered to wechat successfully. and I want to send message to wechat now, but I occured:
[ERROR] E/MicroMsg.SDK.MMessageAct: send fail, target ActivityNotFound
this is my android module(src//.java) code:
#Kroll.method
public void regToWx()
{
Log.d(current_module, "=======start to register to wechat==========");
api = WXAPIFactory.createWXAPI(getActivity(),null);
Log.d(current_module, "=======create api after====="+api);
api.registerApp(APP_ID);
Log.d(current_module, "====注册微信成功======");
}
#Kroll.method
public void sendMessageToWx()
{
Log.d(current_module, "====下面发送消息给微信======");
WXTextObject text_obj = new WXTextObject();
text_obj.text="we are young!!!";
Log.d(current_module, "====构造Media Message======");
WXMediaMessage msg_obj = new WXMediaMessage();
msg_obj.mediaObject = text_obj;
msg_obj.description = "this is desciption";
Log.d(current_module, "====构造 Request======");
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = String.valueOf(System.currentTimeMillis());
req.message = msg_obj;
req.scene = SendMessageToWX.Req.WXSceneTimeline;
Log.d(current_module, "====发送请求给微信了======");
boolean result = api.sendReq(req);
Log.d(current_module, "====result======"+result);
Activity activity = TiApplication.getInstance().getCurrentActivity();
Log.d(current_module, activity.toString());
}
and this my test_app
<activity android:name="com.happysoft.testmodule.TestModuleModule" android:exported="true" android:label="#string/app_name"></activity>

I solved this trouble.
#Kroll.onAppCreate
public static void onAppCreate(TiApplication app)
{
Log.d(LCAT, "inside onAppCreate");
api = WXAPIFactory.createWXAPI(app,APP_ID,true);
api.registerApp(APP_ID);
Log.d(LCAT, "================= register App success=====================");
}

Related

Local notifications not shown

Help me find the error in the code
My MainActivity:
string CHANNEL_ID = "MyChannel";
protected override void OnCreate(Bundle savedInstanceState)
{
....
...
CreateNotificationChannel();
LoadApplication(new App());
}
public void CreateNotification(string SetContentTitle, string SetContentText)
{
var builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.SetContentTitle(SetContentTitle)
.SetContentText(SetContentText)
.SetChannelId(CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.icon);
// Finally, publish the notification:
var notificationManager = NotificationManagerCompat.From(this);
// Get the notification manager:
// NotificationManager notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
// Publish the notification:
int notificationId = 1000;
notificationManager.Notify(notificationId, builder.Build());
}
void CreateNotificationChannel(){
if (Build.VERSION.SdkInt<BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
string name = "MyName";
var description = "desc";
var channel = new NotificationChannel(CHANNEL_ID, name, NotificationImportance.High)
{
Description = description
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
and I have a class in which when I need I start displaying local notifications using the code below
var urlOb = new MainActivity();
urlOb.CreateNotification(titleback, textback);
I think I did everything right, but local notifications are not shown.
You can call the method in other activity
public static MainActivity instance;
In the method onCreate
//...
base.OnCreate(savedInstanceState);
instance = this;
And you can call it in other method
MainActivity.instance.CreateNotification(titleback, textback);

How to use Xamarin.Auth in Xamarin.Forms (Shared Project for iOS and Android)?

I am trying to use Xamarin.Auth for a Facebook signin. It's all set up, but I am missing the last part. The Facebook signin is not my MainActivity, one has to click on a button in order to sign in. I don't know how to start the page for the signin. I have trying to follow this approach, but as my MainActivity isn't the Facebook signin page, it won't work. I have binded (I am following the MVVM pattern) the signin button and have implemented an interface in order to use DependencyService. My problem is when I have to implement the code of the platforms.
This is what I have tried on Android:
class LoginFBImpl : Activity, ILoginFB, IFacebookAuthenticationDelegate
{
public void LoginFB() //the method in the interface
{
var auth = new FacebookAuthenticator(FacebookAuthenticator.ClientId, FacebookAuthenticator.Scope, this);
var authenticator = auth.GetAuthenticator();
var intent = authenticator.GetUI(this);
StartActivity(intent); //Problem occurs here
}
public async void OnAuthenticationCompletedAsync(UserModel token)
{
var facebookService = new FacebookService();
var name = await facebookService.GetNameAsync(token.AccessToken);
var id = await facebookService.GetIdAsync(token.AccessToken);
var picture = await facebookService.GetPictureAsync(token.AccessToken);
}
public void OnAuthenticationCancelled()
{
}
public void OnAuthenticationFailed(string message, Exception exception)
{
}
}
iOS:
public class LoginFBImpl : UIViewController, ILoginFB, IFacebookAuthenticationDelegate
{
public void LoginFB()
{
var auth = new FacebookAuthenticator(FacebookAuthenticator.ClientId, FacebookAuthenticator.Scope, this);
var authenticator = auth.GetAuthenticator();
var viewController = authenticator.GetUI();
PresentViewController(viewController, true, null);
}
public async void OnAuthenticationCompletedAsync(UserModel token)
{
DismissViewController(true, null);
var facebookService = new FacebookService();
var name = await facebookService.GetNameAsync(token.AccessToken);
var id = await facebookService.GetIdAsync(token.AccessToken);
var picture = await facebookService.GetPictureAsync(token.AccessToken);
}
public void OnAuthenticationFailed(string message, Exception exception)
{
DismissViewController(true, null);
var alertController = new UIAlertController
{
Title = message,
Message = exception?.ToString()
};
PresentViewController(alertController, true, null);
}
public void OnAuthenticationCancelled()
{
DismissViewController(true, null);
var alertController = new UIAlertController
{
Title = "Authentication cancelled",
Message = "You didn't complete the authentication process"
};
PresentViewController(alertController, true, null);
}
}
I think it has something to do with the Activity/ViewController, but I don't know how to do it properly. When I run this I get: java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference on Android, and I am expecting something similar on iOS - Haven't tested it yet as I am working on Windows.

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

This is going to be a long post! (grab a cup of coffee/popcorn)
I am using AltBeacon Xamarin sample in my code to show the beacons.
I have come across this example in creating Notifications in Xamarin.
Here there's an Application class where the core logic goes.
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 is a POCO class
NotificationActivity is a basic Activity class.
I perform the HttpClient request and get data. I create a notification and present it on my screen. It goes like this
Now when I tap on the notification, I dont go to the NotificationActivity. I am trying to invoke an activity from an ApplicationClass. Is this the right way to perform such stuff. Kindly provide details.
Thanks.
Edit: Added 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;
}
}
First thing you need to do is to set the your pending intent within the notification builder, it will get your NotificationActivity launching:
var builder =
new NotificationCompat.Builder(this)
.SetContentTitle("receivedNotification.Title")
.SetContentText("receivedNotification.Text")
.SetSmallIcon(Android.Resource.Drawable.IcDialogInfo)
.SetContentIntent(pendingIntent);
The second will be to get your back stack setup, from what you posted I'm not sure what the flow should be as the user will exit the app if they use the back button.
If you want the user to go back to the MainActivity when that press the back button, then you can add a ParentActivity to your NotificationActivity activity attribute, i.e.:
[Activity(Label = "NotificationActivity", ParentActivity = typeof(MainActivity))]
And thus the line:
stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(NotificationActivity)));
Would add the MainActivity to the back stack.

Azure Notification Hub and WP8 Intermitant notifications

This is a fairly long piece of code but I am getting nowhere with this and cannot see any issues, although I am new to using notification hubs. I am trying to register for targeted notifications (the logged on user) using the notification hub in Azure. After the registration, a test notification is sent.
The issue I am having is that sometimes the notification is sent to the device, and sometimes it is not. It mostly isn't but occasionally when I step through the code on the server, i will get the notification on the emulator come through. Once when I deployed the app to my phone the notification came though on the emulator! I cannot discover a pattern.
My Controller class looks like this;
private NotificationHelper hub;
public RegisterController()
{
hub = NotificationHelper.Instance;
}
public async Task<RegistrationDescription> Post([FromBody]JObject registrationCall)
{
var obj = await hub.Post(registrationCall);
return obj;
}
And the helper class (which is used elsewhere so is not directly in the controller) looks like this;
public static NotificationHelper Instance = new NotificationHelper();
public NotificationHubClient Hub { get; set; }
// Create the client in the constructor.
public NotificationHelper()
{
var cn = "<my-cn>";
Hub = NotificationHubClient.CreateClientFromConnectionString(cn, "<my-hub>");
}
public async Task<RegistrationDescription> Post([FromBody] JObject registrationCall)
{
// Get the registration info that we need from the request.
var platform = registrationCall["platform"].ToString();
var installationId = registrationCall["instId"].ToString();
var channelUri = registrationCall["channelUri"] != null
? registrationCall["channelUri"].ToString()
: null;
var deviceToken = registrationCall["deviceToken"] != null
? registrationCall["deviceToken"].ToString()
: null;
var userName = HttpContext.Current.User.Identity.Name;
// Get registrations for the current installation ID.
var regsForInstId = await Hub.GetRegistrationsByTagAsync(installationId, 100);
var updated = false;
var firstRegistration = true;
RegistrationDescription registration = null;
// Check for existing registrations.
foreach (var registrationDescription in regsForInstId)
{
if (firstRegistration)
{
// Update the tags.
registrationDescription.Tags = new HashSet<string>() {installationId, userName};
// We need to handle each platform separately.
switch (platform)
{
case "windows":
var winReg = registrationDescription as MpnsRegistrationDescription;
winReg.ChannelUri = new Uri(channelUri);
registration = await Hub.UpdateRegistrationAsync(winReg);
break;
case "ios":
var iosReg = registrationDescription as AppleRegistrationDescription;
iosReg.DeviceToken = deviceToken;
registration = await Hub.UpdateRegistrationAsync(iosReg);
break;
}
updated = true;
firstRegistration = false;
}
else
{
// We shouldn't have any extra registrations; delete if we do.
await Hub.DeleteRegistrationAsync(registrationDescription);
}
}
// Create a new registration.
if (!updated)
{
switch (platform)
{
case "windows":
registration = await Hub.CreateMpnsNativeRegistrationAsync(channelUri,
new string[] {installationId, userName});
break;
case "ios":
registration = await Hub.CreateAppleNativeRegistrationAsync(deviceToken,
new string[] {installationId, userName});
break;
}
}
// Send out a test notification.
await SendNotification(string.Format("Test notification for {0}", userName), userName);
return registration;
And finally, my SendNotification method is here;
internal async Task SendNotification(string notificationText, string tag)
{
try
{
var toast = PrepareToastPayload("<my-hub>", notificationText);
// Send a notification to the logged-in user on both platforms.
await NotificationHelper.Instance.Hub.SendMpnsNativeNotificationAsync(toast, tag);
//await hubClient.SendAppleNativeNotificationAsync(alert, tag);
}
catch (ArgumentException ex)
{
// This is expected when an APNS registration doesn't exist.
Console.WriteLine(ex.Message);
}
}
I suspect the issue is in my phone client code, which is here and SubscribeToService is called immediately after WebAPI login;
public void SubscribeToService()
{
_channel = HttpNotificationChannel.Find("mychannel");
if (_channel == null)
{
_channel = new HttpNotificationChannel("mychannel");
_channel.Open();
_channel.BindToShellToast();
}
_channel.ChannelUriUpdated += async (o, args) =>
{
var hub = new NotificationHub("<my-hub>", "<my-cn>");
await hub.RegisterNativeAsync(args.ChannelUri.ToString());
await RegisterForMessageNotificationsAsync();
};
}
public async Task RegisterForMessageNotificationsAsync()
{
using (var client = GetNewHttpClient(true))
{
// Get the info that we need to request registration.
var installationId = LocalStorageManager.GetInstallationId(); // a new Guid
var registration = new Dictionary<string, string>()
{
{"platform", "windows"},
{"instId", installationId},
{"channelUri", _channel.ChannelUri.ToString()}
};
var request = new HttpRequestMessage(HttpMethod.Post, new Uri(ApiUrl + "api/Register/RegisterForNotifications"));
request.Content = new StringContent(JsonConvert.SerializeObject(registration), Encoding.UTF8, "application/json");
string message;
try
{
HttpResponseMessage response = await client.SendAsync(request);
message = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
message = ex.Message;
}
_registrationId = message;
}
}
Any help would be greatly appriciated as I have been stuck on this now for days! I know this is a lot of code to paste up here but it is all relevant.
Thanks,
EDIT: The SubscribeToService() method is called when the user logs in and authenticates with the WebAPI. The method is here;
public async Task<User> SendSubmitLogonAsync(LogonObject lo)
{
_logonObject = lo;
using (var client = GetNewHttpClient(false))
{
var logonString = String.Format("grant_type=password&username={0}&password={1}", lo.username, lo.password);
var sc = new StringContent(logonString, Encoding.UTF8);
var response = await client.PostAsync("Token", sc);
if (response.IsSuccessStatusCode)
{
_logonResponse = await response.Content.ReadAsAsync<TokenResponseModel>();
var userInfo = await GetUserInfoAsync();
if (_channel == null)
SubscribeToService();
else
await RegisterForMessageNotificationsAsync();
return userInfo;
}
// ...
}
}
I have solved the issue. There are tons of fairly poorly organised howto's for azure notification hubs and only one of them has this note toward the bottom;
NOTE:
You will not receive the notification when you are still in the app.
To receive a toast notification while the app is active, you must
handle the ShellToastNotificationReceived event.
This is why I was experiencing intermittent results, as i assumed you would still get a notification if you were in the app. And this little note is pretty well hidden.
Have you used proper tag / tag expressions while register/send the message. Also, Where are you storing the id back from the notification hub. It should be used when you update the channel uri (it will expire).
I would suggest to start from scratch.
Ref: http://msdn.microsoft.com/en-us/library/dn530749.aspx

how translate getApplication from java to monodroid?

i got a java project about floating view from web. i try to translate it to monodroid, but i fail, because on function ,i don't know how to write in monodroid .
java code is in http://www.xsmile.net/file/FloatViewDemo.rar
namespace MonoFloatView
{
[Activity(Label = "MonoFloatView", MainLauncher = true, Icon = "#drawable/icon")]
public class MyFloatViewActivity : Activity
{
private IWindowManager wm = null;
private WindowManagerLayoutParams wmParams = null;
private MyFloatView myFV = null;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
createView();
// Create your application here
}
private void createView()
{
//myFV = new MyFloatView(getApplicationContext()); //java
myFV = new MyFloatView(ApplicationContext);
myFV.SetImageResource(Resource.Drawable.Icon);
//wm = (WindowManager)getApplicationContext().getSystemService("window");
//http://stackoverflow.com/questions/13634835/monodroid-screen-dimensions
//i get some tip from url above.
wm = GetSystemService(Activity.WindowService).JavaCast<IWindowManager>();
//i don't know the getApplication, how to write in monodroid?
wmParams = ((MyApplication)getApplication()).getMywmParams();
wmParams.Type = LayoutParams.TYPE_PHONE;
wmParams.Format = PixelFormat.RGBA_8888;
wmParams.Flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_NOT_FOCUSABLE;
wmParams.Gravity = Gravity.LEFT | Gravity.TOP;
wmParams.X = 0;
wmParams.Y = 0;
wmParams.Width = 40;
wmParams.Height = 40;
wm.AddView(myFV, wmParams);
}
public override void onDestroy()
{
base.OnDestroy();
wm.RemoveView(myFV);
}
}
}
If you're in an Activity, you should be able to use:
this.Application

Resources