How do you send message using NFC with Xamarin.Android? - xamarin.android

I am developing and app to demostrate how NFC works. My goal is to make and app that will work very similary to Android Beam. I am using Xamarin.Android. The goal is to type message to one device, press button and it should be send to another device with the same app where it should be shown. I have tried almost everything even the documentation but it seems like it doesnt work. Does anyone have any experience with this technology? Is this technology even available nowadays?
There is some of my code to get you an idea about what i am trying to do:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
mNfcAdapter = NfcAdapter.GetDefaultAdapter(this);
myButton.Click += (e, o) => {
mNfcAdapter.SetNdefPushMessageCallback(this, this);
mNfcAdapter.SetOnNdefPushCompleteCallback(this, this);
};
}
public NdefMessage CreateNdefMessage(NfcEvent e)
{
DateTime time = DateTime.Now;
var text = (time.ToString("HH:mm:ss") + message2);
NdefMessage msg = new NdefMessage(
new NdefRecord[] { CreateMimeRecord (
text, Encoding.UTF8.GetBytes (text))});
return msg;
}
private NdefRecord CreateMimeRecord(string mimeType, byte[] payload)
{
byte[] mimeBytes = Encoding.UTF8.GetBytes(mimeType);
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TnfMimeMedia, mimeBytes, new byte[0], payload);
return mimeRecord;
}
public void OnNdefPushComplete(NfcEvent e)
{
Toast.MakeText(this.ApplicationContext, "Message sent", ToastLength.Long).Show();
}
protected override void OnResume()
{
base.OnResume();
if (NfcAdapter.ActionNdefDiscovered == Intent.Action)
{
ProcessIntent(Intent);
}
}
protected override void OnNewIntent(Intent intent)
{
Intent = intent;
}
void ProcessIntent(Intent intent)
{
IParcelable[] rawMsgs = intent.GetParcelableArrayExtra(
NfcAdapter.ExtraNdefMessages);
NdefMessage msg = (NdefMessage)rawMsgs[0];
var textViewMsg = FindViewById<TextView>(Resource.Id.textViewMsg);
textViewMsg.Text = Encoding.UTF8.GetString(msg.GetRecords()[0].GetPayload());
}
Thank you all :)

OnNdefPushComplete and the whole Android Beam was deprecated and removed from Android 10
https://developer.android.com/reference/android/nfc/NfcAdapter.OnNdefPushCompleteCallback
If you want to do Device to Device NFC going forward then it should be possible with one phone doing Host Card Emulation (HCE) and the other using enableReaderMode
But Google recommend using Bluetooth or Wifi Direct as a more reliable replacement for Android Beam. One of the replacement methods Google provided was Android Nearby https://developers.google.com/nearby

Related

Auto OTP verification android xamarin

