Load Xamarin Forms page from android notification - xamarin.android

I am trying to load a Xamarin Forms page from an Android Notification. I am really lost on the android side of this, and most of my code has been pieced together from tutorials and blog posts. However nothing really seems to cover exactly this scenario.
I have implemented a very simple interface with dependency service to create the notification with an intent...
[assembly: Xamarin.Forms.Dependency(typeof(QuoteNotification))]
namespace QuoteApp.Droid
{
class QuoteNotification : IQuoteNotification
{
public void Notify(string title, string message)
{
//type needs to be derived from java, not xamarin.forms
Intent LoadPostPage = new Intent(Forms.Context, typeof(DroidToForms));
const int pendingIntentId = 0;
PendingIntent pendingIntent =
PendingIntent.GetActivity(Forms.Context, pendingIntentId, LoadPostPage, PendingIntentFlags.OneShot);
Notification.Builder builder = new Notification.Builder(Forms.Context)
.SetContentIntent(pendingIntent)
.SetAutoCancel(true)
.SetContentTitle(title)
.SetContentText(message)
.SetSmallIcon(Resource.Drawable.icon);
// Build the notification:
Notification notification = builder.Build();
// Get the notification manager:
NotificationManager notificationManager =
Forms.Context.GetSystemService(Context.NotificationService) as NotificationManager;
// Publish the notification:
const int notificationId = 0;
notificationManager.Notify(notificationId, notification);
}
}
}
this calls an activity -
namespace QuoteApp.Droid
{
[Activity(Label = "QuoteApp", MainLauncher = true)]
class DroidToForms : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
StartActivity(typeof(XFPostPage));
//Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new QuoteApp.PostPage());
}
}
}
which in turn calls this forms page, all the code here has been in Xamarin.Android project
namespace QuoteApp.Droid
{
/// <summary>
/// This is a Xamarin.Forms screen. It MUST:
/// * inherit from ANdroidActivity
/// * call Forms.Init()
/// * use LoadApplication()
/// </summary>
[Activity(Label = "XFPostPage", MainLauncher = true) ]
public class XFPostPage : Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
//LoadApplication( new App() ); //how do i send to PostPage.xaml ??
Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new QuoteApp.PostPage());
}
}
}
this gives the following error in logcat
07-04 17:51:44.494 7668 7668 E AndroidRuntime: Caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at QuoteApp.Droid.XFPostPage.OnCreate (Android.OS.Bundle bundle) [0x00016] in <ab64801c0fb24acb8457c1d1202cc143>:0
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <d855bac285f44dda8a0d8510b679b1e2>:0
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at (wrapper dynamic-method) System.Object:2780fa42-5931-40d3-8d14-a642f1a3025c (intptr,intptr,intptr)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at md543d03747be5a5b03a21a2a23b8ba191a.XFPostPage.n_onCreate(Native Method)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at md543d03747be5a5b03a21a2a23b8ba191a.XFPostPage.onCreate(XFPostPage.java:29)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6237)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.app.ActivityThread.-wrap11(ActivityThread.java)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
07-04 17:51:44.494 7668 7668 E AndroidRuntime: ... 3 more
I have tried a bunch of different ideas all with different runtime errors, my understanding of the Xamarin.Android workings are very limited. eventually i will be using the notification with AlarmManager and further information will be sent to PostPage.Xaml. At the moment i'm just lost at exactly where this is going wrong though?!
Any Help would be hugely appreciated, thanks in advance.

