How can I get Android and iPhone IMEI number using Xamarin.forms - xamarin

I am developing an Xamarin.forms application, I need to catch the imei number of mobile that is using the application. I am aware of how it is done in Android. But how can I do the same in Xamarin.forms. Please educate me.

There is no 'Forms-way' of doing this. If you know how on Android you can make use of the DependencyService. Which means in your shared project create an interface like:
public interface IImeiService
{
string GetImei();
}
Now in your Android project implement this interface, so it would be something like:
public class ImeiService : IImeiService
{
public string GetImei()
{
// ... Implement your Android code here
}
}
Register your Android code with an attribute on the class above the namespace
[assembly: Xamarin.Forms.Dependency (typeof (ImeiService))]
namespace ImeiApp.Droid {
You can now access it, back in your shared code, with:
var imei = DependencyService.Get<IImeiService>().GetImei();
If you would have an iOS implementation you could repeat the same steps, although you can, of course, use the same interface and call in shared code, so you will only need a iOS specific implementation.
However, since iOS 7 Apple disallows access to this kind of information programmatically, so you cannot get the IMEI number. And if you can, you will use code that will not be allowed through the App Store review process.

Related

How to import Activity of NfcFCardEmulation.EnableService from Xamarin common project, not Android project?

I'm developing an app using Xamarin's HCE feature.
The project structure is as follows.
hceSample
hceSample.Android
hceSample.iOS
I am implementing hce simulation code called hceService in hceSample, not hceSample.Android.
A function called Enable_Card exists in the hce service, and you want to use the NfcFCardEmulation.EnableService function in that function.
Activity and ComponentName are requested as parameters of the function.
The ComponentName area was handled easily, but I don't know how to get the Activity. Please advise.
This is the contents of enable_Card function of hceService.
private Activity activity = null;
private bool enable_Card(cardModel card)
{
try
{
sid = card.cardSN;
tag = "Felica";
emulation.EnableService(, componentName); //<- How to get Activity??
emulation.SetNfcid2ForService(componentName, sid);
return true;
}
catch
{
return false;
}
}
This is my first time asking a question on Stackoverflow.
I would appreciate it if you could point out any missing or incorrect parts.
I trying this
activity = Xamarin.Essentials.Platform.CurrentActivity; //<- this function is not found!
Added missing information!
The namespace of the Enable_Card function is located in hceSample.Service.
Are you using the NfcFCardEmulation.EnableService(Activity, ComponentName) Method, right?
The method is an android api from android sdk,you cannot use it directly in xamarin.form(yours is hceSample) project.
If you want to call the function in xamarin form project(hceSample) from native platform(hceSample.Android, or hceSample.iOS),you can use Xamarin.Forms DependencyService to achieve this.
The DependencyService class is a service locator that enables Xamarin.Forms applications to invoke native platform functionality from shared code.
For more information about DependencyService, you can check document Xamarin.Forms DependencyService. And there is a sample included in above document,which is helpful for you to understand DependencyService.
Note:
We recognize that hardware service is the right and ideal way to
implement in each OS project. However, I'm curious if there is a way
to code Android and iOS at the same time
Since the api you used is from android sdk, you can call it in native android or use DependencyService to call it on xamarin.form(yours is hceSample) project.
If you call it on xamarin.form(yours is hceSample) project, you also need to find the the corresponding function or interface in iOS.

When using Appcenter, can I still call VersionTracking inside the App constructor?

The application I am working with uses AppCenter with code like this:
public App()
{
InitializeComponent();
VersionTracking.Track();
VersionChecks();
VersionChecks();
DB.CreateTables();
DB.GetSettings();
DB.PopulateTables();
SetDeviceInfo();
SetResourceColors();
SetResourceDimensions();
MainPage = new AppShell();
}
protected override void OnStart()
{
AppCenter.Start("xx", typeof(Crashes), typeof(Push));
Analytics.TrackEvent(VersionTracking.CurrentVersion);
}
Although I don't see any error messages when it starts up I am concerned about the way this is coded as from what I can see the App constructor fires first followed by the OnStart().
So if this happens, how can VersionTracking work. Should that code not be in the OnStart and how about the additional code that I have which sets up the application?
Would appreciate any advice that people can offer about the use of AppCenter with Xamarin forms.
Answer
Yes, you can use Xamarin.Essentials.VersionTracking in the constructor of App.
Explanation
You are confusing three different SDKs: Xamarin.Essentials, Xamarin.Forms and AppCenter.
VersionTracking is an API in Xamarin.Essentials.
App is a subclass of the Xamarin.Forms.Application API.
AppCenter.Start is an API in the AppCenter
These are three independent SDKs and each can be used independently of the others.
Xamarin.Forms app startup flow is like : Native App Startup -> Xamarin.Forms.Application Startup
Your App class is instantiated only after Native app has finished loading.
As versioning is managed by native app, there is no problem in initialising VersionTracking in constructor, as Native app has fully loaded by this time.

How to connect DJI product using DJI mobile sdk

I have been trying almost all samples in dji github (either android or ios) but couldn't connect my dji product (phantom 4 pro+ V2.0) to my app. I can successfully register my app by using my api key, but when I connect dji product to the phone with usb cable I cannot see any connection. Give me a help please.
For iOS App: You need to add the external UISupportedExternalAccessoryProtocols keys to your plist file. Like this
`
<key>UISupportedExternalAccessoryProtocols</key>
<array>
<string>com.dji.video</string>
<string>com.dji.protocol</string>
<string>com.dji.common</string>
</array>
And then use the DJIAssistantSimulator to simulate to the drone location.
The first step in connecting your drone to your application is by calling DJISDKManager.registerApp and pass an instance of DJISDKManagerDelegate.
class ProductPublisher : NSObject, ObservableObject {
...
func registerWithSDK() {
...
DJISDKManager.registerApp(with: self)
}
...
}
The important part is your delegate implements some required methods and calling DJISDKManager.startConnectionToProduct().
extension ProductPublisher : DJISDKManagerDelegate {
func appRegisteredWithError(_ error: Error?) {
// set breakpoint here
DJISDKManager.startConnectionToProduct()
}
func productConnected(_ product: DJIBaseProduct?) {
// set breakpoint here, this marks a successful connection
}
}
The class ProductPublisher is a class of my own where I encapsulate all logic regarding registration and connection. It is part of a tutorial series for iOS I am writing. What I have just explained is in part 2.

Xamarin Forms - How to open specific page after clicking on notification when the app is closed?

I'm actually working on a Xamarin Forms application that need push notifications. I use the Plugin.PushNotification plugin.
When the app is running in the foreground or is sleeping (OnSleep), I have no problem to open a specific page when I click on a notification that I receive. But I was wondering how can I do that when the app is closed. Thanks!
I finally found the answer by myself and I want to share it in case someone needs it.
Nota bene: according to the official documentation of the plugin, it's Xam.Plugin.PushNotification that is deprecated. I use the new version of this plugin, Plugin.PushNotification which uses FCM for Android and APS for iOS.
There is no significant differences to open a notif when the app is running, is sleeping or is closed. Just add the next callback method in the OnCreate method (MyProject.Droid > MainApplication > OnCreate) and FinishedLaunching method (MyProject.iOS > AppDelegate > FinishedLaunching):
CrossPushNotification.Current.OnNotificationOpened += (s, p) =>
{
// manage your notification here with p.Data
App.NotifManager.ManageNotif(p.Data);
};
Common part
App.xaml.cs
// Static fields
// *************************************
public static NotifManager NotifManager;
// Constructor
// *************************************
public App()
{
...
NotifManager = new NotifManager();
...
}
NotifManager.cs
public class NotifManager
{
// Methods
// *************************************
public void ManageNotif(IDictionary<string, object> data)
{
// 1) switch between the different data[key] you have in your project and parse the data you need
// 2) pass data to the view with a MessagingCenter or an event
}
}
Unfortunately there is no succinct answer for either platform. Generally speaking, you need to tell the OS what to do when it starts the app as a result of the push notification. On both platforms, you should also consider what API level you are targeting, otherwise it won't work or even crash the app.
On iOS, you will need to implement this method in AppDelegate appropriately: FinishedLaunching(UIApplication application, NSDictionary launchOptions). The launchOptions will have the payload from the push notification for you to determine what to do with it (e.g. what page to open). For more information on iOS, Xamarin's documentation is a good place to start.
Android has a more complicated topology in terms of more drastic differences between API levels, whether you are using GCM/FCM, as well as requiring more code components. However, to answer the question directly, you will need to handle this in OnCreate(Bundle savedInstanceState) of your main Activity. If you are using Firebase, the push notification payload is available in Intent.Extras. Again, Xamarin's documentation has a good walkthrough.
Finally, note that the Plugin.PushNotification library you are using has been deprecated. I suggest you either change your library and/or your implementation soon. Part of the reason that library has been deprecated is because Google has deprecated the underlying Google Cloud Messaging (GCM) service, which will be decommissioned on April 11, 2019.

Xamarin - Using Portable Class Libraries a mandatory way to go?

Recently I am requested to setup the design for a new app, which needs to be build using Xamarin. The team already created a DEMO app for Android, iOS and Windows Phone. So basically this demo version needs to be transformed/refactored into a proper maintainable product.
When looking into the code what currently is implemented in the DEMO app, I found out that some third party libraries are used which are not available as PCL. This means that I cannot build up my app using PCL's unless I can port this third party library into a PCL.
My findings are:
The functionality we use from this third party library works fine on all 3 platforms
I cannot find any blocking reason why I should not use normal Class Libraries
Questions:
Are there any blocking reasons why I cannot make use of normal Class Libraries?
Will the public apps stores accept these apps or is this not an issue at all?
If not.. Can you give recommendations where especially take care of going with normal Class Library's
If there are.. How can I port third party Libraries to PCL or is there any other way to work around?
First: public app stores don't care about the internals of your app, as long as it follows their guidelines. And that's something Xamarin takes care of, so everything that is dropping out of the compiler will be okay.
Second: You're totally fine with not using PCL if that fits your needs in a better way. In addition to PCL you could also make use of Shared Projects or just linking files from common library projects into each platform-specific project.
But from my personal experience PCL are a good way to make sure the code you're writing and the tools you're using are really working on every platform, so you don't have to be afraid of bad surprises afterwards. And with the PCL profile 78 support of stuff like LINQ etc. is pretty good.
What you can do in addition, is to use a facade inside your shared PCL code, that hides away the concrete implementation, that is then provided for each platform individually.
That could look like:
(PCL)
public interface ILogger
{
void Log(string message);
}
public static class SharedUtilities
{
public static ILogger Logger { get; private set; }
public static void SetUp(ILogger logger)
{
Logger = logger;
}
}
// Now Use it from everywhere in your code:
SharedUtilities.Logger.Log("Hello PCL!");
In your iOS app, for example:
public class IOSLogger : ILogger
{
public void Log(string message)
{
// Make use of a native logging library or whatever you want
}
}
// AppDelegate:
SharedUtilities.SetUp(new IOSLogger());

Resources