I develop an application for Android using Adobe AIR and FlashDevelop. Unfortunately my app crashes after start (standard "process has air.HelloWorld stopped" message) and I can't setup debugger (freeze on "waiting for Flash Player to connect to debugger").
When I try to start it in FlashDevelop - it works. The problem arises when I install .apk on emulator and try to start it.
Main.as
import flash.desktop.NativeApplication;
import flash.events.Event;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class Main extends Sprite {
public function Main() : void {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.DEACTIVATE, deactivate);
// touch or gesture?
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
// entry point
var main : FlixelMain = new FlixelMain();
addChild(main);
}
private function deactivate(e:Event) : void {
// auto-close
NativeApplication.nativeApplication.exit();
}
}
FlixelMain.as
import org.flixel.*;
public class FlixelMain extends FlxGame {
public function FlixelMain() {
FlxG.mobile = true;
super(480, 800, MenuState, 1, 60);
}
}
application.xml
<?xml version="1.0" encoding="utf-8"?>
<application xmlns="http://ns.adobe.com/air/application/3.1">
<id>air.HelloWorld</id>
<versionNumber>0.1</versionNumber>
<supportedProfiles>mobileDevice</supportedProfiles>
<filename>HelloWorld</filename>
<name>HelloWorld</name>
<android>
<manifestAdditions><![CDATA[<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:required="true" android:name="android.hardware.touchscreen.multitouch" />
</manifest>]]>
</manifestAdditions>
</android>
<initialWindow>
<title>HelloWorld</title>
<content>HelloWorld.swf</content>
<visible>true</visible>
<fullScreen>true</fullScreen>
<!--<autoOrients>false</autoOrients>-->
<!--<aspectRatio>landscape</aspectRatio>-->
<renderMode>cpu</renderMode>
<systemChrome>standard</systemChrome>
<aspectRatio>portrait</aspectRatio>
</initialWindow>
<icon>
<image72x72>icons/icon_72.png</image72x72>
<image114x114>icons/icon_114.png</image114x114>
<image512x512>icons/icon_512.png</image512x512>
</icon>
</application>
Exported APK file
http://dynax.boo.pl/HelloWorld.apk
If anyone could check this file on his device or knows this problem I will be grateful :)
Greetings.
It may have something to do with the speed of your network connection.
If you run the Debugger over a slow connection, for example a WIFI connection from your device, the debugger can't seem to keep up with the amount of data that's send over the network. When you hit a break point, the Stack-traces and local variables are all send over the network.
If your connection creates a bottleneck, it may slow things down enough for the app thinks it's crashed and it then exits.
Running the debugger on a faster network connection may solve your problem.
Related
Ive been playing with .net Maui and had some success doing Bluetooth LE but for reasons I've gone ahead and changed my implementation to use wifi and a restful API. I am building for both android and IoS. I am testing with a real device, running android 12.
I am trying to make a basic http(s) (tried both http and https) request to a local server (an esp32). My url is:
const string url = "https://192.168.4.1/api";
My manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="31" />
<application android:allowBackup="true" android:icon="#mipmap/appicon" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
My initialisation function, which gets called when my page is loaded - MainPage()
private void init_network()
{
client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
}
and finally, my send function which gets called by a button pressed event
private bool SendCommand(string command)
{
try
{
var msg = new HttpRequestMessage(HttpMethod.Post, url);
msg.Content = JsonContent.Create(command);
HttpResponseMessage response = client.Send(msg); // line where the code throws exception
if (response.IsSuccessStatusCode)
{
return true;
}
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
return false;
}
I also have a runtime permissions section which asks for location_fine_access, which I've given access for.
When running through the request function, I get an exception thrown with the message:
[DOTNET] Operation is not supported on this platform.
I thought this was a permissions issue, and so android isn't letting me make the request but now I'm not so sure. Anyone else had and resolved this issue?
Looks as though .net maui doesnt hook into the android http client properly and is an issue on github. https://github.com/dotnet/maui/issues/1260
the suggested work around, which I have tested and works for me, is to instantiate your HttpClient with the native android handler like this as a workaround:
new HttpClient(new Xamarin.Android.Net.AndroidMessageHandler()).
I'm trying to implement Amazon IAP in a xamarin project following the documentation here.
So here's how my manifest looks like:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="87" android:versionName="8.7" package="XXXXXXXXXXXX">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<application android:icon="#mipmap/ic_launcher" android:label="XXXXXXXXXXXX">
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="XXXXXXXXXXXX" />
<receiver android:name="com.amazon.device.iap.ResponseReceiver" android:permission="com.amazon.inapp.purchasing.Permission.NOTIFY" >
<intent-filter>
<action android:name="com.amazon.inapp.purchasing.NOTIFY" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
And here's my code which is in the Android Project of my solution:
public async Task<bool> MyMethod()
{
try
{
var iapService = AmazonIapV2Impl.Instance;
var tcs = new TaskCompletionSource<bool>();
var skus = new SkusInput { Skus = new List<string>() { "XXXXXXXXX" } };
var requestId = iapService.GetProductData(skus).RequestId;
GetProductDataResponseDelegator delegator = null;
delegator = new GetProductDataResponseDelegator(async response =>
{
await Task.Run(() =>
{
DoSomething();
tcs.SetResult(result);
});
});
iapService.AddGetProductDataResponseListener(delegator.responseDelegate);
await tcs.Task;
}
catch(Exception ex)
{
}
return true;
}
This doesn't throw exceptions but the method DoSomething(); is never called and the last line return true; is never reached. Also the line tcs.Task is stuck on WaitingActivation status. It's like the listener/reciever wasn't working. So my code endlessly wait for the answer.
Any idea how to fix this?
I'm using Xamarin Form version: 5.0.0
Running on Mac, through Visual Studio and debugging on a simulator or a real device (Xiaomi mi9)
Thanks
So first of all the code await Task.Run(() => wasn't necessary to make it work. Secondly, the problem was that my app wasn't submitted yet on the Amazon AppStore and so to test a non-submit app you need to download on your testing phone the app:Amazon App Tester.
In case you have issue to download the Amazon App Tester read this:
In the past, I've tried to download the Amazon App Tester but for some reason my phone didn't want it. I finally "bought" it (it's $0.00 anyway) from my computer on amazon website. Once bought, I was able to find the app in the tab "my app" in the Amazon AppStore on my phone.
i'have a probleme using Upnp to send video file to xbox one with java/android.
I use cling api to discover and connect upnp device over network.
The discover operation work well, the xbox one is detected.
The problem is when i try to send video link to this device.
Here, it's the xbox response on upnp connect service:
<root xmlns="urn:schemas-upnp-org:device-1-0"
xmlns:df="http://schemas.microsoft.com/windows/2008/09/devicefoundation"
xmlns:microsoft="urn:schemas-microsoft-com:WMPDMR-1-0"
xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>`
<deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
<friendlyName>Xbox-SystemOS</friendlyName>
<modelName>Xbox One</modelName>
<modelDescription>Digital Media Renderer</modelDescription>
<manufacturer>Microsoft Corporation</manufacturer>
<manufacturerURL>http://www.microsoft.com</manufacturerURL>
<modelURL>http://xbox.com</modelURL>
<UDN>uuid:6e5e6c24-e450-4c6b-8987-89c6be33a1f7</UDN>
<df:X_containerId>{6E5E6C24-E450-4C6B-8987-89C6BE33A1F7}</df:X_containerId>
<dlna:X_DLNACAP xmlns:dlna="urn:schemas-dlna-org:device-1-0"/>
<dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC>
<pnpx:X_deviceCategory>MediaDevices</pnpx:X_deviceCategory>
<pnpx:X_hardwareId>VEN_0125&DEV_0002&REV_0001 VEN_0125&DEV_0002</pnpx:X_hardwareId>
<iconList>
<icon>
<mimetype>image/jpeg</mimetype>
<width>120</width>
<height>120</height>
<depth>24</depth>
<url>/upnphost/udhisapi.dll?content=uuid:cde23e6c-d763-427d-b96b-c71a8cc5a3a5</url>
</icon>
<icon>
<mimetype>image/jpeg</mimetype>
<width>48</width>
<height>48</height>
<depth>24</depth>
<url>/upnphost/udhisapi.dll?content=uuid:a89beb23-a099-4f65-8cd5-aad6e7210db0</url>
</icon>
<icon>
<mimetype>image/png</mimetype>
<width>120</width>
<height>120</height>
<depth>24</depth>
<url>/upnphost/udhisapi.dll?content=uuid:d4eb98f9-e708-4faa-bcd4-591a9365d000</url>
</icon>
<icon>
<mimetype>image/png</mimetype>
<width>48</width>
<height>48</height>
<depth>24</depth>
<url>/upnphost/udhisapi.dll?content=uuid:ba12866a-d6c8-4a19-94e7-7a2ed8f305b3</url>
</icon>
</iconList>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:RenderingControl:1</serviceType>
<serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
<controlURL>/upnphost/udhisapi.dll?control=uuid:6e5e6c24-e450-4c6b-8987-89c6be33a1f7+urn:upnp-org:serviceId:RenderingControl</controlURL>
<eventSubURL>/upnphost/udhisapi.dll?event=uuid:6e5e6c24-e450-4c6b-8987-89c6be33a1f7+urn:upnp-org:serviceId:RenderingControl</eventSubURL>
<SCPDURL>/upnphost/udhisapi.dll?content=uuid:654eefc5-0e1b-4bfa-a72f-e02001be36e4</SCPDURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
<serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
<controlURL>/upnphost/udhisapi.dll?control=uuid:6e5e6c24-e450-4c6b-8987-89c6be33a1f7+urn:upnp-org:serviceId:AVTransport</controlURL>
<eventSubURL>/upnphost/udhisapi.dll?event=uuid:6e5e6c24-e450-4c6b-8987-89c6be33a1f7+urn:upnp-org:serviceId:AVTransport</eventSubURL>
<SCPDURL>/upnphost/udhisapi.dll?content=uuid:85466b84-2a4a-4514-b7a4-2bb7a4871da4</SCPDURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
<controlURL>/upnphost/udhisapi.dll?control=uuid:6e5e6c24-e450-4c6b-8987-89c6be33a1f7+urn:upnp-org:serviceId:ConnectionManager</controlURL>
<eventSubURL>/upnphost/udhisapi.dll?event=uuid:6e5e6c24-e450-4c6b-8987-89c6be33a1f7+urn:upnp-org:serviceId:ConnectionManager</eventSubURL>
<SCPDURL>/upnphost/udhisapi.dll?content=uuid:1de93088-6694-4d7c-a4a5-771ae3008378</SCPDURL>
</service>
</serviceList>
</device>
</root>
As said in the api documentation, you have to send first an SetAVTransportURI action to the device wich provide the url of the video file:
4.2. Controlling a renderer
Cling Support provides several action callbacks that simplify creating a control point for the AVTransport service. This is the client side of your player, the remote control.
This is how you set an URI for playback:
ActionCallback setAVTransportURIAction = new SetAVTransportURI(service, "http://www.duorimes.siquiere.fr/wa_files/Il_20camino.flv", "NO METADATA") {
#Override
public void failure(ActionInvocation invocation, UpnpResponse operation, String defaultMsg) {
// Something was wrong
}
};
This is how you actually start playback:
ActionCallback playAction = new Play(service) {
#Override
public void failure(ActionInvocation invocation, UpnpResponse operation, String defaultMsg) {
// Something was wrong
}
};
In my case, the first action send me a 500 error code (Internal server error)
Did someone ever experience the same problem?
Thanks by advance for your help.
For SetAVTransportURI, meta must be encoded in XML defined by DLNA spec.
In SetAVTransportURI(service, "http://www.duorimes.siquiere.fr/wa_files/Il_20camino.flv", "NO METADATA"), "NO METADATA" is illegal XML string.
Try to use empty String "" or generate your own meta XML may help.
I’m developing an AIR (Flex) mobile application for Android and it needs to communicate with an http server using SSL or TSL. I got the CA Certificate Chain using Firefox (checked it also with other tools) and got the following chain:
The one scratched is my companies SSL/TSL server. For security reasons I prefer not to post its address.
So, after finding out which certificates I needed (just two in the chain), I searched on my Android tablet which certificates where installed. As you can see in the next picture, the Root certificate, “VeriSign Class 3 Public Primary Certification Authority - G5” was already installed on the system:
The only one that I needed to download was “VeriSign Class 3 Secure Server CA - G3”, which I already did:
Now, I try to enter to the HTTP server with two different browsers and I’m no longer required to accept any certificates. The problem comes when AIR enters the scene. I’ve tried two approaches to communicate with the server, using HTTPService and SecureSocket.
For the first one I use the following code:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView">
<fx:Declarations>
<s:HTTPService id="bookingservice"
resultFormat="text"
url="https://www.myserver.com/"
result="bookingservice_resultHandler(event)"
fault="bookingservice_faultHandler(event)"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected function button1_clickHandler(event:MouseEvent):void
{
resultado.text = "llamando...";
bookingservice.send();
}
protected function bookingservice_resultHandler(event:ResultEvent):void
{
resultado.text = event.result as String;
}
protected function bookingservice_faultHandler(event:FaultEvent):void
{
resultado.text = "satus code: " + event.statusCode + " mensaje: " + event.message.toString();
}
]]>
</fx:Script>
<s:Button top="10" right="10" click="button1_clickHandler(event)" label="Extra" />
<s:TextArea id="resultado"
width="80%" height="80%"
horizontalCenter="0" verticalCenter="0" />
</s:View>
This incredibly simple approach ends with a message box asking for user to accept the unverified server even though all its chain certificates are installed on the Android’s system certificate store.
For the second approach I use the following code:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView">
<fx:Script>
<![CDATA[
private var secureSocket:SecureSocket = new SecureSocket;
protected function button1_clickHandler(event:MouseEvent):void
{
secureSocket.addEventListener( Event.CONNECT, onConnect )
secureSocket.addEventListener( IOErrorEvent.IO_ERROR, onError );
resultado.text = "llamando...";
try
{
secureSocket.connect( "https://www.myserver.com/",443);
}
catch ( error:Error )
{
trace ( error.toString() );
}
resultado.text = "llamando...";
}
private function onConnect( event:Event ):void
{
resultado.text = "Connected.";
}
private function onError( error:IOErrorEvent ):void
{
resultado.text = error.text + ", Server Certificate Status: " + secureSocket.serverCertificateStatus;
}
]]>
</fx:Script>
<s:Button top="10" right="10" click="button1_clickHandler(event)" label="Extra" />
<s:TextArea id="resultado"
width="80%" height="80%"
horizontalCenter="0" verticalCenter="0" />
</s:View>
For this last approach, I don’t even get a message box asking for certificate authorization, I only get an error which says: “Error #2031: Socket Error. URL: https://www.myserver.com/, Server Certificate Status: invalid”.
I would like to know why the AIR (Flex) mobile runtime is not considering the certificates that are already installed on Android certificate store and it’s still asking for user authorization or, even worst, giving errors and saying that the server certificate is invalid. Does anyone know why this is happening? Am I missing something?
Every bit of help will be appreciated.
Not a real answer, but for SecureSocket -
you can add your own certificates programmatically with the
addBinaryChainBuildingCertificate() method
Simply change
secureSocket.connect("https://www.myserver.com/",443);
to
secureSocket.connect("www.myserver.com",443);
(assuming that "www.myserver.com" is the domain named in the certificate)
The following code WORKS when run on the Desktop but does not on the android device. I am thinking it has something to do with the FileStream below.
Any thoughts on how I can save this to an Android device too?
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.net.FileReference;
import flash.net.URLRequest;
import flash.events.Event;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, complete_handler);
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.load(new URLRequest("http://massmediamail.com/mp3s/Why%20a%20Protestant%20Pastor%20Beacame%20Catholic.mp3"));
//any file type;
function complete_handler(event:Event):void
{
var data:ByteArray = event.target.data;
var fr:FileReference = new FileReference();
trace(File.applicationDirectory.nativePath);
fr.save(data, 'Catholic.mp3');
var fileStream:FileStream = new FileStream();
trace(File.applicationDirectory.nativePath);
fileStream.open(new File (File.applicationStorageDirectory.nativePath+"\\Catholic.mp3"),FileMode.WRITE);
fileStream.writeBytes(data, 0, data.length);
}
HERE IS THE ERROR:
Error #2044: Unhandled IOErrorEvent:. text=Error #2038: File I/O Error.
at Untitled_fla::MainTimeline/complete_handler()[Untitled_fla.MainTimeline::frame1:25]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
THIS IS THE LINE IT'S REFERRING TOO:
fileStream.open(new File (File.applicationStorageDirectory.nativePath+"\\Catholic.mp3"),FileMode.WRITE);
It works with Air for Android. Yes you can do more with it later but this is the basic start.
import flash.net.FileReference;
/// It can be an mp3,jpg, png, etc... just change the url
/// and the extension name. nice huh?
var yourFileLocation = "http://YourWeb.com/YourSong.mp3";
var yourFileName = "YourSong.mp3";
var daFile:FileReference = new FileReference();
daFile.download(new URLRequest(yourFileLocation), yourFileName);
I worked FOREVER... to find this. I hope it helps many. Why is this not more common knowledge? Somethings in action-script are impossible to find sometimes.
There is ONE question I have regarding this. How can I make the code download directly to a location on the device rather than the user having to choose the location. Thanks Much!
You'll definitely need to change to "/" over the "\", Android is a linux based system. Actually you should use File.separator property for this rather than a string, this will keep your code cross-platform.
Generally though you should be able to use this:
File.applicationStorageDirectory.resolvePath( "Catholic.mp3" );
Have you given the application permission to write to the filesystem?
To do this you need to add the following, in particular the "WRITE_EXTERNAL_STORAGE" line, to your application descriptor.
<android>
<manifestAdditions><![CDATA[
<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
]]></manifestAdditions>
</android>
Also you should listen for these errors to get more information, and handle them in your code:
fileStream.addEventListener( IOErrorEvent.IO_ERROR, fileStream_errorHandler,