I have a 3MB website that's static HTML/CSS/JS and I'd like to package it up into an Android app for offline use.
Are there premade APK archives for static webapps... the kind where I can just insert the static html/css/js and the app is programmed to load "index.html" or something? Presumablty I'd need to put index.html in /res/raw or /assets. I'm not a Java programmer so that's that main reason I'm asking.
I understand that APK files need to be cryptographically signed but presumably I can do this later.
AppMobi takes your webapp, compiles it with their pre-built template, and gives you the resulting APK. Make sure you use a custom loading splash image and implement the hack workaround in the forums to speed up first-time loading.
You don't need to do anything but create a new project and paste your web-app into the project folder, then follow the screenshots. And that hack I mentioned.
If you have or understand gradle, I did this to prevent polluting the actual web-app:
task appmobi(dependsOn: [buildForWeb]) << {
File indexFile = new File('build/index.html')
def appMobiLoader = '''<script type="text/javascript" src="http://localhost:58888/_appMobi/appmobi.js"></script>
<script type="text/javascript">
function deviceReadyListener() {
AppMobi.device.hideSplashScreen();
}
window.document.addEventListener("appMobi.device.ready", deviceReadyListener, false);
</script>'''
def indexText = indexFile.text.replace("</head>", "$appMobiLoader</head>")
indexFile.withWriter { writer ->
writer.write(indexText)
}
}
Check out the PhoneGap project. http://www.phonegap.com/
Related
So in my project I have an image object that loads various different sprites throughout the game. In order to implement this, I have a folder with a bunch of .pngs that the game accesses. In order for this to work in a standalone build I put these images in the following path:
StreamingAssets/Question Images
However, in Android I am getting an error because, as the manual says:
"On Android, the files are contained within a compressed .jar file (which is essentially the same format as standard zip-compressed files). This means that if you do not use Unity’s WWW class to retrieve the file, you need to use additional software to see inside the .jar archive and obtain the file.
The thing is I have no idea how to go about implementing this, any ideas?
From Application.streamingAssetsPath
It is not possible to access the StreamingAssets folder on WebGL and Android platforms. No file access is available on WebGL. Android uses a compressed .apk file. These platforms return a URL. Use the UnityWebRequest class to access the Assets.
Example using UnityWebRequestTexture
private void Start()
{
StartCoroutine(GetTexture());
}
private IEnumerator GetTexture()
{
// in general I would always avoid to have spaces in file-paths
var path = Path.Combine(Application.streamingAssetsPath, "QuestionImages", "exampleImage.png");
using(var www = UnityWebRequestTexture.GetTexture(path))
{
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError)
{
Debug.LogErrorFormat(this, "Unable to load texture due to {0} - {1}", www.responseCode, www.error);
}
else
{
Texture myTexture = ((DownloadHandlerTexture)www.downloadHandler).texture;
}
}
}
Note: Typed on smartphone so no warrenty but I hope the idea gets clear.
I have a cordova app up and running where I have an expansion file that is hosting a lot of pdf documents. I want to be able to open a pdf file from that expansion file and convert the entire file into a base 64 string in order to print that pdf from my app. I am trying to use this cordova plugin: https://github.com/sarahgoldman/cordova-print-pdf-plugin which is great, but there is no explanation on how to actually create the base 64 string.
I have attempted to use
var files = new File([""], "filename.pdf",{type:'application/pdf'});
console.log(files);
if (files.length > 0) {
getBase64(files[0]);
}
});
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
where the filename.pdf is stored in my expansion file but I don't get a proper response from the code.
any help would be greatly appreciated.
Thank you,
You're really asking two questions in one.
Expansion Files in Cordova
To get at the content of your expansion file, I suggest this cordova plugin:
https://github.com/agamemnus/cordova-plugin-xapkreader/tree/cordova-6.5.0
it facilitates accessing files inside of the expansion file so you can do something like this:
<img src="content://com.test.expansion/myfile.png">
Key is to follow the installation instructions to the point because this plugin requires more work than most of the other ones I've installed.
Base64 Encoding in Javascript
look at the btoa() and atob() functions. They convert text to and from base64 encoding.
Feed your PDF content to the function and hand that over to the pdf plugin.
I'm using AIDE (A code editor / IDE & compiler which runs on Android) to write an Android app, and I want to add some assets to my project, specifically a HTML file plus associated CSS and JavaScript files, to be displayed in a WebView.
I've put my assets (a HTML file) in projectDirectory/app/src/main/assets/htmlfile.html, but, when I use the code below to load it in WebView, it shows "File not found". The exact same thing works fine in Android Studio.
Where do I put this assets folder for AIDE to pick up its contents ?
Here is my code where I'm loading the WebView, although I don't think there's anything wrong here, as it works in Android Studio.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
setContentView(webView);
webView.loadUrl("file:///android_asset/htmlfile.html");
}
What I've tried:
Placing it in /app/src/main/assets/htmlfile.html (The usual location, which works in Android Studio).
In /app/src/main/res/assets/htmlfile.html
In /app/src/assets/htmlfile.html
Pretty much everywhere else.
However, wherever I put it and recompile, the WebView always shows "File not found". So where do I put my assets folder for it to work with AIDE, or how do I make AIDE pick it up when compiling ? Does AIDE support assets at all ?
Doh: All I needed to do was menu > more > project > refresh build, with the assets in /app/src/main/assets/htmlfile.html and it worked. Somewhat non-obvious, but hey, solved my problem.
Leaving this self answer in case anyone else has the same problem.
As for an html keep it in app->src->main->assets
And later on you can acces it like "file:///android_asset/error.html"
Lets take example of a webview wv1. You can write
wv.loadUrl("file:///android_asset/error.html");
Dont forget to rebuild your project. This is a safety measure in such case. Many times files are not included automatically
I have some level definitions in xml format (with .txt extension) inside (without any subfolders) my project's rescources folder
I for more scalability, I have a plain text file naming all these level definition XMLs
I read that file using
TextAsset WorldList = (TextAsset)Resources.Load("WorldList");
And then I load the needed world:
TextAsset TA = (TextAsset)Resources.Load(/*"LevelDefs/" +*/ Worlds[worldToload]);
xps.parseXml(TA.text);
loadLevel(levelToLoad);
(you see that I have moved these rescources out of subfolder to reduce the chance of them not loading)
worldToload here is the index number of that world
program works fine on windows but nothing loads on my android test device.
I seem to have problems debugging on device so I only guess something went wrong in loading phase.
any suggestions?
From Unity Documentation:
Most assets in Unity are combined into the project when it is built.
However, it is sometimes useful to place files into the normal
filesystem on the target machine to make them accessible via a
pathname. An example of this is the deployment of a movie file on iOS
devices; the original movie file must be available from a location in
the filesystem to be played by the PlayMovie function.
Any files placed in a folder called StreamingAssets in a Unity project
will be copied verbatim to a particular folder on the target machine.
You can retrieve the folder using the Application.streamingAssetsPath
property. It’s always best to use Application.streamingAssetsPath to
get the location of the StreamingAssets folder, it will always point
to the correct location on the platform where the application is
running.
So below snippet should work:
// Put your file to "YOUR_UNITY_PROJ/Assets/StreamingAssets"
// example: "YOUR_UNITY_PROJ/Assets/StreamingAssets/Your.xml"
if (Application.platform == RuntimePlatform.Android)
{
// Android
string oriPath = System.IO.Path.Combine(Application.streamingAssetsPath, "Your.xml");
// Android only use WWW to read file
WWW reader = new WWW(oriPath);
while ( ! reader.isDone) {}
realPath = Application.persistentDataPath + "/Your"; // no extension ".xml"
var contents = System.IO.File.ReadAll(realPath);
}
else // e.g. iOS
{
dbPath = System.IO.Path.Combine(Application.streamingAssetsPath, "Your.xml");
}
Thanks to David I have resolved this problem.
for more precision I add some small details:
1-As David points out in his answer (and as stated in unity documentations), we should use StreamingAssets if we want to have the same folder structure. One should use Application.streamingAssetsPathto retrieve the path.
However, files are still in the apk package in android's case, so they should be accessed using unity android's www class.
a good practice here is to create a method to read the file (even mandatory if you are going to read more than one file)
here is one such method:
private IEnumerator LoadDataFromResources(string v)
{
WWW fileInfo = new WWW(v);
yield return fileInfo;
if (string.IsNullOrEmpty(fileInfo.error))
{
fileContents = fileInfo.text;
}
else
fileContents = fileInfo.error;
}
This is a coroutine, and to use it we need to call it using
yield return StartCoroutine(LoadDataFromResources(path + "/fileName.ext"));
Yet another remark: we can not write into this file or modify it as it's still inside the apk package.
I'm creating an app for Air 3.8 on Flash CS6. When I click on info_btn, the programm load an external textfile (here test.txt) and shows it in my dynamic text field (here info_txt).
It works when I CRTL+Enter, but not on my android device when I test the .apk file I created. I'm sure the reason is that the test.txt is not compiled in the apk, but I don't know how to change that. If you guys can help, it would be great.
Here is my code, if it can help:
var fl_TextLoader_3:URLLoader = new URLLoader();
var fl_TextURLRequest_3:URLRequest = new URLRequest("textes/test.txt");
fl_TextLoader_3.addEventListener(Event.COMPLETE, fl_CompleteHandler_3);
function fl_CompleteHandler_3(event:Event):void
{
var textData:String = new String(fl_TextLoader_3.data);
info_txt.text = textData;
}
info_btn.addEventListener(MouseEvent.CLICK, fl_infotxt);
function fl_infotxt(Event:MouseEvent):void {
fl_TextLoader_3.load(fl_TextURLRequest_3);
}
Usually mobile AIR projects will have an assets folder -- they do in Flash Builder and Flash Develop IDEs, so I assume CS6 has something similar.
The assets folder is where images and app icons go that will be delivered in the .apk. You can put any files and folders you want in there, including your text files. To package your text file into the .apk, you could create a assets/textes folder and put your test.txt in it.
Then the URL you would need in your code would be:
var fl_TextURLRequest_3:URLRequest = new URLRequest("assets/textes/test.txt");