I know people have asked questions along these lines here, but I haven't found an answer that helps me.
I've made a simple game in pygame, I'm using RAPT to port it to android. I've gotten the game to compile and run successfully on my tablet. Great.
It goes something like this:
import android
android.init()
import pygame
pygame.init()
def main():
#does stuff for the game
The standard stuff.
But as soon as I add these lines below the import android:
enable = True
android.accelerometer_enable(enable)
or
android.check_pause()
or anything in the android module other than init(), the game refuses to run. ADB logcat shows that the code throws an AttributeError: 'module' object has no attribute of (whatever function I tried)
I've even tried copy-pasting code from https://github.com/codetricity/accel/blob/master/main.py
and trying to compile the example code given from the RAPT download page...
https://github.com/renpytom/rapt-pygame-example/blob/master/main.py
and it returns the same kind of errors once compiled.
What's going on?
In RAPT, accelerometer is seen as a 3-axis joystick. So you can use the pygame joystick module.
pygame.joystick.init()
num_joy_presenti = pygame.joystick.get_count()
accel = None
for i in range(num_joy_presenti):
generico_joy = pygame.joystick.Joystick(i)
generico_joy.init()
if generico_joy.get_name() == "Android Accelerometer":
accel = pygame.joystick.Joystick(i)
accel.init()
Then, "accel" will be your accelerometer and you can use the joystick module to get its values. Documentation here http://www.pygame.org/docs/ref/joystick.html#pygame.joystick.Joystick
Instead of android.check_pause you can detect pygame.APP_WILLENTERBACKGROUND and pygame.APP_WILLENTERFOREGROUND events as in the example at https://github.com/renpytom/rapt-pygame-example/blob/master/main.py
Related
I am pretty new to Appium, using UIAutomator2. Following instructions on the links:
[https://discuss.appium.io/t/click-back-button-on-android-device-in-java/6817/3][1]
[https://discuss.appium.io/t/click-back-button-twice-in-android-7-using-appium-uiautomator2/20368][2]
[https://stackoverflow.com/questions/30801879/how-to-automate-the-android-phone-back-button-using-appium][3]
I have tried all the options offered in these articles:
driver.pressKeyCode(4);
helper.driver.pressKeyCode(187);
driver.back();
driver.navigate().back();
If I add the imports
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;
and I try
driver.pressKeyCode(AndroidKeyCode.BACK);
Eclipse tells me that the method is undefined...
But none of them have worked. Is there anything I need to import or any additional classes I need to create? My driver only has methods for testing, such as close(), equals(), execute(), findElement()... but nothing like back(), or pressKeyCode() or navigate()(this one, probably, because it is not webView)... So, when I try to just type any of those methods, Eclipse either suggests to add a cast, or to create a class...
Please, Can anyone give me some more details on how to do it?
The driver should be an Appium driver. And try to run on real device than emulators.
driver = new AppiumDriver<>(url, desiredCapabilities);
I'm doing digital signal processing work in R using R Studio and think it would be a neat idea to expand this into an Android app. I know people have used Kivy to develop Android Apps in Python and I know it's possible to wrap R code in Python, so is this feasible? I read that it's possible to run R code on Android, just not sure if adding it to my project is a possibility. I also don't need to have the entire app to be written in R. Are there any examples/documentation related to this?
Turns out you can! I've built a more complex app using Kivy and the rpy2 package, but I'll demonstrate a simple example here.
You can define your R code like so:
r_code.py
from rpy2.robjects.packages import SignatureTranslatedAnonymousPackage
r_code = """
add <- function(x, y) {
return(x + y)
}
"""
r_lib = SignatureTranslatedAnonymousPackage(r_code, "r_lib")
Your Kivy App will look something like this:
main.py
from kivy.app import App
from r_code import r_lib
class MainApp(App):
def build(self):
window = BoxLayout(orientation='vertical')
label = Label(text=str(r_lib.add(3, 4)[0]))
b.add_widget(label)
return b
if __name__ == "__main__":
MainApp().run()
And if you want to package this into an Android App, you can follow the directions from the official doc. If you run into an error with rpy2, you might have to install the correct version for your system from here.
Happy coding!
I use the randomforest estimator, implemented in tensorflow, to predict if a text is english or not. I saved my model (A dataset with 2k samples and 2 class labels 0/1 (Not English/English)) using the following code (train_input_fn function return features and class labels):
model_path='test/'
TensorForestEstimator(params, model_dir='model/')
estimator.fit(input_fn=train_input_fn, max_steps=1)
After running the above code, the graph.pbtxt and checkpoints are saved in the model folder. Now I want to use it on Android. I have 2 problems:
As the first step, I need to freeze the graph and checkpoints to a .pb file to use it on Android. I tried freeze_graph (I used the code here: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/tools/freeze_graph.py). When I call the freeze_graph in my mode, I get the following error and the code cannot create the final .pb graph:
File "/Users/XXXXXXX/freeze_graph.py", line 105, in freeze_graph
_ = tf.import_graph_def(input_graph_def, name="")
File "/anaconda/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/framework/importer.py", line 258, in import_graph_def
op_def = op_dict[node.op]
KeyError: u'CountExtremelyRandomStats'
this is how I call freeze_graph:
def save_model_android():
checkpoint_state_name = "model.ckpt-1"
input_graph_name = "graph.pbtxt"
output_graph_name = "output_graph.pb"
checkpoint_path = os.path.join(model_path, checkpoint_state_name)
input_graph_path = os.path.join(model_path, input_graph_name)
input_saver_def_path = None
input_binary = False
output_node_names = "output"
restore_op_name = "save/restore_all"
filename_tensor_name = "save/Const:0"
output_graph_path = os.path.join(model_path, output_graph_name)
clear_devices = True
freeze_graph.freeze_graph(input_graph_path, input_saver_def_path,
input_binary, checkpoint_path,
output_node_names, restore_op_name,
filename_tensor_name, output_graph_path,
clear_devices, "")
I also tried the freezing on the iris dataset in "tf.contrib.learn.datasets.load_iris". I get the same error. So I believe it is not related to the dataset.
As a second step, I need to use the .pb file on the phone to predict a text. I found the camera demo example by google and it contains a lot of code. I wonder if there is a step by step tutorial how to use a Tensorflow model on Android by passing a feature vector and get the class label.
Thanks, in advance!
UPDATE
By using the recent version of tensorflow (0.12), the problem is solved. However, now, the problem is that what I should pass to output_node_names ??? How can I get what are the output nodes in the graph ?
Re (1) it looks like you are running freeze_graph on a build of tensorflow which does not have access to contrib ops. Maybe try explicitly importing tensorforest before calling freeze_graph?
Re (2) I don't know of a simpler example.
CountExtremelyRandomStats is one of TensorForest's custom ops, and exists in tensorflow/contrib. As was pointed out, TF switched to including contrib ops by default at some point. I don't think there's an easy way to include the contrib custom ops in the global registry in the previous releases, because TensorForest uses the method of building a .so file that is included as a data file which is loaded at runtime (a method that was the standard when TensorForest was created, but may not be any longer). So there are no easily-included python build rules that will properly link in the C++ custom ops. You can try including tensorflow/contrib/tensor_forest:ops_lib as a dep in your build rule, but I don't think it will work.
In any case, you can try installing the nightly build of tensorflow. The alternative includes modifying how tensorforest custom ops are built, which is pretty nasty.
I am able to build an .apk, but after I install it on my android phone it simply crashes at startup. My thoughts for failing is that I am using 3rd party libraries e.g(beautifulsoup).
This is how my imports look in main.py:
from kivy.app import App
from kivy.properties import ListProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
import time, os, random, urllib2, re, cookielib as cj
from bs4 import BeautifulSoup as bs
from functools import partial
I'm running mavericks 10.9.3
Does it have something to do with buildozer.spec file?
I've tried adding BeautifulSoup to app requirements, but it doesn't change a thing.
Any help would be appreciated.
I ran into this problem as well, but I was (apparently) able to get everything working fine with a workaround. Since it doesn't look like you posted a logcat, I'll assume you ran into the same issue I did.
Yes, you do need to list beautifulsoup4 as a requirement in your spec. From looking into bs4's code, it looks like bs4 is willing to use any of several "builders." It supports HTMLParser, html5lib, or lxml. I have no idea why we can't load HTMLParser, but it's actually the least preferred library of the three, and if it weren't for the fact that there's no try block around the import, it seems that everything would work fine (as long as one of the other parsing libraries was available).
With this in mind, I included one of the other libraries, and I decided to hack the import process so that Python would pretend _htmlparser loaded okay :)
This article was instructive: http://xion.org.pl/2012/05/06/hacking-python-imports/
The end result was something like this:
import imp
import sys
class ImportBlocker(object):
def __init__(self, *args):
self.black_list = args
def find_module(self, name, path=None):
if name in self.black_list:
return self
return None
def load_module(self, name):
module = imp.new_module(name)
module.__all__ = [] # Necessary because of how bs4 inspects the module
return module
sys.meta_path = [ImportBlocker('bs4.builder._htmlparser')]
from bs4 import BeautifulSoup
I also added html5lib to the requirements in buildozer.spec.
Now, is this the right way to solve the problem? I don't know. The best approach would probably be to request that the author fix it. It might be as simple as to put the import in a try block. Nevertheless, this is the approach I've gone with for the moment, and it is at least an interesting exercise, and a way to test your app until a better fix comes along.
Additionally, I should warn you that I only did this recently, so I can't 100% guarantee that it won't cause any problems, but at a minimum, it's worked well enough to get my app running and scraping the particular website I was interested in. Good luck!
I understand that this question is some years old. I think the answer #Will gave was fantastic but unfortunately, in my case, I couldn't use it because html5lib was too slow for what I was making. So this is for reference; for anyone who absolutely must use the built-in parser. It's not pretty but it's fairly manageable.
The issue
After much investigation, I nailed down the cause of the problem. In the buildozer log, I noticed that there was a problem compiling the _htmlparser file with the log reading as follows (with my project path replaced with <project-path>):
Compiling <project-path>/.buildozer/android/platform/build/dists/mypackage/private/lib/python2.7/site-packages/bs4/builder/_htmlparser.py ...
SyntaxError: ("(unicode error) \\N escapes not supported (can't load unicodedata module)", ('<project-path>/.buildozer/android/platform/build/dists/mypackage/private/lib/python2.7/site-packages/bs4/builder/_htmlparser.py', 135, None, 'data = u"\\N{REPLACEMENT CHARACTER}"\n'))
Because it was failing to compile, it wasn't being included in the built apk file. So I looked at the file and at the line that was causing the problem: data = u"\N{REPLACEMENT CHARACTER}" which should actually be replaced by data = u"\ufffd"
Quick-fix
Now the easy way out would be to modify the file right in the package. You could just edit the file mentioned in the error above which should, in theory, work but it's not recommended because every time the package gets re-installed or the code gets built from another machine the problem will be back.
Marginally better fix
It would be nice if the fix was all packaged into our code, so drawing inspiration from #Will's answer, here is the code you would need to put in before your bs4 import:
import sys
class ImportFixer(object):
def __init__(self, mname):
self.mname = mname
def find_module(self, name, path=None):
if name == self.mname:
return self
return None
def load_module(self, name):
import _htmlparser as module
module.__name__ = name
return module
sys.meta_path = [ImportFixer('bs4.builder._htmlparser')]
from bs4 import BeautifulSoup
The main difference is that you need to copy the _htmlparser.py file from the bs4 package to your current directory and fix the before mentioned line data = u"\N{REPLACEMENT CHARACTER}" with data = u"\ufffd"
Then, every time the bs4 module is imported, the import is magically intercepted and the local file is used.
Warning: if you ever update Beautiful Soup, you may need to use a more recent _htmlparser.py file in your project with the same fix made as needed.
Final comment
If I made some typos, grammar mistakes or didn't make sense at all, keep in mind that I worked most of the weekend to fix this and quite frankly I'm not thinking straight. Comment if you have any questions and I'll reply and/or edit my answer when I get a chance.
I wrote an application using PyQt for Windwos/Linux and I want to port it to Android. Application is simple, has 2 levels of GUI and I do not want to implement touch functions, but to control application using USB keyboard.
I am using this project:
android-python27
to interpret my PyQt code for Android, but it doesn't work. I suppose that I have to modify code, but I do not know how. I only found one sample for using android-python27:
import android, time
droid = android.Android()
while 1:
droid.makeToast("Hello from Python 2.7 for Android")
time.sleep(5)
My application is being started in this way:
app = QtGui.QApplication(sys.argv)
app.Encoding(QtGui.QApplication.UnicodeUTF8)
ui = MainMenu()
class MainMenu(QtGui.QWidget):#glavni izbornik
def __init__(self):
super(MainMenu, self).__init__()
i=0
self.UI(self)
def UI(self, Form):
...
What should I change to adopt code to android-python27?