Getting null or empty userid in Sinch - sinch

FATAL EXCEPTION: main
java.lang.IllegalArgumentException: toUserId must not be null or empty
at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.call(DefaultCallClient.java:153)
at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.callUser(DefaultCallClient.java:102)
at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.callUser(DefaultCallClient.java:97)
at packagename.SinchService$SinchServiceInterface.callUser(SinchService.java:91)
at packagename.PlaceCallActivity.callButtonClicked(PlaceCallActivity.java:142)
at packagename.PlaceCallActivity.access$000(PlaceCallActivity.java:26)
at packagename.PlaceCallActivity$1.onClick(PlaceCallActivity.java:173)
at android.view.View.performClick(View.java:4802)
at android.view.View$PerformClick.run(View.java:20101)
at android.os.Handler.handleCallback(Handler.java:810)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:189)
at android.app.ActivityThread.main(ActivityThread.java:5532)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
What could be the possible issues please elaborate tell. I am getting random mobile number from database using json parser request.
private void callButtonClicked() {
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("status",status));
params.add(new BasicNameValuePair("mobile", callNo));
JSONObject json = jsonParser.makeHttpRequest(Config.URL_Random, "POST",
params);
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
response=json.getString(MOBILE);
}
}catch (JSONException e){
e.printStackTrace();
}
String userNo = response;
Log.d("Response is",userNo);
try {
Call call = getSinchServiceInterface().callUser(userNo);
if (call == null) {
// Service failed for some reason, show a Toast and abort
Toast.makeText(this, "Service is not started. Try stopping the service and starting it again before "
+ "placing a call.", Toast.LENGTH_LONG).show();
return;
}
String callId = call.getCallId();
Intent callScreen = new Intent(this, CallScreenActivity.class);
callScreen.putExtra(SinchService.CALL_ID, callId);
startActivity(callScreen);
} catch (MissingPermissionException e) {
ActivityCompat.requestPermissions(this, new String[]{e.getRequiredPermission()}, 0);
}
}
I am storing user mobile number at login screen and callno is the number in Textview of LoggedIn No Ok. This json response response=json.getString(MOBILE); will get any random number from a database. So tell me please where i am doing it wrong and also i guess my php api made by another guy who is storing the number giving random number assured me that everything is absolutely fine from there side.

Try this maybe because your callNo is out of scope of callbuttonclicked
Suppose if you have number in textview then you do this inside callbuttonclicked function:
callNo= userNo.getText().toString();
userNo = (TextView) findViewById(R.id.number); --> do this in onCreate method
hope that would resolve your problem.

seems to me you have empty ot null values in you database, we dont allow emty strong as userid to send to

Related

What is the callback URL after calling repeat.vsp when using Form Integration?