I am working on an Android App using Xamarin, in which server sends an OTP and the user needs to enter this OTP in the App, to SignUp for my App. What I want is, that my App should be able to automatically read the OTP sent by the server and to be filled in edit text field of OTP.
I'm almost done to read the message but unable to set the otp in edit text field.
SMS broadcast receiver class:
[BroadcastReceiver(Enabled = true, Label = "SMS Receiver")]
[IntentFilter(new string[] { "android.provider.Telephony.SMS_RECEIVED" })]
public class SMSBroadcastReceiver : BroadcastReceiver
{
private const string IntentAction = "android.provider.Telephony.SMS_RECEIVED";
public override void OnReceive(Context context, Intent intent)
{
try
{
if (intent.Action != IntentAction) return;
var bundle = intent.Extras;
if (bundle == null) return;
var pdus = bundle.Get("pdus");
// var castedPdus = JNIEnv.GetArray(pdus.Handle);
var castedPdus = JNIEnv.GetArray<Java.Lang.Object>(pdus.Handle);
var msgs = new SmsMessage[castedPdus.Length];
var sb = new StringBuilder();
string sender = null;
for (var i = 0; i < msgs.Length; i++)
{
var bytes = new byte[JNIEnv.GetArrayLength(castedPdus[i].Handle)];
JNIEnv.CopyArray(castedPdus[i].Handle, bytes);
string format = bundle.GetString("format");
msgs[i] = SmsMessage.CreateFromPdu(bytes,format);
if (sender == null)
sender = msgs[i].OriginatingAddress;
sb.Append(string.Format("SMS From: {0}{1}Body: {2}{1}", msgs[i].OriginatingAddress,System.Environment.NewLine, msgs[i].MessageBody));
Toast.MakeText(context, sb.ToString(), ToastLength.Long).Show();
}
}
catch (System.Exception ex)
{
Toast.MakeText(context, ex.Message, ToastLength.Long).Show();
}
}
}
Here is my main activity:
[Activity(Label = "UserSms", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
SMSBroadcastReceiver smsReceiver = new SMSBroadcastReceiver();
TextView msg = FindViewById<TextView>(Resource.Id.editTextOtp);
Button btn = FindViewById<Button>(Resource.Id.button3);
RegisterReceiver(smsReceiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
}
}
How can I achieve this? Any help or guidance in this regard would be highly appreciated.
Update
public void onSMSReceived(string msgs)
{
EditText OtpNumber = (EditText)FindViewById(Resource.Id.editTextOtp);
try
{
OtpNumber.SetText(msgs.ToString(),null);
}
catch (System.Exception ex)
{
}
}
Your are on the finishing line. You only need to do these thing:
Create an interface which will have public method onSMSReceived(String smsMsg)
Instantiate that interface.
Implement that interface in MainActivity activity.
Override onSMSReceived(String smsMsg) in your MainActivity
Notify MainActivity using above created interface from your SMS Broadcast Receiver.
Populate message received in onSMSReceived(String smsMsg) in your MainActivity.
You are done.
I didn't get exactly how you're doing it, but i did in two ways,
1.User has to enter it manually,
2.We have to read automatically through the programming,
But i faced one problem in reading sms automatically, like sending sms and reading sms are calling at the same time may be like register click event, I found one more way to detect automatically like sending otps two times and storing generated otps in a list of string and comparing with message.body
Here the problem is we have to send otp two times, still i'm figuring out how to call reading sms part after sometime,,,!
If you want that solution plz mail me at sailokeshgoud#gmail.com

Xamarin In App Billing Component Not Connecting To Google Play

I have went through the Xamarin IAB 'tutorial' on it's Component page. I installed the component and Google Play Billing Lib into my app, published my apk to Google Play Dev Console in Alpha and added products on the Dev Console to the app. However, when I try to test the app on a phone, anytime I click on any of the purchase buttons nothing happens. The buttons themselves worked fine I have tested them by pushing other notifications, changing colors, etc. They work with everything else, but when it comes to purchasing nothing happens, no pop-ups, no buffering or attempt to connection, literally nothing. I think my app never connects to Google Play, and I have no idea why.
My Main Activity
private InAppBillingServiceConnection _serviceConnection;
private string publicKey = "my public key";
private IList<Product> _products;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Establish Connection to Google Play Store
_serviceConnection = new InAppBillingServiceConnection(this, publicKey);
_serviceConnection.OnConnected += async () =>
{
// Load available products and any purchases
await RequestProducts();
};
// Attempt to connect to the service
_serviceConnection.Connect();
IAPHelper.Instance.Initalize(_products, _serviceConnection);
var g = new Game1();
SetContentView(g.Services.GetService<View>());
g.Run();
}
// Request a list of available products that the user can purchase by providing alist of
protected async Task RequestProducts()
{
_products = await _serviceConnection.BillingHandler.QueryInventoryAsync(new List<string>{
ReservedTestProductIDs.Purchased,
ReservedTestProductIDs.Canceled,
ReservedTestProductIDs.Refunded,
ReservedTestProductIDs.Unavailable
}, ItemType.Product);
// Were any products returned?
if (_products == null)
{
// No, abort
return;
}
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
My Helper Method
private IList<Product> _products;
private InAppBillingServiceConnection _serviceConnection;
public void Initalize(IList<Product> _products, InAppBillingServiceConnection _serviceConnection)
{
this._products = _products;
this._serviceConnection = _serviceConnection;
}
// Called when a product is clicked to buy
public bool ProductPurchasing(string id)
{
Product _selectedProduct = null;
try
{
for (int i = 0; i < _products.Count; i++)
{
if (id == _products[i].ProductId)
{
_selectedProduct = _products[i];
break;
}
}
_serviceConnection.BillingHandler.BuyProduct(_selectedProduct);
return true;
}
catch (Exception ex)
{
return false;
}
}

LWUIT ConnectionRequest: Bad Request on Blackberry

My lwuit application is working fine on Blackberry Simulator while on device the application installs successfully, starts normally, but where am having issues is on network connection. Trying to access network I get 400 Bad Request message. I don't no what am doing wrong, my network connection code is as below:
public ConnectionRequest prepareConnection(String page, String progressMsg, final int request)
{
final ConnectionRequest conR = new ConnectionRequest()
{
public void readResponse(InputStream input) throws IOException {
StringBuffer sb = new StringBuffer();
int ch;
while((ch=input.read()) != -1)
sb.append((char)ch);
httpResponse(sb.toString().trim(), request);
}
};
conR.setUrl(NetworkHandler.getURL()+page);
conR.setDuplicateSupported(true);
Progress progress = new Progress(progressMsg, conR)
{
public void actionCommand(Command command)
{
if(command.getCommandName().equals("Cancel"))
conR.kill();
}
};
conR.setDisposeOnCompletion(progress);
return conR;
}
private void login(String code)
{
Container container = Display.getInstance().getCurrent();
if(!validateLogin(container))
{
showDialogMessage("Alert", "Please enter your user name and password!");
return;
}
NetworkManager.getInstance().start();
ConnectionRequest conR = prepareConnection(NetworkHandler.LOGIN_PAGE, "Authenticating...", RequestType.LOGIN);
Dialog dialog = conR.getDisposeOnCompletion();
conR.setPost(true);
conR.addArgument("u", getFieldValue(findTxtUserName(container)));
conR.addArgument("p", getFieldValue(findTxtPassword(container)));
conR.addArgument("c", code);
NetworkManager.getInstance().addToQueue(conR);
dialog.show();
}
public void onLoginForm_BtnLoginAction(Component c, ActionEvent event) {
login("");
}
Please I want you guys to help me out.
Thanks in Advance.
The login me
This usually indicates a problem in APN configuration on the device. Normally Blackberry app's workaround incorrect APN configurations automatically which is a pretty difficult thing to do. CodenameOne does that seamlessly but LWUIT does not.

How can I get FilePicker working properly on certain BlackBerry handsets?

I'm implementing a Filepicker in my app to allow users to choose photos from their phones. The code I'm using is as follows:
Calling the Filepicker:
try
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
FilePicker fp = FilePicker.getInstance();
fileListener = new FilePickListener();
fp.setListener(fileListener);
fp.show();
}
});
}
catch (Exception e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Please check your data card..");
}
});
}
And the method to get the filename in my FilePickListener:
public void selectionDone(String str)
{
this.currFileName = str;
int index = str.lastIndexOf('/');
Dialog.alert("Filename: "+str.substring(index+1).trim());
}
This works perfectly in most handsets that I've tried it on (which have been a mix of handsets with some running OS5 and some running OS6). But on some, like the 8900 (running OS v5.0.0.411) it doesn't work properly. The Filepicker gets called and appears, but when any file gets selected, the selectionDone method doesn't get called. I've tested it on two separate 8900s and both have the same problem.
Does anyone have an idea why it works on certain handsets and not other?
You are a victim of a known RIM issue: FilePicker throws ControlledAccessException.
The issue is marked as "Fixed". However there is no info in which OS version they fixed it. (Is it so difficult to tell such a useful info?)
But from the comments to the issue:
We experience the very same issue with OS 5.0.0.321 on a Bold 9700. However, the issue does NOT appear on OS 5.0.0.464
so my guess would be they fixed it in OS 5.0.0.464. But that's not the end - in OS 6 FilePicker appears broken in early versions of OS 6 again. The conclusion - just don't use it. Use a custom file browser screen to pick a file. There is a sample in SDK 4.7.0 named FileExplorerDemo, check it for implementation details.
This is a known issue. FilePicker does not open on some devices and return an error, like the 8900 device. You can catch this error on some devices by adding the catch (Error e) { }
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
FilePicker fp = FilePicker.getInstance();
fileListener = new FilePickListener();
fp.setListener(fileListener);
fp.show();
}
});
}
catch (Exception e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Please check your data card..");
}
});
}
catch (Error e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("This device does not support File Picker");
}
});
}

