RedLaserSDK.java from MonoDroid - xamarin.android

I'm trying to use RedLaserSDK.java from MonoDroid.
I've included redlasersdk.jar as AndroidJavaLibrary
I've included RedLaserSDK.java as AndroidJavaSource
I've included layout/video_view.axml
I've included drawable/overlay_logo.png
I've included raw/beep.ogg
My MainActivity looks something like this:
[Activity (Label = "MainActivity", MainLauncher = true)]
public class MainActivity : TabActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
TabHost tabHost = TabHost;
// Tab for Scan
TabHost.TabSpec scanspec = tabHost.NewTabSpec("Scan");
scanspec.SetIndicator("", Resources.GetDrawable(Resource.Drawable.icon_scan_tab));
Intent scanIntent = new Intent(this, Java.Lang.Class.ForName("com.ebay.rlsample.RedLaserSDK"));
scanspec.SetContent(scanIntent);
tabHost.AddTab(scanspec); // Exception occurs here....
}
}
But I get an ActivityNotFound exception: Unable to explicitly find class 'MyApp/MyApp.com.ebay.rlsample.RedLaserSDK'
Any thoughts on what I might have wrong?

All I was missing was:
<activity android:name="com.ebay.rlsample.RedLaserSDK" android:label="RedLaserSDK"/>

Related

xamarin.android webview evaluatejavascript It does not return any value at all

I have a fundamental problem that I can not really understand where the problem comes from.
I am designing a project by xamarin.android webview.
Now I need to run a Java function in Web View and check the return value in a if function.
I searched all the websites and in all of them I got the following code:
In Main Activity Class:
public class MainActivity : AppCompatActivity
{
WebView web_view;
.
.
.
Define web_view public in class
In OnCreate :
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_main);
web_view = FindViewById<WebView>(Resource.Id.webview);
web_view.Settings.JavaScriptEnabled = true;
web_view.Settings.BuiltInZoomControls = true;
web_view.Settings.AllowContentAccess = true;
web_view.SetWebViewClient(new HelloWebViewClient());
web_view.LoadUrl("https://www.example.com");
}
In Back Key Press:
public override bool OnKeyDown(Android.Views.Keycode keyCode, Android.Views.KeyEvent e)
{
if (keyCode == Keycode.Back)
{
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
{
JavascriptResult jsr = new JavascriptResult();
string strjs = "closePackageDetails();";
web_view.EvaluateJavascript(strjs, jsr);
string rrr = jsr.strResult;
Toast.MakeText(this, "message send:" + rrr, ToastLength.Long).Show();
}
else
{
Toast.MakeText(this, "android version less 4.4" , ToastLength.Long).Show();
}
}
}
On JavascriptResult Class (separate on C# Class Palaced in MainActivity in Root directory)
namespace webviewapp
{
class JavascriptResult : Java.Lang.Object, IValueCallback
{
public string strResult;
public void OnReceiveValue(Java.Lang.Object result)
{
Toast.MakeText(Android.App.Application.Context, "رسیدن نتیجه احضار شد", ToastLength.Long);
strResult = ((Java.Lang.String)result).ToString();
}
}
}
<>
Everything looks right and the program is debugged without error and the APK file is created successfully.
After installing the program on the mobile phone and running it, the web page is loaded and everything looks good.
By touching the back button, the JavaScript function is executed correctly and the result is visible in Web View. But the result, which is a boolean value, is not returned.
In fact, the OnReceiveValue procedure does not work.
The variable 'rrr' always displays an null value.
Where it went wrong really puzzled me?
It is happening because the callback is executed later than the next line ,so the variable 'rrr' is always null.
Add the breakpoint at OnReceiveValue and the line string rrr = jsr.strResult; to check it .
Just do the next thing directly in the method OnReceiveValue in the callback class.

Start an Android activity in Xamarin Forms?

I am trying to view a hosted PDF file with the default Android pdf viewer in my App with the following code
var intent = new Intent(Intent.ActionView);
intent.SetDataAndType(Uri.Parse("http://sample/url.pdf"), "application/pdf");
intent.SetFlags(ActivityFlags.ClearTop);
Android.Content.Context.StartActivity(intent);
I have used this code in a Native project, so I know that it works within an Android activity. For Xamarin Forms, is there a way for me to start an Android activity from a content page, and vice versa?
You can use DependencyService to implement this function:
INativePages in PCL:
public interface INativePages
{
void StartActivityInAndroid();
}
Implement the interface in Xamarin.Android:
[assembly: Xamarin.Forms.Dependency(typeof(NativePages))]
namespace PivotView.Droid
{
public class NativePages : INativePages
{
public NativePages()
{
}
public void StartAc()
{
var intent = new Intent(Forms.Context, typeof(YourActivity));
Forms.Context.StartActivity(intent);
}
}
}
Start an Android Activity in PCL :
private void Button_Clicked(object sender, EventArgs e)
{
Xamarin.Forms.DependencyService.Register<INativePages>();
DependencyService.Get<INativePages>().StartAc();
}
Forms.Context is obsolete now.
The workaround is to instantiate the current context in Main activity class of Android project as under:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static Xamarin.Forms.Platform.Android.FormsAppCompatActivity Instance { get; private set; }
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
Instance = this;
}
And retrieve the local context in your NativePages StartAc() method as under:
public void StartAc()
{
var intent = new Intent(MainActivity.Instance, typeof(YourActivity));
MainActivity.Instance.StartActivity(intent);
}
Create an class for this function in an android project:
public class PdfLauncher : IPdfLauncher
{
public void LaunchPdf(string url)
{
//implementation
}
}
Create an interface in a portable project
public interface IPdfLauncher
{
void LaunchPdf(string url);
}
Add a property to your viewmodel so you can call the function from your portable project
public IPdfLauncher PdfLauncher {get;set;}
Add the interface to your viewmodel constructor and pass in an instance that you create in your android main activity. You can now call android code from your xforms commands and, if you ever add iOS or UWP you can simply implement that interface in those projects and pass them in at runtime. I use an injection framework from MVVM to automate creating these platform specific implementations, and I'd recommend you look into it if you find yourself doing these often.

