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:
Related
I am baffled by what's happening.
I put the file name "Help" into the Extras of the Intent that I then immediately start. (There can't be any problems with this first code block. With breakpoint after putExtra, Watch expression helpIntent.getStringExtra(PACKAGE_NAME + ".filename") returned "Help".)
import static com.dslomer64.sqhell.BuildConfig.APPLICATION_ID;
...
public class MainActivity extends Activity
{
public final static String PACKAGE_NAME = APPLICATION_ID;
...
#Override public boolean onOptionsItemSelected(MenuItem item)
{
if(item.toString().equals("Help") || item.toString().equals("Acknowledgements"))
{
Intent
helpIntent;
helpIntent = new Intent(this, HelpActivity.class);
helpIntent.putExtra(PACKAGE_NAME + ".filename", item.getTitle().toString());
startActivity(helpIntent);
return true;
}
...
}
The fun begins in the spawned Intent:
public class HelpActivity extends Activity
{
...
public void showHelp(AssetManager assets, String filename)
{
try
{
////////////////////////////////////////////
// filename = null ********* #1
stream = assets.open(filename);
//////////////////////////////////////////// }
catch (IOException e) { e.printStackTrace(); }
...
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.w("`````Help", "onCreate--bundle info: " + bundle.toString()) ;
Log.w("`````Help","onCreate--bundle key: " + bundle.getString("filename") );
Bundle bundle = getIntent().getExtras();
setContentView(R.layout.activity_help);
////////////////////////////////////////////
String fn = bundle.getString((PACKAGE_NAME + ".filename"));
// fn = null ***************************** #2
////////////////////////////////////////////
showHelp(getAssets(), fn );
}
The first sign of trouble (#1) was "filename is empty". Tracing back was easy. Now we're at #2, where--just compare--I use the same basic syntax to try to get the filename "Help" out of the Extras of the Intent. But it's null.
I'm not an expert with Intent but I've successfully used one a few times in the past.
I guess if I supplied a compilable program that shows the error it would be easier. But ...
If nobody spots anything right off, I'll get on that.
But it's straightforward!
But not.
================
EDIT
I added 2 Log statements (see above) and got this output:
W/`````Help: onCreate--bundle info:
Bundle[{com.dslomer64.sqhell.filename=Help}]
//////////////////////////////////////^^^^
W/`````Help: onCreate--bundle key: null
Not sure how this helps since it looks like "Help" is where it should be. And I assume key is null is equivalent to the original problem about filename being null.
============================
EDIT #2: Here's the WHOLE HelpActivity class. If this doesn't help, I'll get on the compilable thing:
package com.dslomer64.sqhell;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
import android.widget.EditText;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import static android.provider.ContactsContract.Directory.PACKAGE_NAME;
public class HelpActivity extends Activity
{
Scanner scDict;
InputStream stream;
EditText help;
public void showHelp(AssetManager assets, String filename)
{
help = /*(EditText)*/ findViewById(R.id.txaHelp);
try
{
stream = assets.open(filename);
}
catch (IOException e) { e.printStackTrace(); }
scDict = new Scanner(stream).useDelimiter("\n\r\t ,.:;-( )"); // added (SPACE) recently
help.getText().clear();
while(scDict.hasNext())
help.append(scDict.next());
hideKeyboard();
help.setSelection(0);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle bundle = getIntent().getExtras();
setContentView(R.layout.activity_help);
Log.w("`````Help", "onCreate--bundle info: " + bundle.toString()) ;
Log.w("`````Help", "onCreate--bundle key: " + bundle.getString(PACKAGE_NAME + ".filename"));
String fn = bundle.getString(PACKAGE_NAME + ".filename");
showHelp(getAssets(), fn );
}
}
=========================
In following cricket's advice, I noticed a long line in the importarea:
import static android.provider.ContactsContract.Directory.PACKAGE_NAME;
I don't remember ever seeing such before. So I took it out and got a few errors, wherever PACKAGE_NAME was used. Since each line had the "red underline" indicating use keypress 'Alt-Enter' for an easy import construction, I found that I HAD TWO CHOICES: the one above and MainActivity.PACKAGE_NAME.
I assume the previous time I did this, I chose the wrong item to import.
All is well.
Spent... too long on this.
Thanks to all who helped and Cricket for steering me in the right direction.
=====================
FINAL EDIT:
All I needed to do all along was delete the long import statement. And also pay attention to what I selected after doing it.
Criminey.
I thought I was doing what Cricket suggested all along. Didn't get the funny import in other classes. Why here????
it looks like "Help" is where it should be.
It does
... key is null
Its actually the value, but you're getting the value of the key "filename", not PACKAGE_NAME + ".filename", which is what you used in the putExtra.
The keys don't match, so the value is null
Suggestion: define your own constant like
public static final String FILENAME_EXTRA = APPLICATION_ID + ".filename";
and use that in all classes
Additionally your Scanner and everything requiring the file to be opened should be inside the try block.
you put data in the Intent, not the Bundle.
So, try String fn = getIntent().getStringExtra(PACKAGE_NAME + ".filename").Then you will find what you want.
you are using a wrong key when retrieving the value.
Log.w("`````Help","onCreate--bundle key: " + bundle.getString(PACKAGE_NAME + ".filename") );
I have windows 7 which is connected to two android devices and I am using Selenium and Appium to automate an App but not able to run the test simultaneously in both the devices. below is the code I am using along with contents from testng.xml. let me know where I am wrong. The below code runs fine but it installs the app on first device then on second device what I want to acheive is install the app simultaneously on both the devices. Any help appreciated.
package ca.automation.com;
import org.testng.annotations.Test;
import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;
import io.appium.java_client.android.AndroidDriver;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class StackOverflow {
WebDriver driver1;
WebDriver driver2;
// ExtentReports report;
// ExtentTest logger;
// Boolean present;
File app = new File("App\\app_US_IT_Ananta.apk");
#BeforeSuite
public void startReport(){
// report=new ExtentReports("C:\\Anuj\\MobileAppResults.html");
}
#Test (priority =0)
public void installapp() {
// logger=report.startTest("VerifyAppInstalltion");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("udid", "1015fadb1a274005");
// capabilities.setCapability("udid", "ee92ba92");
capabilities.setCapability("deviceName","Android Emulator");
capabilities.setCapability("platformVersion", "4.4");
capabilities.setCapability("autoAcceptAlerts", true);
capabilities.setCapability("app", app.getAbsolutePath());
try {
driver1 = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
#Test (priority =0)
public void installapp1() {
DesiredCapabilities capabilities1 = new DesiredCapabilities();
capabilities1.setCapability("udid", "ee92ba92");
capabilities1.setCapability("deviceName","Android Emulator");
capabilities1.setCapability("platformVersion", "4.4");
capabilities1.setCapability("autoAcceptAlerts", true);
capabilities1.setCapability("app", app.getAbsolutePath());
try {
driver2 = new AndroidDriver(new URL("http://127.0.0.1:4730/wd/hub"), capabilities1);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
Testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests" thread-count="2">
<test name="Test">
<classes>
<class name="ca.automation.com.StackOverflow"/>
</classes>
</test> <!-- Test -->
Change parallel="tests" to parallel="methods" because you have to execute the methods in parallel, as its in your case.
Also, running tests in parallel wont be exactly 100% simultaneous execution. There would be some lag between execution in both devices. Try out a complete script with few more additional steps. That way we can easily make out that the tests are running simultaneously.
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); */ }
}
}
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????
Hi i am using the following code to parse a certificate details.Everything is fine except a bit problem mentioned below.
package android.net.http;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.security.cert.Certif`enter code here`icate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.util.Base64InputStream;
import android.util.Log;
public class SslCertificate1Activity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
String text = "-----BEGIN CERTIFICATE-----\n"+
"MIIC/TCCAmagAwIBAgIBKjANBgkqhkiG9w0BAQQFADCBqDEiMCAGA1UEAxMZeG1sZ2F0ZXdheS5p\n"+
"dHMudXRleGFzLmVkdTEoMCYGA1UECxMfSW5mb3JtYXRpb24gVGVjaG5vbG9neSBTZXJ2aWNlczEq\n"+
"MCgGA1UEChMhVGhlIFVuaXZlcnNpdHkgb2YgVGV4YXMgYXQgQXVzdGluMQ8wDQYDVQQHEwZBdXN0\n"+
"aW4xDjAMBgNVBAgTBVRleGFzMQswCQYDVQQGEwJVUzAeFw0wNDA1MDkwNTMwMTBaFw0wNTA1MDQw\n"+
"NTMwMTBaMIGAMQswCQYDVQQGEwJVUzEOMAwGA1UECBMFVGV4YXMxDzANBgNVBAcTBkF1c3RpbjEq\n"+
"MCgGA1UEChMhVGhlIFVuaXZlcnNpdHkgb2YgVGV4YXMgYXQgQXVzdGluMRMwEQYDVQQLEwpUb29s\n"+
"cyBUZWFtMQ8wDQYDVQQDEwZDbGllbnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ6PABjb\n"+
"zXUkgo29S4uv1Qz9reo1/tP4pkQTGAldSbtA4hVtA/3sjw2+u3kgxYruAi2cXV2k0RPZhsUZjlDk\n"+
"jMPb/dlY81bD8gqe3lu3ezugJrlArlpfWN6PlufbTjxHSqIA0XD9R5/ZECaUV9dD43K5KdWUCy99\n"+
"YKDiSwVPO9F5AgMBAAGjXTBbMB0GA1UdDgQWBBRkCCpscEXxXu8Ba67p6zdh13ypjzAfBgNVHSME\n"+
"GDAWgBR2RsZH2kSY782kBROo92FAWS6sADAJBgNVHRMEAjAAMA4GA1UdDwQHAwUBEiRIkDANBgkq\n"+
"hkiG9w0BAQQFAAOBgQCtV1NzpdVBs5vyb8yLXNA3hA1LsmE/2QanXG4T3UN93BI4HQzx0idnkN1Y\n"+
"0RAQ1rjGeQ1pk3l2DWsPi9mTkCGmYs/EMLkKOBee9ad3BIG6sKwXgbgLyNLgda+Y1bo+SIomq/a7\n"+
"yP92UHMFEegfS/ssECA+Q3hHuU6in3AqLfWH1w==\n"+
"-----END CERTIFICATE-----";
int startIndex = 0;
String cert = text.substring(startIndex,text.length());
byte[] certBytes = cert.getBytes();
InputStream in = new Base64InputStream(new ByteArrayInputStream(
certBytes), 0);
CertificateFactory certFact = CertificateFactory.getInstance ("X.509");
Certificate certGen = certFact.generateCertificate(in);
X509Certificate x509 = (X509Certificate) certGen;
Log.i("","certificate details:"+x509);
}
catch (Exception e)
{
Log.e("testapp", "exception: " + e.getMessage());
}
}
}
and I am getting android.util.BASE64DataException:bad base-64 at the foloowing line when I launced debugger:-
Certificate certGen = certFact.generateCertificate(in);
Seems like there is something wrong with Base64InputStream.Please help in rectifying the Exception.
Thanks in advance
No, nothing is wrong with Base64InputStream. When in doubt, you should suspect your own code of being incorrect rather than everyone else's.
What's wrong is that you're giving Base64InputStream data that ends with "-----END CERTIFICATE-----" after the padding part.
You should only be passing in the bit between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----".
It looks like you've started thinking about that already here:
int startIndex = 0;
String cert = text.substring(startIndex,text.length());
... but that code isn't going to do anything - when startIndex is 0, substring is going to return the whole string...
Personally I'd consider doing the Base64 conversion first using the Base64 class to convert the base64 part of the string (you still need to get the substring) to a byte[] and then create a ByteArrayInputStream around that.