i just finished creating an iOS and Android application with Air ( SDK 18 )
I get an Error #0 ( sometimes - inconsistable ) when trying to save a preferences file.
The code is quite straightforward:
private static var _file:File=File.applicationStorageDirectory.resolvePath(CONFIGFILE);
private static function saveFile():void{
var fileStream:FileStream = new FileStream();
if(File.applicationStorageDirectory.spaceAvailable>1024){
fileStream.open(_file, FileMode.WRITE);
fileStream.writeUTFBytes(Base64.encrypt(JSON.stringify(ob),Strings.HASHSALT));
fileStream.close();
}else{
showLowSpaceAlert()
}
}
On Android eveything works fine and on iOS there are no issues 50% of the time ...
Anyone know this bug? Thanks!
Do not try to create a File object with a static variable, static objects are created during the app init time and timing issues are likely to appear. Your problem is due to your code logic.
The correct way is:
private static var _file:File;
then:
private static function saveFile():void
{
if(!_file)
{
_file = File.applicationStorageDirectory.resolvePath(CONFIGFILE);
}
//etc ...
}
I have only ever gotten this error when a device it out of space. You might try these calls...
trace( File.applicationStorageDirectory.spaceAvailable );
trace( File.cacheDirectory.spaceAvailable );
...to get how many bytes of space are available to you. For example...
var data:String = Base64.encrypt(JSON.stringify(ob),Strings.HASHSALT);
if ( data.length > File.cacheDirectory.spaceAvailable )
{
trace( "NOT ENOUGH SPACE" );
}
else
{
trace( "OK TO SAVE" );
}
The question have been asked on Adobe Forum and the OP tends to says that the issue is because the iOs device lakes of free space.
You should consider freeing a bit of memory on your device.
Related
How can I make possible that the app will load all of the images from the specific folder and then put in array and choose one image randomly? When chose one then pass to the fronted to show the image. How to do that too?
I am C# developer but not long time ago I found ElectronJS and this framework does everything easier so therefore I am moving to this framework.
I did in C# programming this way:
// basic settings.
var ext = new List<string> { ".jpg", ".gif", ".png" };
// we use same directory where program is.
string targetDirectory = Directory.GetCurrentDirectory() + "\\assets\\" + "images\\" + "animals\\";
// Here we create our list of files
// New list
// Use GetFiles to getfilenames
// Filter unwanted stuff away (like our program)
if (Directory.Exists(targetDirectory))
{
Files = new List<string>
(Directory.GetFiles(targetDirectory, "*.*", SearchOption.TopDirectoryOnly)
.Where(s => ext.Any(es => s.EndsWith(es))));
// Show first picture so we dont need wait 3 secs.
ChangePicture();
}
else
{
panel5.BackgroundImage = new Bitmap(Resources.doggy);
}
I don't know how to do in ElectronJS.
Thank you in advance the answers.
Alright. I found the solution.
However I don't understand the people who are giving negative reputation for the opened question. If they are giving negative reputation then they could explain why.
Well anyway, I did fix this issue with this way:
I created images.js file and added this:
var fs = require('fs');
function getRandImage() {
var files = fs.readdirSync('./assets/images/animals/')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
console.log('../assets/images/animals/' + chosenFile);
return '../assets/images/animals/' + chosenFile;
}
module.exports = { getRandImage }
I used console to see if the value is correct, otherwise others can delete that part.
Sending the data to the renderer process:
const { getRandImage } = require('./images');
child.webContents.send('random-image', getRandImage());
I did put in the preload.js file the following (I used the starter pack electronjs github to start with something):
var { ipcRenderer } = require('electron');
ipcRenderer.on('random-image', function (event, store) {
document.getElementById("randompic").src = store;
console.log(store);
});
Same here, I did use console.log just for test the value is correct and I used to change the randompic ID related image src html to the randomly chosen image.
Hopefully I did helping those people who are newbie as me.
I started working on a project that was built using OneSignal v1.15.2.
On Android everything works fine.
On iOS instead, I tried to follow this: https://documentation.onesignal.com/v3.0/docs/unity-sdk-setup (points [5.1 - 5.7]: they just add UserNotifications.framework)
Now, if I launch my application it crashes and the message is: "dyld: image not found".
If I remove UserNotifications.framework the all game runs ok but notifications.
Is the current version of OneSignal so different from the past? Is there another setup process guide that I should follow?
I'm using Unity 5.3.1p4 and XCode 8.2.1 (I was using XCode 8.3.1 and notifications worked well, but this newer version have some documented incompatibility with Unity 5.3.1p4).
Can anyone help me?
Thank you.
Best regard,
Andrea.
For what it's worth I'm using Unity 5.6.0 and Xcode 8.3.2 with the SDK Unity5OneSignalSDK.unitypackage and points 5.1 through 5.7 where sufficient to get push notifications working.
I am also automating the background modes to check "remote-notifications" using the following post processor ... I can't find a way to automate the link with UserNotifications.framework yet tho ... let me know if anybody has ideas on how to do that.
// ---------------------------------------------------------------------------------------------------------------------
public static class XCodePostProcess
{
// -----------------------------------------------------------------------------------------------------------------
[PostProcessBuild(100)]
public static void OnPostprocessBuild( BuildTarget target, string pathToBuildProject )
{
if (target == BuildTarget.iOS)
{
UpdateInfoPlist( pathToBuildProject );
}
}
// -----------------------------------------------------------------------------------------------------------------
private static void UpdateInfoPlist( string path )
{
// load plist
string plistPath = Path.Combine( path, "Info.plist" );
PlistDocument plist = new PlistDocument();
plist.ReadFromString( File.ReadAllText( plistPath ) );
//Get Root
PlistElementDict rootDict = plist.root;
//Add Necessary Things
PlistElementArray LSApplicationQueriesSchemes = rootDict.CreateArray( "LSApplicationQueriesSchemes" );
LSApplicationQueriesSchemes.AddString( "itms-beta" ); // test flight
// localizations
PlistElementArray CFBundleLocalizations = rootDict.CreateArray( "CFBundleLocalizations" );
CFBundleLocalizations.AddString( "en" ); // english
CFBundleLocalizations.AddString( "de" ); // german
CFBundleLocalizations.AddString( "fr" ); // french
CFBundleLocalizations.AddString( "es" ); // spanish
// for OneSigna remote notifications
PlistElementArray UIBackgroundModes = rootDict.CreateArray( "UIBackgroundModes" );
UIBackgroundModes.AddString( "remote-notification" );
//WriteFile
File.WriteAllText (plistPath, plist.WriteToString ());
}
}
I am trying to use ActionScript's File.upload to upload a file on Air SDK for iOS environment, but the File.upload does not work properly. No handler about the file upload is executed after File.upload is invoked, and no exception is caught. When I check the network traffic of the server side, I found that no http request even hit the server after executing File.upload. The code is below.
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
private var file:File;
private var dir:File;
//This method is executed to create a file and upload it when the Upload Button is pressed.
protected function OnUploadButtonPressed(event:MouseEvent):void{
trace("upload button clicked");
var urlReq:URLRequest = new URLRequest("http://10.60.99.31/MyPath/fileUploadTest.do");
urlReq.method = URLRequestMethod.POST;
var str:String = 'This is test';
var imageBytes:ByteArray = new ByteArray();
for ( var i:int = 0; i < str.length; i++ ) {
imageBytes.writeByte( str.charCodeAt(i) );
}
trace("size = " + imageBytes.length);
try{
dir = File.applicationStorageDirectory
//I also tested in several different directories
//dir = File.createTempDirectory();
//dir = File.documentsDirectory;
var now:Date = new Date();
var filename:String = "IMG" + now.fullYear + now.month + now.day + now.hours + now.minutes + now.seconds + now.milliseconds + ".txt";
file = dir.resolvePath( filename );
var stream:FileStream = new FileStream();
stream.open( file, FileMode.WRITE );
stream.writeBytes( imageBytes );
stream.close();
//Read back the file contents to check whether the file is written successfully.
var readStream:FileStream = new FileStream();
readStream.open(file, FileMode.READ);
var result:String = readStream.readUTFBytes(readStream.bytesAvailable);
trace("read back result = " + result);//The result is shown here as expected.
file.addEventListener( Event.COMPLETE, uploadComplete );
file.addEventListener( IOErrorEvent.IO_ERROR, ioError );
file.addEventListener( SecurityErrorEvent.SECURITY_ERROR, securityError );
file.addEventListener(ErrorEvent.ERROR, someError);
file.addEventListener(ProgressEvent.PROGRESS, onProgress);
file.upload( urlReq );//This line does not work. No handler is executed. No http request hit the server side.
trace("after file upload test");
}
catch( e:Error )
{
trace( e );
}
}
//Complete Handler
private function uploadComplete( event:Event ):void
{
trace( "Upload successful." );
}
//IOError handler
private function ioError( error:IOErrorEvent ):void
{
trace( "Upload failed: " + error.text );
}
//SecurityError handler
private function securityError(error:SecurityErrorEvent):void{
trace( "Security error:" + error.text );
}
//Other handler
private function someError(error:ErrorEvent):void{
trace("some error" + error.text);
}
//Progress handler
private function onProgress(event:ProgressEvent):void{
trace("progressHandler");
}
//This method is executed to invoke the URLLoader.load when the Tricky Button is pressed.
protected function OnTrickyButtonPressed(event:MouseEvent):void{
var urlReq:URLRequest = new URLRequest("http://200.60.99.31/");//This points to a non-existed server
urlReq.method = URLRequestMethod.POST;
urlReq.data = new ByteArray();
var loader:URLLoader = new URLLoader();
try{
loader.load(urlReq);//This line seems very important in iOS7. It decides whether the latter file.upload can work.
//But in iOS8, file.upload does not work even if this line is executed.
trace("after urlloader load");
}catch(e:Error){
trace(e);
}
}
]]>
</fx:Script>
<s:Button x="200" y="200" width="400" height="200" label="Upload" click="OnUploadButtonPressed(event)" />
<s:Button x="200" y="500" width="400" height="200" label="Tricky" click="OnTrickyButtonPressed(event)" />
</s:View>
When executed on Air Simulator, it works fine as expected, and the file is successfully uploaded to the server. But When executed on iOS devices(in my case, iPad), as I explain early, no handler about the file upload is executed, and no the http request event hit the server. So I think the problem may be in the client side.
During my try to solve the problem, I found something tricky about this problem on iOS7. That is, if you invoke the URLLoader.load method (even if the URLLoader.load points to a non-existed address) before invoking the File.upload method, the File.upload will work as expected on iOS7. More specifically, when method OnTrickyButtonPressed above is executed before method OnUploadButtonPressed, File.upload will succeed on iOS7. But this only happens on iOS7. On iOS8, File.upload always refuses to work, regardless of whether the URLLoader.load is executed before.
I think in my case the problem is not the Sandbox problem or Firefox session problem described in the two links below, because not even any http request hit the server side. It seems that the Air SDK for iOS just failed to send the http request for some reason.
Flex 4 FileReference Issues With Firefox
How do I make Flex file upload work on firefox and safari?
To make my problem more clear, I list my environment below:
Develoment Environment: Windows7 (64bit) / Mac os 10.9.4 (Tested on
two OS platforms.)
IDE: Flash Builder 4.7
Air SDK: 3.8 / 16.0.0 (After I updated to the lastest Air SDK 16.0.0
, the problem still exists.)
Application Server: Tomcat7 + Spring
Finally, I would like to mention that uploading file using URLLoader.load is not an option in my case because I want to upload large files in the future, which can not be handled with the URLLoader.load.
I have been struggling for this for days. So I really appreciate it if anyone has any idea about this.
Thanks in advance.
Finally I found that the real problem is not about the code I provided, it is about the http proxy Auto configuration, and this problem happened on iOS7 and iOS8. I described the problem and a workaround in detail in the following link. Hope this will help some of you.
https://forums.adobe.com/thread/1716036
I am trying to save some files on micro SDCard. To check the availability of SDCard, I am using the following method;
private boolean isSdCardReady() {
Enumeration e = FileSystemRegistry.listRoots();
while (e.hasMoreElements()) {
if (e.nextElement().toString().equalsIgnoreCase("sdcard/")) {
return true;
}
}
return false;
}
Even if this method returns true, when I try to save files, it gives exception net.rim.device.api.io.file.FileIOException: File system is not ready.
What does this means? If SDCard is not available, then why its listed in FileSystemRegistry.listRoots()?
How can I make sure that SDCard is available for writing?
My development environment:
BlackBerry JDE Eclipse Plugin 1.5.0
BlackBerry OS 4.5
BlackBerry Bold with a 3G card
Usually I had this error when I tried to access SD card on device restart. You have to postpone all operations in app until startup finished:
while (ApplicationManager.getApplicationManager().inStartup()) {
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
I remember one more possible cause mentioned here. You have to close all streams after using.
Solved the problem. I was looking for "sdcard" while rootsEnum.nextElement().toString(); returns "SDCard". Yeah, its case sensitive. Now, instead of using hard-coded "SDCard", I've changed the above method to the following;
private static String getSdCardRootDir() {
Enumeration rootsEnum = FileSystemRegistry.listRoots();
while (rootsEnum.hasMoreElements()) {
String rootDir = rootsEnum.nextElement().toString();
if (rootDir.equalsIgnoreCase("sdcard/")) {
return "file:///" + rootDir;
}
}
return null;
}
Using this, I got the root directory in its system defined case.
List item
i developed an application , in which uses sq lite database . this is running properly on simulater . but when we application deploy on Blackberry curve 8520 mobile then . tell us database does not exist. anyone know answer please quick response ...
My Code is ->
public static void insertData( String pass , String cpass)
{
boolean fl=false;
String root = null;
MainScreen ms = new MainScreen();
Enumeration e = FileSystemRegistry.listRoots();
while (e.hasMoreElements())
{
root = (String)e.nextElement();
if(root.equalsIgnoreCase("store/"))
{
fl=true;
}
}
if(!fl)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("This application requires an SD card to be present." +
"Exiting application...");
System.exit(0);
}
});
}
else
{
String dbLocation = "C:/om12345/sql/res/store/";
// Create URI
// Statement st=null;
try
{
URI myURI = URI.create("file:///store/home/user/databases/database.sqlite");
//URI myURI1=URI.
d = DatabaseFactory.create(myURI);
Statement st = d.createStatement( "insert into Admin (pass, Cpass) values('"+ pass+"','"+cpass+"')");
st.prepare();
st.execute();
st.close();
d.close();
//ms.add(new RichTextField ("tata" + "tata1"));
// UiApplication.getApplication.invokeLater(pushScreeen(ms));
}
catch ( Exception e1 )
{
System.out.println( e1.getMessage() );
e1.printStackTrace();
}
}
You likely can't store a sqlite database on /store for the 8520. See my answer to BlackBerry SQLite database creation: "filesystem not ready" for more information on that.
You will first need to change the line that says " String dbLocation = "C:/om12345/sql/res/store/";" since that refers to a location on your development machine but will not work on a mobile device. You need to point to the 'res' folder in your application itself.
You can not create database into store directory if you are having less than 1gb internal storage & you have saved your data base in C directory , which can be accessible from your system, but not on device. So change its location copied into it res folder.
& check if you are having SD card then save your database using /SDCard.
If SDCard is not available than you will able to access database , if you are having more than 1GB internal storage
have a look on this link
http://docs.blackberry.com/en/developers/deliverables/17952/SQLite_database_files_1219778_11.jsp