I'm trying to do repeat payments with Form Integration in Sagepay (now Opayo).
From an earlier problem posted on here, I get that the securitykey is needed but is not returned in the Form call, so an additional call needs to be made to the getTransactionDetails command.
I have the securitykey and can now make a call to https://test.sagepay.com/gateway/service/repeat.vsp to initiate the repeat payment. However, the documentation does not say where the response to that call goes. I assume therefore, that it would go to the NotificationURL that is set up with a payment when using the Server or Direct integrations. Since I'm using Form, this is not set.
The question is, is there any way of capturing the response to the https://test.sagepay.com/gateway/service/repeat.vsp call if the initial payment was created using Form integration?
I suppose the second question is, has anybody successfully made repeat payments work with Sagepay Form integration?
Not sure if this helps you and we didn't do repeat payments; but we are looking at releasing deferred payments and I think it is a similar approach.
How do you make the call to 'https://test.sagepay.com/gateway/service/repeat.vsp'?
Could you use a 'HttpWebRequest' to make the call then capture the direct response in 'HttpWebResponse'?
EG:
private static void DeferredSharedApiCall(Dictionary<string, string> data, string type, string url)
{
string postData = string.Join("&", data.Select(x => $"{x.Key}={HttpUtility.UrlEncode(x.Value)}"));
HttpWebRequest request = WebRequest.CreateHttp(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (TextWriter tw = new StreamWriter(request.GetRequestStream()))
{
tw.Write(postData);
}
HttpWebResponse response = null;
try
{
response = request.GetResponse() as HttpWebResponse;
}
catch (WebException ex)
{
//log.Error($"{type} Error, data: {postData}", ex);
}
catch (Exception ex)
{
//log.Error($"{type} Error, data: {postData}", ex);
}
if (response != null)
{
using (TextReader tr = new StreamReader(response.GetResponseStream()))
{
string result = tr.ReadToEnd();
//log.Info($"{type} Response: {Environment.NewLine}{result}");
}
}
}

IntentService in Xamarin PCL Solution

I am busy writing an application where the user needs to capture a lot of images and then they get packaged together with some text data and then they get uploaded to a local server. I want to implement the uploading on the Android platform through an Intent Service but I cannot find a good Xamarin Forms PCL example to show me how.
This is the method where I initialize the Intent to pass to the IntentService:
public async Task<bool> UploadAsync(Uri serviceAddress,
CaptureEntity capture,
List<ImageEntity> images)
{
try
{
Intent uploadIntent = new Intent();
uploadIntent.PutExtra("serviceAddress", serviceAddress.ToString());
uploadIntent.PutExtra("captureId", capture.WorkflowId.ToString());
StartService(uploadIntent);
return true;
}
catch (Exception exc)
{
App.logger.LogError(DateTime.Now, "Uploader", exc.ToString());
throw exc;
}
}
And this is the IntentService itself.
[Service]
public class ServiceIntent : IntentService
{
public ServiceIntent() : base("ServiceIntent")
{
}
//[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
return base.OnStartCommand(intent, flags, startId);
}
public override void OnCreate()
{
base.OnCreate();
}
protected override void OnHandleIntent(Intent intent)
{
Uri serviceAddress = new Uri(intent.GetStringExtra("serviceAddress"));
Guid captureId = Guid.Parse(intent.GetStringExtra("captureId"));
CaptureEntity capture = new DatabaseConnection_Android().CreateConnection().Query<CaptureEntity>("SELECT * FROM [CaptureEntity]").Single(c => c.WorkflowId == captureId);
var images = new DatabaseConnection_Android().CreateConnection().Query<ImageEntity>("SELECT * FROM [ImageEntity]").Where(i => i.CaptureEntityId == capture.Id);
try
{
MultipartFormDataContent content = new MultipartFormDataContent();
StringContent strContent = new StringContent(
capture.XmlData,
Encoding.UTF8,
"text/xml");
IImageHandler handler = new ImageHandler_Droid();
HttpRequestMessage request = new HttpRequestMessage();
request.Headers.Add("workflow", capture.WorkflowId.ToString());
request.Method = HttpMethod.Post;
request.RequestUri = serviceAddress;
foreach (var image in images)
{
byte[] imageByte = handler.ReadAllBytes(image.ImagePath);
ByteArrayContent byteContent = new ByteArrayContent(imageByte);
byteContent.Headers.Add("Content-Type", "image/jpeg");
content.Add(byteContent, "file", image.ImageName);
}
content.Add(strContent, "text/xml");
request.Content = content;
using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(180);
var response = client.SendAsync(
request,
HttpCompletionOption.ResponseContentRead).Result;
var readResponse = response.Content.ReadAsStringAsync().Result;
if (readResponse == "File uploaded.")
MessagingCenter.Send<CaptureEntity, string>(
capture,
"Completed",
"Success");
else if (readResponse.Contains("An error has occurred."))
MessagingCenter.Send<CaptureEntity, string>(
capture,
"Uploader",
String.Format(CultureInfo.InvariantCulture,
"Failed: {0}",
readResponse));
else
MessagingCenter.Send<CaptureEntity, string>(
capture,
"Uploader",
String.Format(CultureInfo.InvariantCulture,
"Failed: {0}",
readResponse));
}
}
catch (WebException webExc)
{
MessagingCenter.Send<string, string>("Uploader", "Failed",
String.Format(CultureInfo.InvariantCulture,
"{0} upload failed.\n{1}",
capture.DisplayName,
webExc.Message));
}
catch (TimeoutException timeExc)
{
MessagingCenter.Send<string, string>("Uploader", "Failed",
String.Format(CultureInfo.InvariantCulture,
"{0} upload failed.\n{1}",
capture.DisplayName,
timeExc.Message));
}
catch (Exception exc)
{
MessagingCenter.Send<string, string>("Uploader", "Failed",
String.Format(CultureInfo.InvariantCulture,
"{0} upload failed.\n{1}",
capture.DisplayName,
exc.Message));
}
}
}
Can anyone tell me what I am doing wrong as I am getting the following error when I want to start the service:
Java.Lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.Context.startService(android.content.Intent)' on a null object reference
In your Intent declaration you need to tell the service you want to call
Something like this:
var uploadIntent = new Intent(this, typeof(ServiceIntent));
Note: this represents the Context.
Update:
As mentioned in the comments your interface implementation cannot derive from Activity class. In order to have access to the Context to be able to call the StartService method and also create your Intent you can make it in two ways:
Using the Xamarin.Forms.Forms.Context:
public async Task<bool> UploadAsync(Uri serviceAddress,
CaptureEntity capture,
List<ImageEntity> images)
{
try
{
var context = Xamarin.Forms.Forms.Context;
var uploadIntent = new Intent(context, typeof(ServiceIntent));
uploadIntent.PutExtra("serviceAddress", serviceAddress.ToString());
uploadIntent.PutExtra("captureId", capture.WorkflowId.ToString());
context.StartService(uploadIntent);
return true;
}
catch (Exception exc)
{
App.logger.LogError(DateTime.Now, "Uploader", exc.ToString());
throw exc;
}
}
If you are using latest versions of Xamarin.Forms this global context was deprecated and they suggest to you local context instead. You can still use it though but in future updates of XF your app might break.
using CurrentActivity plugin:
public async Task<bool> UploadAsync(Uri serviceAddress,
CaptureEntity capture,
List<ImageEntity> images)
{
try
{
var context = CrossCurrentActivity.Current.Activity;
var uploadIntent = new Intent(context, typeof(ServiceIntent));
uploadIntent.PutExtra("serviceAddress", serviceAddress.ToString());
uploadIntent.PutExtra("captureId", capture.WorkflowId.ToString());
context.StartService(uploadIntent);
return true;
}
catch (Exception exc)
{
App.logger.LogError(DateTime.Now, "Uploader", exc.ToString());
throw exc;
}
}
This plugin can be installed from nugget and the setup is very straight forward. Basically it gives you access to the current activity and you can use it as your context to call the IntentService
Hope this helps.-
Here is the IntentService.
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
In Android, we usually use IntentService to do asynchronous operator. As we all know, thread is also used to do asynchronous operator. The difference between IntentService and Thread is IntentService is Service which belongs to Android Component. So, the priority of IntentService is higher than Thread.
For example, there is a ActivityA which has a IntentService, and there is a ActivityB which has a Thread, both IntentService and Thread are working, and both ActivityA and ActivityB are al background Activity. Now, if your phone's system doesn't have extra resources, your ActivityB will be killed firstly.
About the Exception:
Java.Lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.Context.startService(android.content.Intent)' on a null object reference
That means you should use android.content.Context to call the StartService method. In Android, there are three kinds of Context. Application, Activity and Service. So you can call the StartService method in these three classes directly. If you are not in these three classes, you need pass the Context to your class, and then use the Context to call StartService.
I added Activity for this class' inheritance.
If you do this, your class will be a Activity, and you need to register it in your manifiest, add layout for your class, and it should have the lifecycle, and etc. It will not be what you want to get class. In Android, Activity is a Component, not normal class, so you can't inherit it unless you want your class to be a Activity.
Demo:
I have made a demo for you,