I ended up using OnNewIntent in MainActivity.
there is some excellent information here Processing notifications in Xamarin Forms Android
My Code ended up looking like this.
Call the dependency service to get the android implmentation
DependencyService.Get<IQuoteNotification>().Notify("words",SelectedQuote.FixedTitle , SelectedQuote.Id);
Which builds notification with the Intent:
class QuoteNotification : IQuoteNotification
{
public void Notify(string title, string message, int postIndex)
{
//type needs to be derived from java, not xamarin.forms
Intent LoadPostPage = new Intent(Forms.Context, typeof(MainActivity));
LoadPostPage.PutExtra("NotificationTrue", true);
LoadPostPage.PutExtra("PostID", postIndex);
const int pendingIntentId = 0;
PendingIntent pendingIntent =
PendingIntent.GetActivity(Forms.Context, pendingIntentId, LoadPostPage, PendingIntentFlags.OneShot);
Notification.Builder builder = new Notification.Builder(Forms.Context)
.SetContentIntent(pendingIntent)
.SetAutoCancel(true)
.SetContentTitle(title)
.SetContentText(message)
.SetSmallIcon(Resource.Drawable.icon);
// Build the notification:
Notification notification = builder.Build();
// Get the notification manager:
NotificationManager notificationManager =
Forms.Context.GetSystemService(Context.NotificationService) as NotificationManager;
// Publish the notification:
const int notificationId = 0;
notificationManager.Notify(notificationId, notification);
}
}
then Override OnNewIntent in MainActivity. If the intent is not Built by my QuoteNotification class then send -1 as PostID
protected override void OnNewIntent(Intent intent)
{
if (intent.HasExtra("NotificationTrue")){
LoadApplication(new App(intent.GetIntExtra("PostID", -1)));
//Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new QuoteApp.PostPage());
}
base.OnNewIntent(intent);
}
Then in App.Xaml.cs add some logic to navigate to the correct page
public partial class App : Application
{
public App(int PostId = -1)
{
InitializeComponent();
if (PostId >= 0)
{
MainPage = new NavigationPage(new PostPage(PostId));
}
else
MainPage = new NavigationPage(new MainPage());

Problem is with your code Intent LoadPostPage = new Intent(Forms.Context, typeof(DroidToForms));.
For Android platform of XF project, it only has one Activity, which is MainActivity, or pages of XF are rendered based on this MainActivity.
So you may change you code like this:
Intent intent = new Intent(context, typeof(MainActivity));
intent.PutExtras(valuesForActivity);
PendingIntent resultPendingIntent = PendingIntent.GetActivity(Xamarin.Forms.Forms.Context, 0, intent, PendingIntentFlags.OneShot);
Then in your OnCreate method of MainActivity:
//navigate to the page of PCL
Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new PostPage());
At last, as #Pratik suggested, if you want to create a native page/ view for Android platform, use PageRenderer or ViewRenderer to do so.

Related

MonoGame NullReferenceException on iOS

I'm trying to build a simple MonoGame app for iOS using F#. I have done this by manually cooking up a fsproj file, on the basis of project files for
F# iOS Single Page Application (template),
F# console application (template) and
C# iOS MonoGame (template).
My code looks like this:
namespace MonoGameFSharpTemplate
module Game =
open Microsoft.Xna.Framework
open Microsoft.Xna.Framework.Graphics
open Microsoft.Xna.Framework.Input
open Microsoft.Devices.Sensors
type Game1 () as x =
inherit Game()
do x.Content.RootDirectory <- "Content"
member val graphics = new GraphicsDeviceManager(x) with get, set
override x.Initialize() =
do base.Initialize()
override x.LoadContent() = ()
override x.Update (gameTime) =
do base.Update(gameTime)
override x.Draw (gameTime) =
do base.Draw(gameTime)
module App =
open UIKit
open Foundation
open Game
[<Register("AppDelegate")>]
type AppDelegate() =
inherit UIApplicationDelegate()
override val Window = null with get, set
override this.FinishedLaunching(app, options) =
use game = new Game1()
game.Run()
true
module Main =
open UIKit
[<EntryPoint>]
let main argv =
UIApplication.Main(argv, null, "AppDelegate")
0
It should be pretty much equivalent to the code provided in the C# template (which runs just fine, by the way).
When running this code in the iOS simulator, I get a NullReferenceException with the following stack trace
at Microsoft.Xna.Framework.Game.get_IsActive () [0x00000] in <d3066bb8224f42c4ab3ae66d66329856>:0
at Microsoft.Xna.Framework.iOSGamePlatform.Tick () [0x00006] in <d3066bb8224f42c4ab3ae66d66329856>:0
at Microsoft.Xna.Framework.iOSGameView.DoTick () [0x00000] in <d3066bb8224f42c4ab3ae66d66329856>:0
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/5024/152b654a/source/xamarin-macios/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/5024/152b654a/source/xamarin-macios/src/UIKit/UIApplication.cs:63
at MonoGameFSharpTemplate.Main.main (System.String[] argv) [0x00000] in /Users/torbonde/Projects/MonoGameFSharpTemplate/MonoGameFSharpTemplate/Program.fs:47
I'm running the latest MonoGame build, v3.7.0.937, but I had the same issue using v3.6.
Does anyone know why I'm getting this error, and how to fix it? I can post the project file with references if necessary.

Xamarin forms Android timeout issue on StartUp

Hi, my android application sometimes stucks on startup. On Xamarin test cloud the failure seems like;
SetUp : System.TimeoutException : Timed out waiting...
at Xamarin.UITest.Shared.WaitForHelper.WaitFor (System.Func1 predicate, System.String timeoutMessage, Nullable1 timeout, Nullable1 retryFrequency, Nullable1 postTimeout) <0x7e4c998 + 0x004db> in :0
at Xamarin.UITest.Android.AndroidApp..ctor (IAndroidAppConfiguration appConfiguration) <0x7cacab8 + 0x0073b> in :0
at Xamarin.UITest.Configuration.AndroidAppConfigurator.StartApp (AppDataMode appDataMode) <0x7cac008 + 0x00063> in :0
at YH.MB.Test.AppInitializer.StartApp (Platform platform) <0x7cab060 + 0x00027> in :0
at YH.MB.Test.Tests.BeforeEachTest () <0x7cab010 + 0x00013> in :0
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x3249110 + 0x00093> in :0
When i tried it on Samsung s3(on xamarin test cloud) there was a StackTrace too;
java.lang.NullPointerException: key == null
at android.util.LruCache.get(LruCache.java: 113)
at com.android.providers.settings.SettingsProvider$SettingsCache.isRedundantSetValue(SettingsProvider.java: 872)
at com.android.providers.settings.SettingsProvider.insert(SettingsProvider.java: 574)
at android.content.ContentProvider$Transport.insert(ContentProvider.java: 201)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java: 148)
at android.os.Binder.execTransact(Binder.java: 367)
at dalvik.system.NativeStart.run(Native Method: )
I can not repeat that issue on debug mode. What can it be?
My Android OnCreate method is;
protected override void OnCreate(Bundle bundle)
{
// set the layout resources first
ToolbarResource = Resource.Layout.toolbar;
TabLayoutResource = Resource.Layout.tabs;
base.OnCreate(bundle);
Forms.Init(this, bundle);
#if ENABLE_TEST_CLOUD
Xamarin.Forms.Forms.ViewInitialized += (object sender, Xamarin.Forms.ViewInitializedEventArgs e) =>
{
if (!string.IsNullOrWhiteSpace(e.View.AutomationId))
{
e.NativeView.ContentDescription = e.View.AutomationId;
}
};
#endif
var container = new SimpleContainer();
container.Register<IDevice>(t => AndroidDevice.CurrentDevice);
container.Register<IDisplay>(t => t.Resolve<IDevice>().Display);
container.Register<IMediaPicker>(t => new MediaPicker());
container.Register<IFontManager>(t => new FontManager(t.Resolve<IDisplay>()));
container.Register<INetwork>(t => t.Resolve<IDevice>().Network);
container.Register<IJsonSerializer, MBJsonSerializer>();
container.Register<IPhoneService, PhoneService>();
container.Register<IUserDialogs>(t => UserDialogs.Instance);
if (!Resolver.IsSet)
Resolver.SetResolver(container.GetResolver());
UserDialogs.Init(this);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
My UITest SetUp Method ;
[TestFixture(Platform.Android)]
[TestFixture(Platform.iOS)]
public class Tests
{
IApp app;
Platform platform;
public Tests(Platform platform)
{
this.platform = platform;
}
[SetUp]
public void BeforeEachTest()
{
app = AppInitializer.StartApp(platform);
}
}
Thanks in advance.

Appium unable to retrieve webelement using TestNG

We have developed an app and we would like to configure automated tests with Appium and TestNG. The app contains both native and web pages, but the header where reside logo, hamburger (in homepage) and back button is always native.
I get the web resources id from Chrome Inspector, but the command:
WebElement usernameEditText = driver.findElement(By.id("username"));
or
WebElement login = driver.findElement(By.xpath("//input[#id='login-ico']"));
fails with this error:
org.openqa.selenium.NoSuchElementException: An element could not be
located on the page using the given search parameters. (WARNING: The
server did not provide any stacktrace information)
Command duration or timeout: 309 milliseconds
For documentation on this error, please visit:
http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.46.0', revision:
'61506a4624b13675f24581e453592342b7485d71', time: '2015-06-04 10:22:50'
System info: host: 'stefano', ip: '127.0.0.1', os.name: 'Mac OS X',
os.arch: 'x86_64', os.version: '10.11.4', java.version: '1.7.0_79'
*** Element info: {Using=xpath, value=//input[#id='login-ico']}
Session ID: 18098de4-ee19-42b5-9f91-30f6f7e01552
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities [{automationName=Appium, platform=LINUX,
javascriptEnabled=true,
appActivity=com.UnipolSaiApp.activity.MainActivity,
networkConnectionEnabled=true, desired={automationName=Appium,
platformVersion=5.0.1, platformName=Android, deviceName=Android,
appActivity=com.UnipolSaiApp.activity.MainActivity, device=Android,
appPackage=com.UnipolSaiApp}, locationContextEnabled=false,
appPackage=com.UnipolSaiApp, platformVersion=5.0.1,
databaseEnabled=false, deviceName=9b984ca9, platformName=Android,
webStorageEnabled=false, device=Android, warnings={},
takesScreenshot=true}]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:204)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:156)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:605)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:43)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:358)
at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:455)
at io.appium.java_client.DefaultGenericMobileDriver.findElementByXPath(DefaultGenericMobileDriver.java:129)
at io.appium.java_client.AppiumDriver.findElementByXPath(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElementByXPath(AndroidDriver.java:1)
at org.openqa.selenium.By$ByXPath.findElement(By.java:358)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:350)
at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:51)
at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElement(AndroidDriver.java:1)
at pages.LoginPage.login_success(LoginPage.java:25)
at scenarios.AppiumTest.loginTest(AppiumTest.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:673)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:842)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1166)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.runWorkers(TestRunner.java:1178)
at org.testng.TestRunner.privateRun(TestRunner.java:757)
at org.testng.TestRunner.run(TestRunner.java:608)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1158)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1083)
at org.testng.TestNG.run(TestNG.java:999)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:74)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Instead, the retrieving of native elements occur with success.
Here the code of my AndroidSetup:
public class AndroidSetup {
protected AndroidDriver driver;
protected void prepareAndroidForAppium() throws MalformedURLException {
File appDir = new File("/path_of_apk");
File app = new File(appDir,"*****.apk");
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("deviceName","Android");
dc.setCapability("platformVersion","5.0.1");
dc.setCapability("platformName","Android");
//dc.setCapability(CapabilityType.BROWSER_NAME, "browser");
dc.setCapability("device","Android");
dc.setCapability("appPackage","com.*******");
dc.setCapability("appActivity","com.*******.MainActivity");
//other caps
//dc.setCapability("app",app.getAbsolutePath());
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), dc);
Set<String> contexts = driver.getContextHandles();
for (String ctx : contexts) {
System.out.println(ctx);
}
}
}
Here the AppiumTest:
public class AppiumTest extends AndroidSetup {
#BeforeClass
public void setUp() throws Exception {
prepareAndroidForAppium();
}
#AfterClass
public void tearDown() throws Exception {
driver.quit();
}
#Test
public void loginTest() throws InterruptedException
{
new LoginPage(driver).login_success();
}
}
Here the BaePage class:
public class BasePage {
protected WebDriver driver;
String app_package_name = "com.****:id/";
public BasePage(WebDriver driver) {
this.driver = driver;
}
protected void waitForVisibilityOf(By locator) {
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
}
protected void waitForClickabilityOf(By locator) {
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(locator));
}
}
And here the LoginPage:
public class LoginPage extends BasePage {
public LoginPage(WebDriver driver) {
super(driver);
}
public LoginPage login_success() throws InterruptedException {
Thread.sleep(30000);
WebElement login = driver.findElement(By.xpath("//input[#id='login-ico']"));
login.click();
WebElement usernameEditText = driver.findElement(By.id("usernameET"));
usernameEditText.sendKeys("****");
WebElement passwordEditText = driver.findElement(By.id("passwordET"));
passwordEditText.sendKeys("*****");
WebElement loginButton = driver.findElement(By.id("submitBtn"));
loginButton.click();
return new LoginPage(driver);
}
}
The following code:
Set<String> contexts = driver.getContextHandles();
for (String ctx : contexts) {
System.out.println(ctx);
}
returns just NATIVE_APP entry.
Can you explain me what's wrong? It's an error about the Appium configuration?

