i have a website that is mobile responsive, then i turned it into a mobile app with webview, the IDE i used is Intellij, Programming language used is Java, it prints well with the POS 58MM printer on desktop, but for the mobile app, it is not, i'm making use of printerlibs.jar as a library
my java code
package com.example.mobileprinting;
import com.lvrenyang.io.IOCallBack;
import com.lvrenyang.io.Pos;
import com.lvrenyang.io.USBPrinting;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, IOCallBack {
private LinearLayout linearlayoutdevices;
Button btnDisconnect,btnPrint;
static MainActivity mActivity;
ExecutorService es = Executors.newScheduledThreadPool(30);
Pos mPos = new Pos();
USBPrinting mUsb = new USBPrinting();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPos.Set(mUsb);
mUsb.SetCallBack(this);
mActivity = this;
linearlayoutdevices = (LinearLayout) findViewById(R.id.linearlayoutdevices);
btnDisconnect = (Button) findViewById(R.id.buttonDisconnect);
btnPrint = (Button) findViewById(R.id.buttonPrint);
btnDisconnect.setOnClickListener(this);
btnPrint.setOnClickListener(this);
btnDisconnect.setEnabled(false);
btnPrint.setEnabled(false);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
probe();
} else {
finish();
}
WebView webView = findViewById(R.id.webView);
ProgressBar progressBar = findViewById(R.id.progressBar);
// Enable JavaScript (optional)
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
// Handle the JavaScript alert
// For simplicity, showing an AlertDialog
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton(android.R.string.ok, (dialog, which) -> result.confirm())
.setCancelable(false)
.show();
return true;
}
});
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// Show the ProgressBar when the page starts loading
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
// Hide the ProgressBar when the page has finished loading
progressBar.setVisibility(View.GONE);
printPage();
}
});
// Load a URL
webView.loadUrl("https://example.com.ng/app")
}
// This is where you add the WebAppInterface class as an inner class
public class WebAppInterface {
Context mContext;
WebAppInterface(Context context) {
mContext = context;
}
@JavascriptInterface
public void printPage() {
// Get a reference to the WebView
WebView webView = ((Activity) mContext).findViewById(R.id.webView);
// Create a WebViewClient to capture the content of the WebView
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
// Create a bitmap of the WebView content
view.measure(View.MeasureSpec.makeMeasureSpec(
View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
view.draw(new Canvas(bitmap));
// Convert the bitmap to a byte array
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();
// Send the byte array to the printer via USB
if (mUsb != null && mUsb.IsOpened()) {
// Write the bytes to the printer
int bytesWritten = mUsb.Write(bytes, 0, bytes.length);
if (bytesWritten != -1) {
// Printing successful
Log.d(TAG, "Printing successful");
} else {
// Printing failed
Log.e(TAG, "Printing failed");
// Show a message to the user indicating that printing failed
Toast.makeText(mContext, "Printing failed", Toast.LENGTH_SHORT).show();
}
} else {
// Printer is not connected, display a message
Log.e(TAG, "Printer is not connected");
Toast.makeText(mContext, "Printer is not connected", Toast.LENGTH_SHORT).show();
}
}
});
// Reload the WebView to trigger onPageFinished and capture the content
webView.reload();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
btnDisconnect.performClick();
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (arg0.getId() == R.id.buttonDisconnect) {
es.submit(new MainActivity.TaskClose(mUsb));
}
else if (arg0.getId() == R.id.buttonPrint) {
btnPrint.setEnabled(false);
}
}
@Override
public void OnOpen() {
// TODO Auto-generated method stub
this.runOnUiThread(new Runnable(){
@Override
public void run() {
btnDisconnect.setEnabled(true);
btnPrint.setEnabled(true);
linearlayoutdevices.setEnabled(false);
for(int i = 0; i < linearlayoutdevices.getChildCount(); ++i)
{
Button btn = (Button)linearlayoutdevices.getChildAt(i);
btn.setEnabled(false);
}
Toast.makeText(mActivity, "Connected", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void OnOpenFailed() {
// TODO Auto-generated method stub
this.runOnUiThread(new Runnable(){
@Override
public void run() {
btnDisconnect.setEnabled(false);
btnPrint.setEnabled(false);
linearlayoutdevices.setEnabled(true);
for(int i = 0; i < linearlayoutdevices.getChildCount(); ++i)
{
Button btn = (Button)linearlayoutdevices.getChildAt(i);
btn.setEnabled(true);
}
Toast.makeText(mActivity, "Failed", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void OnClose() {
// TODO Auto-generated method stub
this.runOnUiThread(new Runnable(){
@Override
public void run() {
btnDisconnect.setEnabled(false);
btnPrint.setEnabled(false);
linearlayoutdevices.setEnabled(true);
for(int i = 0; i < linearlayoutdevices.getChildCount(); ++i)
{
Button btn = (Button)linearlayoutdevices.getChildAt(i);
btn.setEnabled(true);
}
probe(); // 如果因为打印机关机导致Close。那么这里需要重新枚举一下。
}
});
}
@SuppressLint("RtlHardcoded")
private void probe() {
linearlayoutdevices.removeAllViews();
final UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
if (deviceList.size() > 0) {
// 初始化选择对话框布局,并添加按钮和事件
while (deviceIterator.hasNext()) { // 这里是if不是while,说明我只想支持一种device
final UsbDevice device = deviceIterator.next();
//Toast.makeText( this, "" + device.getDeviceId() + device.getDeviceName() + device.toString(), Toast.LENGTH_LONG).show();
Button btDevice = new Button(
linearlayoutdevices.getContext());
btDevice.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
btDevice.setGravity(android.view.Gravity.CENTER_VERTICAL
| Gravity.LEFT);
btDevice.setText(String.format(" VID:%04X PID:%04X",
device.getVendorId(), device.getProductId()));
btDevice.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
PendingIntent mPermissionIntent = PendingIntent
.getBroadcast(
MainActivity.this,
0,
new Intent(
MainActivity.this
.getApplicationInfo().packageName),
PendingIntent.FLAG_IMMUTABLE);
if (!mUsbManager.hasPermission(device)) {
mUsbManager.requestPermission(device,
mPermissionIntent);
Toast.makeText(getApplicationContext(),
"没有权限", Toast.LENGTH_LONG)
.show();
} else {
Toast.makeText(mActivity, "Connecting...", Toast.LENGTH_SHORT).show();
linearlayoutdevices.setEnabled(false);
for(int i = 0; i < linearlayoutdevices.getChildCount(); ++i)
{
Button btn = (Button)linearlayoutdevices.getChildAt(i);
btn.setEnabled(false);
}
btnDisconnect.setEnabled(false);
btnPrint.setEnabled(false);
es.submit(new MainActivity.TaskOpen(mUsb,mUsbManager,device));
//es.submit(new TaskTest(mPos,mUsb,mUsbManager,device));
}
}
});
linearlayoutdevices.addView(btDevice);
}
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Handle the configuration change if needed
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
WebView webView = findViewById(R.id.webView);
Intent intent;
if (item.getItemId() == R.id.action_home) {
// Handle the menu item click
intent = new Intent(this, MainActivity.class);
startActivity(intent);
return true;
} else if (item.getItemId() == R.id.action_refresh) {
// Handle the refresh action here
webView.reload();
return true;
} else if (item.getItemId() == R.id.action_exit) {
// Handle the exit action here
showExitConfirmationDialog();
return true;
} else if (item.getItemId() == R.id.action_print) {
// Handle the menu item click
intent = new Intent(this, ConnectUSBActivity.class);
connectUsbLauncher.launch(intent);
return true;
}
// Add more conditions for other menu items if needed
return super.onOptionsItemSelected(item);
}
public class TaskOpen implements Runnable
{
USBPrinting usb = null;
UsbManager usbManager = null;
UsbDevice usbDevice = null;
public TaskOpen(USBPrinting usb, UsbManager usbManager, UsbDevice usbDevice)
{
this.usb = usb;
this.usbManager = usbManager;
this.usbDevice = usbDevice;
}
@Override
public void run() {
// TODO Auto-generated method stub
usb.Open(usbManager,usbDevice);
}
}
static int dwWriteIndex = 1;
public class TaskPrint implements Runnable
{
Pos pos = null;
public TaskPrint(Pos pos)
{
this.pos = pos;
}
@Override
public void run() {
// TODO Auto-generated method stub
final boolean bPrintResult = PrintTicket(AppStartActivity.nPrintWidth, AppStartActivity.bCutter, AppStartActivity.bDrawer, AppStartActivity.bBeeper, AppStartActivity.nPrintCount, AppStartActivity.nCompressMethod);
final boolean bIsOpened = pos.GetIO().IsOpened();
mActivity.runOnUiThread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(mActivity.getApplicationContext(), bPrintResult ? getResources().getString(R.string.printsuccess) : getResources().getString(R.string.printfailed), Toast.LENGTH_SHORT).show();
mActivity.btnPrint.setEnabled(bIsOpened);
}
});
}
public boolean PrintTicket(int nPrintWidth, boolean bCutter, boolean bDrawer, boolean bBeeper, int nCount, int nCompressMethod)
{
boolean bPrintResult = false;
byte[] status = new byte[1];
if(pos.POS_QueryStatus(status, 3000, 2))
{
for(int i = 0; i < nCount; ++i)
{
if(!pos.GetIO().IsOpened())
break;
pos.POS_FeedLine();
pos.POS_S_Align(1);
pos.POS_S_TextOut("REC" + String.format("%03d", i) + "\r\nCaysn Printer\r\n测试页\r\n\r\n", 0, 1, 1, 0, 0x100);
pos.POS_S_TextOut("扫二维码下载苹果APP\r\n", 0, 0, 0, 0, 0x100);
pos.POS_S_SetQRcode("https://appsto.re/cn/2KF_bb.i", 8, 0, 3);
pos.POS_FeedLine();
//pos.POS_S_SetBarcode("20160618", 0, 72, 3, 60, 0, 2);
pos.POS_S_SetBarcode("11606211111331200008", 0, 73, 2, 60, 0, 2);
pos.POS_FeedLine();
}
if(bBeeper)
pos.POS_Beep(1, 5);
if(bCutter)
pos.POS_CutPaper();
if(bDrawer)
pos.POS_KickDrawer(0, 100);
int dwTicketIndex = dwWriteIndex++;
bPrintResult = pos.POS_TicketSucceed(dwTicketIndex, 30000);
}
return bPrintResult;
}
}
public class TaskClose implements Runnable
{
USBPrinting usb = null;
public TaskClose(USBPrinting usb)
{
this.usb = usb;
}
@Override
public void run() {
// TODO Auto-generated method stub
usb.Close();
}
}
@SuppressLint("MissingSuperCall")
@Override
public void onBackPressed() {
WebView webView = findViewById(R.id.webView);
if (webView.canGoBack()) {
webView.goBack(); // Navigate to the previous page
} else {
//super.onBackPressed(); // No previous page, so exit the app or perform another action
//show dialog before exit
showExitConfirmationDialog();
}
}
//action to take when back button is pressed on last page or the exit button is pressed
private void showExitConfirmationDialog() {
new AlertDialog.Builder(this)
.setTitle("Exit Confirmation")
.setMessage("Are you sure you want to exit the app?")
.setPositiveButton("Exit", (dialog, which) -> finishAffinity())
.setNegativeButton("Cancel", null)
.show();
}
}
The Code: