phonegap custom plugin for android advice needed - android

Hi I am in mobile app.
I have developed an app in phonegap (html5, JQuery, JS) and I want to develop a plugin to print to a BT printer.
I download printer manufacturer's SDK and I imported the appropriate .jar file to my project with the following way:
To include this library into your project:
Drag the appropriate library file into the Project Explorer from the SDK package
Right click the project folder and choose Properties
Click Java Build Path
Click Libraries and the Add JARs button
At the top of your main code add:
import com.starmicronics.stario.StarIOPort;
import com.starmicronics.stario.StarIOPortException;
import com.starmicronics.stario.StarPrinterStatus;
Now you can access all of StarIO’s methods!
I create the following plugin
js
var HelloPlugin = {
callNativeFunction: function (success, fail, resultType) {
return cordova.exec(success, fail, "com.tricedesigns.HelloPlugin", "nativeAction", [resultType]);
}
};
java
package com.tricedesigns;
import com.starmicronics.stario.StarIOPort;
import com.starmicronics.stario.StarIOPortException;
import com.starmicronics.stario.StarPrinterStatus;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.util.Log;
public class HelloPlugin extends Plugin {
public static final String NATIVE_ACTION_STRING="nativeAction";
public static final String SUCCESS_PARAMETER="success";
public static final String portName = "BT:";
public static final String portSettings = "mini";
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
Log.d("HelloPlugin", "Hello, this is a native function called from PhoneGap/Cordova!");
//only perform the action if it is the one that should be invoked
if (NATIVE_ACTION_STRING.equals(action)) {
String resultType = null;
try {
resultType = data.getString(0);
}
catch (Exception ex) {
Log.d("HelloPlugin", ex.toString());
}
byte[] texttoprint = resultType.toString().getBytes();
if (resultType.equals(SUCCESS_PARAMETER)) {
StarIOPort port = null;
return new PluginResult(PluginResult.Status.OK, "Yay, Success!!!");
}
else {
return new PluginResult(PluginResult.Status.ERROR, "Oops, Error :(");
}
}
return null;
}
}
which is working with no promblems.
When i try to include the below call to printer .jar method
port = StarIOPort.getPort(portName, portSettings, 10000, context);
I get Error: Status=2 Message=Class not found.
Where am i wrong????

Related

How can I import a lib file? scanner occur FileNotFoundException