Can replace Vaadin layout component inside Panel?

Am using Vaadin 7.3.10.
I have added a layout component inside a panel in order that
the layouts shall be scrolled if required.
However when I try to replace the layout component, the new
component adds to (is shown below) rather than replaces the
existing component - see below for code sample.
How/Can this be done?
n.b. if the layout is not contained inside the panel, the
replacement occurs correctly.
Also, I do not require to use the Navigator for this.
Thank you,
Steve...
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Button.ClickEvent;
public class NewComponent extends VerticalLayout {
private VerticalLayout mainLayout = new VerticalLayout();
private Panel panel = new Panel();
public NewComponent() {
mainLayout.addComponent(new Label("Main"));
mainLayout.setSizeFull();
addComponent(mainLayout);
panel.setWidth("1000px");
panel.setHeight("500px");
panel.setContent(mainLayout);
Button button = new Button("Click Me");
button.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
replaceComponent(mainLayout, new Label("what's wrong?"));
}
});
mainLayout.addComponent(button);
addComponent(panel);
}
}
public class TestUI extends UI {
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = TestUI.class)
public static class Servlet extends VaadinServlet {
}
#Override
protected void init(VaadinRequest request) {
setContent(new NewComponent());
}
You have to call replaceComponent on the mainLayout and not with.
right now it looks like this:
<newComponent>
<panel>
<mainLayout>
<labelMain/>
<clickMeButton/>
</mainLayout>
</panel>
</newComponent>
then you call replaceComponent on newComponent, which will add the label like this
<newComponent>
<panel>
<mainLayout>
<labelMain/>
<clickMeButton/>
</mainLayout>
</panel>
<whatsWrongLabel/>
</newComponent>
It should look like this:
<newComponent>
<panel>
<mainLayout>
<labelMain/>
</mainLayout>
</panel>
<clickMeButton/>
</newComponent>
and then mainLayout.replaceComponent(labelMain, whatsWrongLabel).
mainLayout is not in the VerticalLayout, that's why the new component is simply added to it. You have to replace the panel's content.
Change
replaceComponent(mainLayout, new Label("what's wrong?"));
To
panel.setContent(new Label("what's wrong?"));