Elmah doesn't log exceptions using WebAPI with HttpResponseException

In my WebApi code, I raise a HttpResponseException which short-circuits the request pipeline and generates a valid Http response. However, I'm trying to integrate webApi with elmah logging, yet the HttpResponseExeptions aren't showing up.
I have the web.config set-up for elmah and have the following code:
In Global.asx.cs:
static void ConfigureWebApi(HttpConfiguration config)
{
config.Filters.Add(new ServiceLayerExceptionFilter());
config.Filters.Add(new ElmahHandledErrorLoggerFilter());
config.DependencyResolver = new WebApiDependencyResolver(ObjectFactory.Container);
}
Filter:
public class ElmahHandledErrorLoggerFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
base.OnException(actionExecutedContext);
ErrorSignal.FromCurrentContext().Raise(actionExecutedContext.Exception);
}
}
Code where exception is raised:
public Task<FileUpModel> UploadFile()
{
if (Request.Content.IsMimeMultipartContent())
{
var provider = new TolMobileFormDataStreamProvider("C:\images\");
var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(
t =>
{
if (t.IsFaulted || t.IsCanceled)
throw new HttpResponseException(HttpStatusCode.InternalServerError);
var fileInfo = provider.FileData.FirstOrDefault();
if (fileInfo == null)
// the exception here isn't logged by Elmah?!
throw new HttpResponseException(HttpStatusCode.InternalServerError);
var uploadModel = new FileUpModel { success = true };
return uploadModel;
});
return task;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}
Can anyone who has implemented this before let me know what I'm doing wrong?
As mentioned above, the Elmah filter does not catch and log anything when you raise a HttpResponseException. More specifically, if the following syntax is used:
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "It was a bad request");
or
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "HttpResponseException - This request is not properly formatted"));
I wanted to trap and log an error in both cases. The way to do it is to use an "ActionFilterAttribute", override "OnActionExecuted", and check actionExecutedContext.Response.IsSuccessStatusCode.
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
// when actionExecutedContext.Response is null, the error will be caught and logged by the Elmah filter
if ((actionExecutedContext.Response != null) && !actionExecutedContext.Response.IsSuccessStatusCode)
{
try
{
var messages = (System.Web.Http.HttpError)((System.Net.Http.ObjectContent<System.Web.Http.HttpError>)actionExecutedContext.Response.Content).Value;
StringBuilder stringBuilder = new StringBuilder();
foreach (var keyValuePair in messages) {
stringBuilder.AppendLine("Message: Key - " + keyValuePair.Key + ", Value - " + keyValuePair.Value);
}
Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Web API Failed Status Code returned - " + stringBuilder.ToString()));
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Error in OnActionExecuted - " + ex.ToString()));
}
}
}
On a side note, I also overwrote "OnActionExecuting" to validate the model state. This allowed me to remove all of the checks within my actions.
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext.ModelState != null && !actionContext.ModelState.IsValid)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (var obj in actionContext.ModelState.Values)
{
foreach (var error in obj.Errors)
{
if(!string.IsNullOrEmpty(error.ErrorMessage)) {
stringBuilder.AppendLine("Error: " + error.ErrorMessage);
}
}
}
Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Invalid Model State -- " + stringBuilder.ToString()));
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
Of course, you will need to add the filter using "config.Filters.Add".
Web API special cases HttpResponseException thrown in action and converts into HttpResponseMessage and hence you are not seeing your exception filter getting invoked.
This is not true in the case of throwing HttpResponseException from filters. However, ideally one need not throw HttpResponseException from filters as you could short-circuit a request by setting the Response property on the supplied input context.
You need to turn on Elmah for HttpFilters in order to get this to work as you expect for WebApi.
Use Elmah.Contrib.WebApi available as a NuGet Package, it will wire include a class that you can then wire up following the instructions on the Elmah.Contrib.WebApi project site.
If you want to do this yourself, Capturing Unhandled Exceptions in ASP.NET Web API's with ELMAH walks you through what the Elmah.Contrib.WebApi is doing for you.
Additionally, I had to change the way that the error response is thrown for it to be picked by Elmah to:
throw new HttpException((int)HttpStatusCode.NotAcceptable, "This request is not properly formatted");
I would also recommend the use of the Elmah.MVC NuGet Package.

