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,
Related
so I'm trying to set up an aws database and im following the tutorial for set up here : http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/getting-started-store-query-app-data.html
But none of the imports work! When i import the following:
import com.amazonaws.services.dynamodbv2.*;
import com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.*;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedScanList;
All of them have a red line error!
Here is my dependencies.
compile 'com.amazonaws:aws-android-sdk-core:2.3.3'
compile 'com.amazonaws:aws-android-sdk-cognito:2.3.3'
compile 'com.amazonaws:aws-android-sdk-s3:2.3.3'
compile('com.amazonaws:aws-android-sdk-mobileanalytics:2.3.3')
compile('com.amazonaws:aws-android-sdk-apigateway-core:2.3.3')
compile 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.3.3'
So because of this i cannot make the basic objects necessary to store data into my aws database... I get redline errors below. I hope you guys can help!
AmazonDynamoDBClient ddbClient = new AmazonDynamoDBClient(credentialsProvider);
DynamoDBMapper mapper = new DynamoDBMapper(ddbClient);
If you want to store data using DynamoDB, you need to give some permissions.
Set Permissions in Your Android Manifest
In AndroidManifest.xml, set the following permission, if it’s not already present
<uses-permission android:name="android.permission.INTERNET" />
A step by step storing data is given in the link: Store and Retrieve App Data in Amazon DynamoDB
Having read this documentation, I'm using this code...
import org.acra.ACRA;
import org.acra.annotation.ReportsCrashes;
import org.acra.ReportField;
#ReportsCrashes (
formUri = "http://example.com/crash-reports/emailer.php",
customReportContent = {ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, ReportField.STACK_TRACE, ReportField.LOGCAT},
sharedPreferencesName = "ACRA_SHARED_PREFS",
sharedPreferencesMode = Context.MODE_PRIVATE
)
...to specify what content to include in my ACRA reports.
I would like to know if/how it's possible to also specify the order of this content, as the content in the emails that are sent from my emailer.php script seems to be a bit random.
The ReportBuilder class in ACRA constructs the report. It does so in a deterministic fashion and the order is determine by the code in that class.
I am implementing my own auto-updater within my application. I was able to successfully download the .apk file of the newer version into the /Download folder on the sdcard, but I can't figure out how to open/run that file so the user is presented with the new installation dialog.
The only thing I could come up with:
QString downloadedAPK = "/storage/emulated/0/Download/latest.apk"; // Not hardcoded, but wrote it here this way for simplicity
QDesktopServices::openUrl(QUrl(downloadedAPK));
Debugger output:
D/Instrumentation(26418): checkStartActivityResult :Intent { act=android.intent.action.VIEW dat=file:///storage/emulated/0/Download/latest.apk }
D/Instrumentation(26418): checkStartActivityResult inent is instance of inent:
W/System.err(26418): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=file:///storage/emulated/0/Download/latest.apk }
W/System.err(26418): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1660)
W/System.err(26418): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1430)
W/System.err(26418): at android.app.Activity.startActivityForResult(Activity.java:3532)
W/System.err(26418): at android.app.Activity.startActivityForResult(Activity.java:3493)
W/System.err(26418): at android.app.Activity.startActivity(Activity.java:3735)
W/System.err(26418): at android.app.Activity.startActivity(Activity.java:3703)
W/System.err(26418): at org.qtproject.qt5.android.QtNative.openURL(QtNative.java:110)
W/System.err(26418): at dalvik.system.NativeStart.run(Native Method)
I have looked everywhere but never found anything regarding opening APKs from Qt. The only thing I found was a solutoin using JNI ( which I don't want to use because it's simpler to just do it with C++ and because I have zero experience with the whole C++/JNI thing ) and it was not well documented so I didn't understand how to make it work.
So, what would be the easiest way to open the downloaded apk?
Edit:
I have followed Tumbus's answer, but because of some compiling errors I had to make a few modifications on his JNI code as follows:
void Updater::InstallApp(const QString &appPackageName)
{
qDebug() << "[+] APP: " << appPackageName; // Which is the string ("/storage/emulated/0/Download/latest.apk")
QAndroidJniObject app = QAndroidJniObject::fromString(appPackageName);
QAndroidJniObject::callStaticMethod<jint>("AndroidIntentLauncher",
"installApp",
"(Ljava/lang/String;)I",
app.object<jstring>());
}
When I run my application on my android device, it pulls the newest .apk file from my server, then nothing happens. Why? (I have not made any changes on the AndroidManifest.xml until now).
You have to make a custom intent to install APK. See this question for details.
I'm afraid such platform-specific think must require calls to platform-specific API. The good news are Qt framework has simplified wrap-up on JNI and you can include a Java class into Android project. Therefore I would make my own static java function called from Qt.
Example
Java class
package io.novikov.androidintentlauncher;
import org.qtproject.qt5.android.QtNative;
import java.lang.String;
import java.io.File;
import android.content.Intent;
import android.util.Log;
import android.net.Uri;
import android.content.ContentValues;
import android.content.Context;
public class AndroidIntentLauncher
{
protected AndroidIntentLauncher()
{
}
public static int installApp(String appPackageName) {
if (QtNative.activity() == null)
return -1;
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(appPackageName)),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
QtNative.activity().startActivity(intent);
return 0;
} catch (android.content.ActivityNotFoundException anfe) {
return -3;
}
}
}
Notice that startActivity() should be called as a method from *QtNative.activity(). We have to maintain special directory structures for java according to conventional rules. The example is at Makefile section below.
JNI
The C++ code to call this method is a bit tricky.
const static char* MY_JAVA_CLASS = "io/novikov/androidintentlauncher/AndroidIntentLauncher";
static void InstallApp(const QString &appPackageName) {
QAndroidJniObject jsText = QAndroidJniObject::fromString(appPackageName);
QAndroidJniObject::callStaticMethod<jint>(MY_JAVA_CLASS,
"installApp",
"(Ljava/lang/String;)I",
jsText.object<jstring>());
}
The string literal "(Ljava/lang/String;)I" is the signature of java method.
The name of the Java class must be at a complete form "my/domain/my_app/MyClass"
Makefile
The last challenge is to include the java code to your project properly. Below the corresponding fragment of the .pro file.
android {
QT += androidextras
OTHER_FILES += android_src/src/io/novikov/androidintentlauncher/AndroidIntentLauncher.java
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android_src
}
QMake has a special variable ANDROID_PACKAGE_SOURCE_DIR for this job. Java sources must reside in ANDROID_PACKAGE_SOURCE_DIR/src/my/domain directories.
Also don't forget to add java source to OTHER_FILES and include androidextras QT option.
I am doing python exercise with a book 'headfirst python'
and making android app by using python and sl4a
my code is
import android
import json
import time
from urllib import urlencode
from urllib2 import urlopen
hello_msg = "Welcome to Coach Kelly's Timing App"
list_title = 'Here is your list of athletes:'
quit_msg = "Quitting Coach Kelly's App."
web_server = 'http://127.0.0.1:8080'
get_names_cgi = '/cgi-bin/generate_name.py'
def send_to_server(url, post_data=None):
if post_data:
page = urlopen(url, urlencode(post_data))
else:
page = urlopen(url)
return(page.read().decode("utf8"))
app = android.Android()
def status_update(msg, how_long=2):
app.makeToast(msg)
time.sleep(how_long)
status_update(hello_msg)
athlete_names = sorted(json.loads(send_to_server(web_server + get_names_cgi)))
app.dialogCreateAlert(list_title)
app.dialogSetSingleChoiceItems(athlete_names)
app.dialogSetPositiveButtonText('Select')
app.dialogSetNegativeButtonText('Quit')
app.dialogShow()
resp = app.dialogGetResponse().result
status_update(quit_msg)
this is my code and the result is
what is the problem???
I can not figure out what the problem is...
Use 10.0.2.2:8080
because If you are running both server and emulator in you computer 127.0.0.1:(port) the local IP will refer to the emulator then you need another local IP for the server which will be automatically The 10.0.2.2
hope i clearified it well, glad i helped
Having followed #Coderji 's solution, I was finally able to solve this problem albeit with a different IP address; since the suggested 10.0.2.2 didn't work for me.
What worked for me was to access a terminal, ipconfig, and then used any of the provided ipv4 addresses provided by cmd (all of them seemed to work). Cheers.
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.