SecurityException even after giving uses-permission tag for vibration

I am trying to make an Android app which starts vibration on button click.
below is the code related to vibration, I have added uses-permission tag in Android manifest file, still the app terminates giving SecurityException
public class MainActivity extends AppCompatActivity {
private Vibrator v;
TimerTask timerTask;
int n=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
}
public void startTimer(View view) {
final Handler handler = new Handler();
Timer mTimer = new Timer();
v.vibrate(2000);
timerTask = new TimerTask() {
#Override
public void run() {
boolean post = handler.post(new Runnable() {
#Override
public void run() {
TextView timer = (TextView) findViewById(R.id.timer);
timer.setText(n);
n++;
}
});
}
};
mTimer.schedule(timerTask, 0, 100);
}
logcat:
06-17 03:41:12.962 8851-8851/com.neuroapp.ojas.neuroapp W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x40c3ba68)
06-17 03:41:13.022 8851-8851/com.neuroapp.ojas.neuroapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:3099)
at android.view.View.performClick(View.java:3571)
at android.view.View$PerformClick.run(View.java:14247)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4517)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at android.view.View$1.onClick(View.java:3094)
at android.view.View.performClick(View.java:3571)
at android.view.View$PerformClick.run(View.java:14247)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4517)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.SecurityException: Requires VIBRATE permission
at android.os.Parcel.readException(Parcel.java:1327)
at android.os.Parcel.readException(Parcel.java:1281)
at android.os.IVibratorService$Stub$Proxy.vibrateMagnitude(IVibratorService.java:290)
at android.os.Vibrator.vibrate(Vibrator.java:88)
at android.os.Vibrator.vibrate(Vibrator.java:57)
at com.neuroapp.ojas.neuroapp.MainActivity.startTimer(MainActivity.java:48)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at android.view.View$1.onClick(View.java:3094)
at android.view.View.performClick(View.java:3571)
at android.view.View$PerformClick.run(View.java:14247)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4517)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)