AWS: Getting 400 Bad Request error from AmazonCloudWatch.GetMetricStatistics()

I'm having a little trouble using AmazonCloudWatch to fetch CPU Utilization. When I try to use AmazonCloudWatch.GetMetricStatistics(), I get this for an exception message:
Exception of type 'Amazon.CloudWatch.AmazonCloudWatchException' was thrown.
And this for an inner exception:
{"The remote server returned an error: (400) Bad Request."}
Here is the code I'm using to make the call:
public static String getCPUStats(String Endpoint, String InstanceID)
{
try
{
AmazonCloudWatchConfig cloudConfig = new AmazonCloudWatchConfig();
cloudConfig.ServiceURL = Endpoint;
string AWSAccessKey = Sql.ToString(appConfig["AWSAccessKey"]);
string AWSSecretKey = Sql.ToString(appConfig["AWSSecretKey"]);
AmazonCloudWatch client = AWSClientFactory.CreateAmazonCloudWatchClient(AWSAccessKey, AWSSecretKey, cloudConfig);
GetMetricStatisticsRequest request = new GetMetricStatisticsRequest();
request.Dimensions.Add(new Dimension { Name = "InstanceId", Value = InstanceID });
request.StartTime = DateTime.UtcNow.AddMinutes(-5);
request.EndTime = DateTime.UtcNow;
request.Namespace = "AWS/EC2";
request.Statistics.Add("Maximum");
request.Statistics.Add("Average");
request.MetricName = "CPUUtilization";
request.Period = 60;
GetMetricStatisticsResponse r = client.GetMetricStatistics(request);
if (r.GetMetricStatisticsResult.Datapoints.Count > 0)
{
Datapoint dataPoint = r.GetMetricStatisticsResult.Datapoints[0];
return "CPU maximum load: " + dataPoint.Maximum;
}
return "No data available.";
}
catch (Exception ex)
{
return ex.Message;
}
}
Some side notes - the access key, secret access key, and endpoint work fine for creating an AmazonEC2Client, so I'm pretty sure the problem isn't there.
I've done quite a bit of googling and poring over the documentation, but haven't been successful in solving this. Any ideas? Thanks so much!
Unfortunately, we weren't able to figure this one out - we ended up deciding to use Microsoft Azure instead of Amazon Web Services :(
I think you can only request one Statistics at a time. So try removing either request.Statistics.Add("Maximum"); or request.Statistics.Add("Average");

OAuthException not catched with C# FacebookSDK

I try to get my code working with catching certain errors. I store the token for a user after he or she grants permission to my app (this is a WP7 app). When I try to post on the wall by using the stored token it works. When I remove the permissions on facebook it throws an OAuthException. I can't catch it it seems. My app just crashes. This is the code I used:
private object PostToFacebook()
{
_fbApp = new FacebookClient(_appsettings.faceBookToken);
FacebookAsyncCallback callback = new FacebookAsyncCallback(this.postResult);
var parameters = new Dictionary<string, object>();
parameters.Add("message", "message on wall");
try
{
_fbApp.PostAsync("me/feed", parameters, callback);
}
catch (Exception ex)
{
}
return null;
}
private void postResult(FacebookAsyncResult asyncResult)
{
if (asyncResult.Error == null)
{
status = "succes";
}
else
{
status = "error" + asyncResult.Error.Message;
}
}
The try catch doesn't catch anything and the generic exception handler in my app.xaml.cs either.
Any ideas how to catch this error so I can ask the user to authenticate again?
Put your try..catch in the callback.
You can also catch exceptions globally by handling the UnhandledException event on the App object.

Resources