Twitter Follow Link

How do I create a link that will automatically make a user follow a certain Twitter user if they're logged in or send them to Twitter to login first if they're not? I had found how to do this about month or 2 ago but can't find it again. I think it was something basic like a link or a form post to something like twitter.com/[user]/follow.
I've looked at the API, but I'd need the user to authenticate themselves on my site, and I don't want to deal with that. I just want them to authenticate directly on Twitter and not worry about it. The way I had found was nice and simple and I just want to find that again.
Use Twitter's web intents.
While you can use the follow button, you can also send users directly to the Intent URL, like so:
https://twitter.com/intent/user?screen_name=NASA
how to use twitter api in my android application to implement follow button only
Android
http://code.google.com/p/android-hackathon-in-fukuoka/source/browse/trunk/sodefuri/src/jp/jagfukuoka/sodefuri/TimeLineActivity.java?spec=svn167&r=167
Code Snip: (I have converted chines string into standard English)
public class TimeLineActivity extends ListActivity {
private TwitterPreferenceManager tpm = new TwitterPreferenceManager(this);
private static final int FOLLOW = 1;
private static final CharSequence FOLLOW_LABEL = "Follow";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// timeline Obtaining process
String screenName = getIntent().getStringExtra("screen_name");
List<String> list = this.getTimeLine(screenName);
setListAdapter(new ArrayAdapter<String>(this, R.layout.timeline_item,list));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, FOLLOW, 0, FOLLOW_LABEL);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case FOLLOW:
ConfigurationBuilder builder = new ConfigurationBuilder();
Configuration conf = builder.setOAuthAccessToken(tpm.getAccessToken())
.setOAuthAccessTokenSecret(tpm.getAccessTokenSercret())
.setOAuthConsumerKey(TwitterPreferenceManager.CONSUMER_KEY)
.setOAuthConsumerSecret(TwitterPreferenceManager.CONSUMER_SERCRET)
.setDebugEnabled(true)
.build();
Twitter twitter = new TwitterFactory(conf).getInstance();
try {
String screen_name = getIntent().getStringExtra("screen_name");
twitter.createFriendship(screen_name);
Toast.makeText(getApplicationContext(), "Was to follow.", Toast.LENGTH_LONG).show();
} catch (TwitterException e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
/**
* Get the time line for the specified user
*
* #param screenName
* #return
*/
private List<String> getTimeLine(String screenName) {
List<String> result = new ArrayList<String>();
Twitter twitter = new TwitterFactory().getInstance();
ResponseList<Status> userTimeline;
try {
userTimeline = twitter.getUserTimeline(screenName);
for (Status status : userTimeline) {
result.add(status.getText());
}
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}
iPhone
http://www.chrismaddern.com/twitter-follow-button-for-ios-iphone-code/
Here is the way, How todo
The FollowMeButton can be created in Interface Builder by adding a UIButton and changing it's class to FollowMeButton or in code using the custom initialiser:
[self.view addSubview:[[FollowMeButton alloc] initWithTwitterAccount:#"chrismaddern" atOrigin:CGPointMake(205, 248) isSmallButton:YES]];
Two size modes are available controlled by setting isSmallButton in the initialiser or by later change the isSmall property of the object.

Resources