Friday, April 4, 2014

Sending touch event to the android device by using monkeyrunner



Using the monkeyrunner, you can control the device with connected on a pc.
It is contained in the android sdk from google.

http://developer.android.com/tools/help/monkeyrunner_concepts.html


Preparation

  1. Install android sdk (recent version, maybe?)
  2. Turn on the debugging option of the device

  3. If DOWN_AND_UP is not working well,
    Settings >  Pointer speed > Lower the speed


Write following python for the first try.

# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection()
# Presses the Menu button
device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)
# Touches (x, y) position
device.touch(x, y, MonkeyDevice.DOWN_AND_UP)

Connect your device to your pc, confirm it is well being debugging.
Type the following script.
$ adb devices

If it is well connected, it will reply device's some string.

To confirm that the touch is working well, I suggest you run some paint app first such as Sketchbook express, Evernote skitch.

With the device connected to the pc, run monkeyrunner with your python script.

<android sdk directory>/tools/monkeyrunner <your script>.py

(x, y) position is dependent on your device's resolution (pixel coordination).
(500, 500) is ok, I think.

If you want to know exact position of the device, turn some settings on.

  1. Developer options > Input > Show touches CHECK
  2. Developer options > Input > Pointer location CHECK
With this setting, you can check the exact coordinate of the location when you touch somewhere.
Location will be shown on the top of the screen.














Sunday, March 9, 2014

Parse.com android push notifications


It seems to work for sending simple pushes to both android, ios devices.
Installation special object seems to be used to send a certain segment of devices.

https://parse.com/tutorials/android-push-notifications

The Parse library provides push notifications by using Google Cloud Messaging (GCM) if possible. On devices that do not support GCM (such as the Amazon Kindle Fire), Parse will use a background service that maintains a persistent connection to the Parse Cloud to deliver pushes. This allows Parse Push to work on all devices running Android 2.2 or higher.


Some push features are available only for pro users.


Global Push opens metrics Visualize how often your app is opened because of a push notification you sent.
Advanced Push Targeting Ability to perform advanced targeting in the Parse Push console.
Push Scheduling Ability to schedule pushes in the Parse Push console.


Thursday, February 6, 2014

multithreading MessagePack usage without java PermGen memory error


If you use new MessagePack() too many time, perm gem memory error occurs soon.

MessagePack msgpack = new MessagePack();
byte[] bytes = msgpack.write(object);

You can test this with
-XX:+TraceClassLoading -XX:+TraceClassUnloading
VM parameters or JConsole.

[Loaded learningtest.msgpack.MessagePackTest$MyMessage_$$_Template_1527741453_0 from __JVM_DefineClass__]
MyMessage [name=msgpack, version=0.6]
[Loaded learningtest.msgpack.MessagePackTest$MyMessage_$$_Template_831556519_0 from __JVM_DefineClass__]
MyMessage [name=msgpack, version=0.6]
[Loaded learningtest.msgpack.MessagePackTest$MyMessage_$$_Template_1872305359_0 from __JVM_DefineClass__]
MyMessage [name=msgpack, version=0.6]

MessagePack.write()
TemplateRegistry.lookup()
TemplateRegistry.lookupAfterBuilding()
TemplateRegistry.buildAndRegister()
AbstractTemplateBuilder.buildTemplate()
DefaultBuildContext.buildTemplate()
BuildContext.build()
BuildContext.createClass()
CtClass.toClass()


But, writing with the MessagePack instance is not thread-safe.
msgpack.setOutputStream(outputStream);
msgpack.write(object);

Insteads, you can should the packer and the unpacker from a singleton MessagePack instance

MessagePack msgpack = new MessagePack(); // singleton
Packer packer = msgpack.createPacker(outputStream); // createPacker every time
packer.write(object);

for (int i = 0; i < 100; i++) {
final int iTask = i;
tasks.add(new Thread() {

@Override
public void run() {
try {
System.out.println(iTask + " start ");
File file = new File("eraseme" + iTask);
FileOutputStream outputStream = null;

outputStream = new FileOutputStream(file);
SomeClass info = new SomeClass();
try {
packer.write(info);
catch (IOException e) {
System.out.println(iTask + " write failed " + e.getMessage());
assertTrue(false);
}
outputStream.close();
FileInputStream inputStream = new FileInputStream(file);
Unpacker unpacker = msgpack.createUnpacker(inputStream);
// Deserialize directly using a template
SomeClass reply = null;
try {
reply = (ReplyMessage.ImageInfoMessage) unpacker.read(SomeClass.class);
catch (IOException e) {
System.out.println(iTask + " read failed " + e.getMessage());
assertTrue(false);
}
System.out.println(iTask + " finished " + reply + " " + file.getAbsolutePath());
catch (Exception exc) {
System.out.println("exc " + exc.getMessage());
assertTrue(false);
}
};
});
}
for (Thread task : tasks) {
task.start();
}
for (Thread task : tasks) {
task.join();
}

assertTrue(true);


Or, we should use pool of MessagePack instances.
I suggest the apache commons pool.
http://commons.apache.org/proper/commons-pool/