I am getting the following error:
scan = new Scanner(new File("file:///android_lib/"+StationNM+".csv"));
I have 아현.csv in the lib folder, but android throws FileNotFoundException.
how can I solve this? adfasdfa
my source is
mport java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Scanner;
import java.lang.Object;
public class model {
public float modelPredict(String StationNM, String UPandDOWN, int day, int hour, int minute)
{
Scanner scan = null;
try {
scan = new Scanner(new File("file:///android_lib/"+StationNM+".csv"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
ArrayList<String[]> records = new ArrayList<String[]>();
ArrayList<Integer> model_list = new ArrayList<Integer>();
while (scan.hasNext()) {
String[] record;
record = scan.nextLine().split(",");
records.add(record);
}
}
this issue was solved
scan = new Scanner(new File("file:///android_lib/"+StationNM+".csv"));
The File constructor takes filesystem paths. What you are passing:
Is not a filesystem path, as paths do not have schemes like file:// or http:// or content://
Refers to a non-existent directory on the filesystem
I have 아현.csv in the lib folder
Put it in src/main/assets/ of your module. Pass in an AssetManager to your modelPredict() method, and use open() on AssetManager to get an InputStream that you can pass to the Scanner constructor. You get an AssetManager by calling getAssets() on a Context, such as your Activity or Service.

How to migrate a jzy3d java project into android?

I followed jzy3d's demo and made a 3D plot model with AnalysisLauncher.open() in IntelliJ, win10. It's working great. Now I need to migrate to Android so that the model can be displayed in a mobile application.
What kind of change is needed for my code? A sample project with any jzy3d surface plot would be ideal.
I read the page How to use jzy3d in android using eclipse?. The idea seems promising because jzy3d relies on JOGL 2 and OpenGL is cross-platform API. But I couldn't understand all the instructions by #Martin. Namely how do I replace AWT and 'derive CanvasNewtAwt'? I have no idea how to start the project in Android Studio.
The jzy3d website(http://www.jzy3d.org/) also says 'Android supposed to work if enable approte JOGL jars'. How do I do this?
import MyColorMap.ColorMapGrayColor;
import org.jzy3d.analysis.AbstractAnalysis;
import org.jzy3d.analysis.AnalysisLauncher;
import org.jzy3d.chart.factories.AWTChartComponentFactory;
import org.jzy3d.colors.Color;
import org.jzy3d.colors.ColorMapper;
import org.jzy3d.colors.colormaps.ColorMapGrayscale;
import org.jzy3d.colors.colormaps.IColorMap;
import org.jzy3d.maths.Coord3d;
import org.jzy3d.plot3d.primitives.Point;
import org.jzy3d.plot3d.primitives.Polygon;
import org.jzy3d.plot3d.primitives.Shape;
import org.jzy3d.plot3d.rendering.canvas.Quality;
public class ChartPlot extends AbstractAnalysis {
private int unitSize;
private BufferedImage img;
public static void main(String[] args) throws Exception {
AnalysisLauncher.open(new ChartPlot("Forest.jpg", 10));
}
ChartPlot (String imgName, int unitSize) {
img= getImg(imgName);
this.unitSize= unitSize;
}
#Override
public void init() {
int[][][] xycoords= getXYCoords(img, unitSize);
float[][][] zcoords= getZCoords(img, unitSize);
List<Polygon>[] polygonsArray= (List<Polygon>[])new List[COUNT_COLOR];
for (int iColor=0; iColor < polygonsArray.length; iColor++) {
polygonsArray[iColor]= getPolygons(xycoords, zcoords, iColor);
}
IColorMap[] colorMaps= new IColorMap[] {new ColorMapGrayscale(), new ColorMapGrayColor(ColorMapGrayColor.RED),
new ColorMapGrayColor(ColorMapGrayColor.YELLOW), new ColorMapGrayColor(ColorMapGrayColor.BLUE),
new ColorMapGrayscale()};
Shape[] surfaces= new Shape[COUNT_COLOR];
for (int iColor= 0; iColor < surfaces.length; iColor++) {
surfaces[iColor]= iColor == INDEX_WHITE || iColor == INDEX_BLACK ?
getSurface_Global(polygonsArray[iColor], colorMaps[iColor]) :
getSurface_Local(polygonsArray[iColor], colorMaps[iColor]);
}
chart = AWTChartComponentFactory.chart(Quality.Advanced, getCanvasType());
chart.getScene().getGraph().add(surfaces[INDEX_BLACK]);
chart.getScene().getGraph().add(surfaces[INDEX_RED]);
chart.getScene().getGraph().add(surfaces[INDEX_YELLOW]);
chart.getScene().getGraph().add(surfaces[INDEX_BLUE]);
chart.getScene().getGraph().add(surfaces[INDEX_WHITE]);
}

fileName.java:1 error ';' expected - Visual Studio Cordova Build with Android plugin

I have used the plugman command from the tutorial
. It has created the necessary files for a test plugin which I have not amended. I have added the plugin to my cordova visual studio project using the Plugins tab of config.xml to this local plugin. When I build I get the error
Severity Code Description Project File Line Suppression State
Error C:\Users\tonyh\OneDrive\Documents\Visual Studio 2015\Projects\AmILateTestDelete\AmILateTestDelete\platforms\android\src\cordova-plugin-am-i-late\AmILate\AmILate.java:1: error: ';' expected AmILateTestDelete 1
package cordova-plugin-am-i-late;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* This class echoes a string called from JavaScript.
*/
public class AmILate extends CordovaPlugin {
#Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("coolMethod")) {
String message = args.getString(0);
this.coolMethod(message, callbackContext);
return true;
}
return false;
}
private void coolMethod(String message, CallbackContext callbackContext) {
if (message != null && message.length() > 0) {
callbackContext.success(message);
} else {
callbackContext.error("Expected one non-empty string argument.");
}
}
}
Has anyone encountered this problem ?
Many thanks.
Tony
Your package name contains hyphens (-), which aren't valid characters in an identifier name (they can be confused with a subtraction/- operation). Try removing those and your file should compile.

flask-socketio doesn't allow connection from android device

Ok so I am following these tutorials to build a socketIO server using flask-socketIO and a client app for android devices. My python setup is pretty simple:
Python server:
init.py:
from flask import Flask, render_template
from flask.ext.socketio import SocketIO, emit
import logging
from os import getcwd
from datetime import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
def openDir(folder):
import os, errno
try:
os.makedirs(folder)
except OSError, e:
if e.errno != errno.EEXIST:
raise
openDir('logs')
def fileAndChannelLogger(file_location,name):
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler("".join([getcwd(),'/',file_location,'/',datetime.today().strftime("%Y%m%d_%H_%M"),"_",name,".log"]))
fh.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s | %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
logger.addHandler(fh)
logger.addHandler(ch)
return logger
logger = fileAndChannelLogger('logs', 'test')
#app.route('/')
def index():
logger.debug("Someone accessed the root page")
return render_template('index.html')
#socketio.on('connect', namespace='/test')
def test_connect():
logger.debug('Client connected')
#socketio.on('new message', namespace='/test')
def new_message(message):
logger.debug(message)
#socketio.on('disconnect', namespace='/test')
def test_disconnect():
logger.debug('Client disconnected')
run.py
from app import app, socketio
if __name__ == '__main__':
socketio.run(app,host='My_cool_host_name')
Android client:
MainActivity.java
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.net.URISyntaxException;
import java.util.Objects;
import com.github.nkzawa.emitter.Emitter;
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import org.json.JSONException;
import org.json.JSONObject;
import static android.app.PendingIntent.getActivity;
public class MainActivity extends Activity implements View.OnClickListener {
EditText userID;
EditText statement;
private Socket mSocket;
{
try {
mSocket = IO.socket("http://My_cool_host_name:5000/test");
} catch (URISyntaxException e) {}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSocket.connect();
Button send = (Button) findViewById(R.id.sendBtn);
send.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
String ID_data = userID.getText().toString();
String statement_data = statement.getText().toString();
if (TextUtils.isEmpty(ID_data)) {
return;
}
if (TextUtils.isEmpty(statement_data)) {
return;
}
statement.setText("");
JSONObject json = new JSONObject();
try {
json.put("user",ID_data);
} catch (JSONException e) {
e.printStackTrace();
}
try {
json.put("statement",statement_data);
} catch (JSONException e) {
e.printStackTrace();
}
mSocket.emit("new message",json);
}
}
Basically it takes in two edit boxes and then passes the info off to the server, nothing super fancy, just enough to get the basic groundwork of how this all works. I start the server, I can see the index.html from my browser when I go to the address with the specified port, when I run the client app in my an emulated device I get this error in the console:
* Running on http://My_cool_host_name:5000/
2015-08-05 22:37:31,311 - DEBUG | Someone accessed the root page
192.168.1.163 - - [2015-08-05 22:37:31] "GET / HTTP/1.1" 200 210 0.022884
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/gevent/pywsgi.py", line 508, in handle_ one_response
self.run_application()
File "/usr/lib/python2.7/site-packages/gevent/pywsgi.py", line 494, in run_app lication
self.result = self.application(self.environ, self.start_response)
File "/usr/lib/python2.7/site-packages/flask_socketio/__init__.py", line 27, i n __call__
raise RuntimeError('You need to use a gevent-socketio server.')
RuntimeError: You need to use a gevent-socketio server.
{'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT_ENCODING': 'gzip',
'HTTP_CONNECTION': 'Keep-Alive',
'HTTP_HOST': 'My_cool_host_name:5000',
'HTTP_USER_AGENT': 'Dalvik/2.1.0 (Linux; U; Android 5.1; Android SDK built for x86 Build/LKY45)',
'PATH_INFO': '/socket.io/',
'QUERY_STRING': 'EIO=3&transport=polling',
'REMOTE_ADDR': '192.168.1.163',
'REMOTE_PORT': '57754',
'REQUEST_METHOD': 'GET',
'SCRIPT_NAME': '',
'SERVER_NAME': 'server_name',
'SERVER_PORT': '5000',
'SERVER_PROTOCOL': 'HTTP/1.1',
'SERVER_SOFTWARE': 'gevent/1.0 Python/2.7',
'wsgi.errors': <open file '<stderr>', mode 'w' at 0x7f344d15b1e0>,
'wsgi.input': <gevent.pywsgi.Input object at 0x7f34461ddd10>,
'wsgi.multiprocess': False,
'wsgi.multithread': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http',
'wsgi.version': (1, 0)} failed with RuntimeError
192.168.1.163 - - [2015-08-05 22:39:08] "GET /socket.io/?EIO=3&transport=polling HTTP/1.1" 500 161 0.010306
As you can see it says something about
You need to use a gevent-socketio server.
But I thought I could just run it like this, do I need to turn around and shuffle this behind a gevent-socketio server just for this simple test? If so can someone recommend a direction? These are my installed python libraries:
alembic==0.6.2
Babel==1.3
Beaker==1.7.0.dev0
BeautifulSoup==3.2.1
blinker==1.3
decorator==3.4.0
Flask==0.10.1
Flask-Babel==0.9
Flask-Bootstrap==3.0.3.1
Flask-Login==0.2.9
Flask-Mail==0.9.0
Flask-Migrate==1.1.0
Flask-Mobility==0.1.1
Flask-Passlib==0.1
Flask-Script==0.6.6
Flask-Scrypt==0.1.3.1
Flask-SocketIO==0.6.0
Flask-SQLAlchemy==1.0
Flask-WhooshAlchemy==0.55a0
Flask-WTF==0.9.4
flup==1.0.2
gevent==1.0
gevent-socketio==0.3.6
gevent-websocket==0.9.2
greenlet==0.4.2
itsdangerous==0.24
Jinja2==2.8
lxml==3.4.4
Mako==0.9.1
MarkupSafe==0.23
MySQL-python==1.2.5
netsnmp-python==1.0a1
numpy==1.9.2
parse==1.6.3
passlib==1.6.2
pycrypto==2.6.1
python-dateutil==2.4.2
pytz==2013.9
PyYAML==3.11
scipy==0.15.1
scrypt==0.6.1
selenium==2.45.0
six==1.9.0
speaklater==1.3
SQLAlchemy==0.7.10
sqlalchemy-migrate==0.7.2
team==1.0
Tempita==0.5.1
Twisted==15.2.1
ujson==1.33
uWSGI==2.0.10
Werkzeug==0.10.4
Whoosh==2.5.6
WTForms==1.0.5
XlsxWriter==0.7.3
yamlog==0.9
zope.interface==4.1.2
Any help would be greatly appreciated, thanks.
Sadly,I also meet the same problems and doesn't know how to solve it. While waiting for some's answer here, I try another library https://github.com/koush/AndroidAsync, and luckily it works. Maybe you can have a try.
I had a similar issue, and it wound up being about the encoding that flask-socketio uses when communicating with Android. Try:
mSocket = IO.socket("http://My_cool_host_name:5000/test?b64=1");
See this thread for more details:

Playing AAC streams with Adobe AIR in Android/iOS

Looks like it's a pretty common trouble but I still can't see any solution.
The goal is to play some AAC stream in Adobe AIR mobile app.
I've used a transcoder from https://code.google.com/p/project-thunder-snow/. The one adds FLV headers to AAC data so the stream can be played through a standard AS3 NetStream object (as I understand). It works fine for Win and Mac, but the same app launched on Android or iOS produces neither sound nor any error. I've figured out that transcoder works fine, the cause is in the different
characteristics of NetStreams.
So, is there any solution or, at least, any documentation describing the difference between the NetStreams on PC and mobile platform?
okay... I might have a clue for you. I tried running the NBAAC code link you posted on the other question from inside Flash CS5 and got this error:
onChannelReady : MetaData
Error: Error #2067: The ExternalInterface is not available in this container. ExternalInterface requires Internet Explorer ActiveX, Firefox, Mozilla 1.7.5 and greater, or other browsers that support NPRuntime.
So it seems the player is designed to be used only inside an html page & uses ExternalInterface (Javascript) for getting metadata from browser into SWF
I removed the ExternalInterface stuff and it played ok in Flash Player & Device Central without browser/HTML. Try this code in your AIR app (I don't have AIR installed anymore to confirm..)
package
{
import com.thebitstream.flv.CodecFactory;
import com.thebitstream.flv.Transcoder;
import com.thebitstream.flv.codec.*;
import com.thebitstream.ice.*;
import com.thebitstream.nsv.*;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
//import flash.external.externalInterface;
import flash.media.SoundTransform;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.NetStreamAppendBytesAction;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLStream;
import flash.utils.ByteArray;
import flash.utils.setTimeout;
[SWF (width="250",height="250")]
public dynamic class NBAAC_AIR_v2 extends Sprite
{
public var request:URLRequest;
public var transcoder :Transcoder
public var transport :NetConnection;
public var transportStream :NetStream;
public var serverConnection:URLStream;
//public var host:String=" "; //now not used in line... request=new URLRequest(resource);
public var resource:String="http://aacplus-ac-64.timlradio.co.uk/;"; //test station
public function NBAAC_AIR_v2 ()
{
super();
/*
if(loaderInfo.parameters.host)
host=loaderInfo.parameters.host;
if(loaderInfo.parameters.resource)
resource=loaderInfo.parameters.resource;
*/
//CodecFactory.ImportCodec(MetaData);
CodecFactory.ImportCodec(AAC);
CodecFactory.ImportCodec(AACP);
transcoder = new Transcoder();
transcoder.addEventListener(CodecEvent.STREAM_READY,onChannelReady);
transcoder.addEventListener(StreamDataEvent.DATA, onTag);
transcoder.initiate();
transcoder.loadCodec("AAC");
transport = new NetConnection();
transport.connect(null);
flash.utils.setTimeout(boot,500);
}
public function boot():void
{
//externalInterface.addCallback('nbaac.setVolume', onVolume);
//externalInterface.addCallback('nbaac.togglePause', onTogglePause);
//externalInterface.addCallback('nbaac.setBuffer', setBufferLength);
//externalInterface.addCallback('nbaac.getBuffer', getBufferLength);
//externalInterface.addCallback('nbaac.getTime', getTime);
/*
var meta:Object={};
meta.uri="";
meta.StreamTitle="";
*/
//externalInterface.call('logit','start up');
transportStream = new NetStream(transport);
transportStream.bufferTime=2;
transportStream.client = this;
transportStream.soundTransform=new SoundTransform(.5,0);
transportStream.play(null);
transportStream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
var headerTag:ByteArray=transcoder.createHeader(false,true);
transportStream.appendBytes(headerTag);
headerTag.clear();
//transcoder.readMetaObject(meta,0);
serverConnection=new URLStream();
serverConnection.addEventListener(ProgressEvent.PROGRESS,loaded);
serverConnection.addEventListener(IOErrorEvent.IO_ERROR, onIo);
serverConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onNoPolicy);
serverConnection.addEventListener(Event.CLOSE, onClose);
request=new URLRequest(resource); //removed "host" from url
//request.requestHeaders=[new URLRequestHeader("GET",resource+" HTTP/1.0")];
//request.requestHeaders=[new URLRequestHeader("Icy-MetaData","1")];
request.method=URLRequestMethod.GET;
serverConnection.load(request);
}
private function getTime() :Number
{ return transportStream.time; }
private function getBufferLength() :Number
{ return transportStream.bufferLength; }
private function setBufferLength (val:Number) :void
{ transportStream.bufferTime = val; }
private function onTogglePause():void
{ transportStream.togglePause(); }
private function onVolume (val:Number) :void
{ transportStream.soundTransform = new SoundTransform(val, 0); }
private function onIo(pe:IOErrorEvent) :void
{ /* externalInterface.call('logit','IOErrorEvent') */ }
private function onTag(sde:StreamDataEvent) :void
{
sde.tag.position=0;
transportStream.appendBytes(sde.tag);
}
private function onChannelReady(ce:CodecEvent) :void
{ trace('onChannelReady :',ce.codec.type); }
private function onClose(e:Event):void
{ /* externalInterface.call('logit','onClose') */ }
public function onMetaData(e:Object):void
{ /* externalInterface.call('logit','onMetaData') */ }
private function loaded(e:ProgressEvent):void
{
var chunk:ByteArray=new ByteArray();
while(serverConnection.bytesAvailable)
{ chunk.writeByte( serverConnection.readByte() ); }
chunk.position=0;
transcoder.addRawData( chunk, 0, "AAC" );
}
private function onNoPolicy(se:SecurityErrorEvent):void
{ /* externalInterface.call('logit','SecurityErrorEvent'+host+resource+'<br />'+se.text); */ }
}
}

Categories

Resources