Creating components as static factory style (Singleton) in Vaadin

I would like to create custom Window using static factory style (or with singleton pattern).
public class MyWindow extends CustomComponent {
private static Window window;
private static MyWindow instance;
public static MyWindow getInstance() {
if (instance == null) {
instance = new MyWindow();
}
return instance;
}
public void show() {
UI.getCurrent().addWindow(window);
}
private MyWindow() {
CustomLayout layout = new CustomLayout("My HTML Layout");
window = new Window("My Window");
window.center();
window.setWidth("615px");
window.setModal(true);
window.setResizable(false);
window.setClosable(true);
window.setContent(layout);
}
}
And call as MyWindow.getInstance().show(); First time calling was ok but after closing this window and while reopened , I got below error logs at my console.
Jul 23, 2014 3:42:39 AM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE:
java.lang.IllegalStateException: com.vaadin.ui.Window already has a parent.
at com.vaadin.ui.AbstractComponent.setParent(AbstractComponent.java:469)
at com.vaadin.ui.Window.setParent(Window.java:155)
at com.vaadin.ui.UI.attachWindow(UI.java:501)
at com.vaadin.ui.UI.addWindow(UI.java:490)
So , how can I use customize Windows with static factory style and how to hide and show Windows ?
I think the easiest way is to create a new Window Object everytime you call the show() method.
The error says that your Window already have a parent. It means that it wasn't removed when you closed it. It is actually weird I've never had that error before. But you can try this if you want:
window.addCloseListener(new CloseListener() {
#Override
public void windowClose(CloseEvent e) {
AbstractSingleComponentContainer.removeFromParent(subwindow);
}
});
This should resolve your problem.

Why Data Can not Pass to Second Activity

Using XamarinStudio and below code base on the Sample in the tutorial. Here the questions.
Do I need to generate the AndroidManifest from the Project Option> Android Application when testing the App ?
Why there is no data passing over even I have generated an AndroidManifest , the code :
---Activity 1
[Activity (Label = "HelloMultiScreen", MainLauncher = true,Icon = "#drawable/icon")]
public class FirstActivity : Activity
{
int count = 1;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
//Use UI created in Main.axml
SetContentView (Resource.Layout.Main);
var showSecond = FindViewById (Resource.Id.showSecond);
showSecond.Click += (sender, e) => {
var second = new Intent(this, typeof(SecondActivity));
second.PutExtra("FirstData", "Data from FirstActivity");
StartActivity (typeof(SecondActivity));
};
}
}
---Activity 2
[Activity (Label = "SecondActivity")]
public class SecondActivity : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Create your application here
SetContentView (Resource.Layout.Second);
var label = FindViewById (Resource.Id.screen2Label);
label.Text = Intent.GetStringExtra("FirstData") ?? "Data not available";
}
}
Thanks
Ok I found the problem when I remade the project myself.
The problem lies in this piece of code:
var second = new Intent(this, typeof(SecondActivity));
second.PutExtra("FirstData", "Data from FirstActivity");
StartActivity (typeof(SecondActivity));
What happens is that you make an Intent with the right data. But you start a new activity without that data.
To fix it change the code to this:
var second = new Intent(this, typeof(SecondActivity));
second.PutExtra("FirstData", "Data from FirstActivity");
StartActivity(second);`

Resources