GCM xamarin: Register

I am using xamarin android 4.10.1 and GooglePlayServices Rev. 12 from xamarin component store. It is mvvmcross application, so I have Core and Android projects. I need push notifications support in my app. So I start with GooglePlayServices component. I write this code:
var gcm = GoogleCloudMessaging.GetInstance(this);
var key = gcm.Register(new[] { "senderId" });
and it doesn't work, I fount that I need to run it on async thread, one solution I found here: http://forums.xamarin.com/discussion/8420/error-calling-googlecloudmessaging-register
ThreadPool.QueueUserWorkItem(o =>
{
var gcm = GoogleCloudMessaging.GetInstance(this);
var key = gcm.Register(new[] { Settings.GmcSenderId });
});
This code works, my service handle registration message, but I need this registration key in my mvvmcross ViewModel. So I start to register with Task approach:
var task = Task.Factory.Startnew(() =>
{
var gcm = GoogleCloudMessaging.GetInstance(this);
return gcm.Register(new[] { Settings.GmcSenderId });
});
var key = task.Result; // wait for result
// key is needed to execute code here
// ViewModel.Key = key;
But every time I receive SERVICE_NOT_AVAILABLE Exception, also I have try to sync with ManualResetEvent object, but still have exceptions.
Maybe some one know solution, how to bring registration Id to ViewModel class from View (activity). Or maybe you have some example with mvvmcross and receiving registration Id in view model...
My code with Task:
public string Register(string senderId)
{
var task = Task.Factory.StartNew(() =>
{
var context = Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity;
var gcm = GoogleCloudMessaging.GetInstance(context);
return gcm.Register(senderId);
});
return task.Result; // exception here!
}
Detailed exception:
InnerException {Java.IO.IOException: Exception of type 'Java.IO.IOException' was thrown.
at Android.Runtime.JNIEnv.CallObjectMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00064] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.1-branch/d23a19bf/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:194
at Android.Gms.Gcm.GoogleCloudMessaging.Register (System.String[] p0) [0x00000] in <filename unknown>:0
at Fiocx.Android.Code.NotificationService+<>c__DisplayClass1.<Register>b__0 () [0x00013] in d:\ASUS\Work\Programming\.NET\Fiocx.CloudApp\mobile_src\Fiocx.Mobile\Fiocx.Android\Code\NotificationService.cs:33
at System.Threading.Tasks.TaskActionInvoker+FuncInvoke`1[System.String].Invoke (System.Threading.Tasks.Task owner, System.Object state, System.Threading.Tasks.Task context) [0x00000] in <filename unknown>:0
at System.Threading.Tasks.Task.InnerInvoke () [0x00000] in <filename unknown>:0
at System.Threading.Tasks.Task.ThreadStart () [0x00000] in <filename unknown>:0
--- End of managed exception stack trace ---
java.io.IOException: SERVICE_NOT_AVAILABLE
at com.google.android.gms.gcm.GoogleCloudMessaging.register(Unknown Source)
at dalvik.system.NativeStart.run(Native Method)
} Java.IO.IOException
Similar problem with a solution: GCM SERVICE_NOT_AVAILABLE on Android 2.2
Btw have you tried using PushSharp?
https://github.com/Redth/PushSharp

Resources