samsung - Impresión Bluetooth y WIFI para Android
conectar celular a impresora wifi (7)
Necesitaríamos una impresora portátil (portátil, es importante) que se pueda conectar al teléfono Android a través de bluetooth o wifi.
Lo que sé actualmente:
- No hay SDK de impresión estándar disponible para Android esta vez
- Hay un SDK no oficial llamado iPrint SDK . ¿Alguno de ustedes lo ha intentado a través de wifi o bluetooth? ¿Funciona?
- Printershare también afirma que está disponible programáticamente . Estaría bien para mí pagar la tarifa única de $ 5 por teléfono. Tiene muchos formatos compatibles. ¿Lo has probado con cualquier dispositivo de mano? Les pregunté sobre la lista de impresoras bluetooth compatibles (ya que tiene un elemento de menú "buscar impresora BT"), pero no respondieron.
Lo que necesito saber más arriba de lo ya preguntado:
- ¿Cómo se imprime desde su aplicación de Android?
- ¿Qué tipo de impresora usas?
- ¿Está previsto en el SDK android estándar incluir la impresión? ¿Cuál es el mapa de ruta? ¿Está disponible ahora como Beta o algo así?
- Si de alguna manera (no lo creo) construyes una solución propia para imprimir a través de bluetooth, ¿puedes recomendar estándares y protocolos para verificar y aprender?
A partir de Android 4.4 , puede imprimir documentos desde un dispositivo a una impresora de hardware a través de wifi.
Las aplicaciones de Android ahora pueden imprimir cualquier tipo de contenido a través de Wi-Fi o servicios alojados en la nube, como Google Cloud Print. En aplicaciones habilitadas para impresión, los usuarios pueden descubrir impresoras disponibles, cambiar tamaños de papel, elegir páginas específicas para imprimir e imprimir casi cualquier tipo de documento, imagen o archivo.
Un breve ejemplo de cómo comenzar el proceso de impresión:
private void doPrint() {
PrintManager printManager = (PrintManager) getActivity().getSystemService(Context.PRINT_SERVICE);
printManager.print("My document", new CustomPrintDocumentAdapter(getActivity()), null);
}
donde CustomPrintDocumentAdapter extiende PrintDocumentAdapter .
Más información está disponible en Desarrolladores de Android .
Hay otro SDK de impresión para Android llamado APF. Se basa en CUPS, por lo que hasta miles de impresoras compatibles. Sitio web: isb-vietnam.com
La única impresión que he podido integrar es para Bixolon SPP-R200. Tienen un SDK decente disponible y es bastante fácil de encontrar. Estoy buscando capacidades de bluetooth de 8 1/2 x 11, pero un SDK para algo así parece ser un orden bastante alto en este momento
La impresión vía Bluetooth en Android no es posible hasta ahora (según mi conocimiento), ya que Android no es compatible con ''Perfiles'' Bluetooth, como BPP (Perfil de impresión básico), HCRP (Perfil de reemplazo de copia impresa), BIP (Perfil de imagen básico) etc. que son los perfiles comunes que se usan con la impresión Bluetooth. Árbitro. this para saber sobre la impresión de perfiles de BT.
Actualmente, Android es compatible con OPP (Object Push Profile) que se utiliza para enviar archivos a través de Bluetooth.
Para tener la impresión de perfiles bluetooth implementados dentro de Bluetooth Stack para Android, puede referirse a Sybase-iAnywhere-Blue-SDK-for-Android , que proporciona un SDK para agregar esta funcionalidad a la implementación de la pila BT existente en Android.
Para la impresión de Wifi, hay muchas aplicaciones en el mercado que le permiten imprimir varios documentos e imágenes desde su teléfono Android. Vea PrinterShare para una de esas aplicaciones. Para la impresión de Wifi, puede usar cualquier impresora que pueda conectar a través de ethernet (LAN).
También consulte las impresoras que están habilitadas con ''Google Cloud Print'', que usa la nube para imprimir en una impresora conectada en cualquier parte del mundo, que admita este protocolo. Esto es bastante nuevo en el mercado, pero algo que definitivamente ganará tracción en los próximos años. Mira la aplicación Cloud Print aquí . y preguntas frecuentes aquí .
Espero que esto ayude a sacar algunas preguntas de tu lista.
Lo siento, no tengo conocimiento acerca de la impresión usando dispositivos bluetooth. Pero investigué sobre la impresión usando wifi y publiqué ese código en GitHub. Puede referirse a eso si es necesario. Android-wifi-print - GitHub
Este es el flujo de ese prototipo.
- comprueba la conectividad.
- Si está conectado en WiFi ... estoy almacenando esa configuración WiFi.
- Ahora estoy disponible o no para verificar si ya tengo la información de la impresora (configuración WiFi de la impresora WiFi). Si está disponible, escanearé y obtendré una lista de WiFi ScanResults y me conectaré a ese otro ... Mostrará una lista de WiFi y al hacer clic en eso, el usuario se conectará a la impresora y almacenará esa configuración WiFi para futuros trabajos de impresión.
- Una vez que finaliza el trabajo de impresión, me estoy conectando a mi conexión de datos Wi-Fi o móvil anterior.
- Ahora volviendo al 2do paso.
- Si el usuario se conectó a datos móviles, solo estoy habilitando WiFi y siguiendo el tercer paso.
- Una vez que finaliza el trabajo de impresión, solo estoy deshabilitando WiFi. para que, volvamos a conectarnos a la conexión de datos móvil. (Eso es predeterminado de Android).
Debajo de clase se encargará de todos los trabajos de impresión en ese prototipo.
PrintUtility.class
public class PrintUtility implements Observer {
private static final int TIME_OUT = 10000;
private static final int CONNECTION_TIME_OUT = 5000;
private Activity mActivity;
private Fragment mFragment = null;
private WifiConfiguration mPrinterConfiguration;
private WifiConfiguration mOldWifiConfiguration;
private WifiManager mWifiManager;
private WifiScanner mWifiScanner;
private List<ScanResult> mScanResults = new ArrayList<ScanResult>();
private PrintManager mPrintManager;
private List<PrintJob> mPrintJobs;
private PrintJob mCurrentPrintJob;
private File pdfFile;
private String externalStorageDirectory;
private Handler mPrintStartHandler = new Handler();
private Handler mPrintCompleteHandler = new Handler();
private Handler mWifiConnectHandler = new Handler();
private String connectionInfo;
private boolean isMobileDataConnection = false;
private PrintCompleteService mPrintCompleteService;
// Observer pattern
private Observable mObservable;
public PrintUtility(Activity mActivity, WifiManager mWifiManager, WifiScanner mWifiScanner) {
this.mActivity = mActivity;
this.mWifiManager = mWifiManager;
this.mWifiScanner = mWifiScanner;
mPrintCompleteService = (PrintCompleteService) mActivity;
mObservable = ObservableSingleton.getInstance();
mObservable.attach(this);
}
public PrintUtility(Activity mActivity, Fragment mFragment, WifiManager mWifiManager, WifiScanner mWifiScanner) {
this.mActivity = mActivity;
this.mFragment = mFragment;
this.mWifiManager = mWifiManager;
this.mWifiScanner = mWifiScanner;
mPrintCompleteService = (PrintCompleteService) mFragment;
mObservable = ObservableSingleton.getInstance();
mObservable.attach(this);
}
public void downloadAndPrint(String fileUrl, final String fileName) {
new FileDownloader(mActivity, fileUrl, fileName) {
@Override
protected void onPostExecute(Boolean result) {
if (!result) {
mObservable.notifyObserver(true);
} else {
// print flow will come here.
try {
externalStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(externalStorageDirectory, Constants.CONTROLLER_PDF_FOLDER);
pdfFile = new File(folder, fileName);
} catch (Exception e) {
mObservable.notifyObserver(true);
e.printStackTrace();
}
print(pdfFile);
}
}
}.execute("");
}
public void print(final File pdfFile) {
this.pdfFile = pdfFile;
// check connectivity info -> mobile or wifi.
connectionInfo = Util.connectionInfo(mActivity);
if (connectionInfo.equalsIgnoreCase(Constants.CONTROLLER_MOBILE)) {
// follow mobile flow.
isMobileDataConnection = true;
if (mWifiManager.isWifiEnabled() == false) {
mWifiManager.setWifiEnabled(true);
}
mWifiManager.startScan();
setScanResults(mWifiScanner.getScanResults());
printerConfiguration();
} else if (connectionInfo.equalsIgnoreCase(Constants.CONTROLLER_WIFI)) {
// follow wifi flow..
// this will get current wifiInfo and store it in shared preference.
Util.storeCurrentWiFiConfiguration(mActivity);
printerConfiguration();
} else {
mObservable.notifyObserver(true);
}
}
private void printerConfiguration() {
// check printer detail is available or not.
mPrinterConfiguration = Util.getWifiConfiguration(mActivity, Constants.CONTROLLER_PRINTER);
if (mPrinterConfiguration == null) {
// printer configuration is not available.
// display list of wifi available in an activity
showWifiListActivity(Constants.REQUEST_CODE_PRINTER);
} else {
// get list of wifi available. if printer configuration available then connect it.
// else.. show list of available wifi nearby.
boolean isPrinterAvailable = false;
// scans nearby wifi..
mWifiManager.startScan();
setScanResults(mWifiScanner.getScanResults());
// checks this wifi in scan result list..
for (int i = 0; i < mScanResults.size(); i++) {
if (mPrinterConfiguration.SSID.equals("/"" + mScanResults.get(i).SSID + "/"")) {
isPrinterAvailable = true;
break;
}
}
if (isPrinterAvailable) {
// connect to printer wifi and show print settings dialog and continue with print flow.
connectToWifi(mPrinterConfiguration);
// prints document.
doPrint();
} else {
showWifiListActivity(Constants.REQUEST_CODE_PRINTER);
}
}
}
private void showWifiListActivity(int requestCode) {
Intent iWifi = new Intent(mActivity, WifiListActivity.class);
mActivity.startActivityForResult(iWifi, requestCode);
}
private void connectToWifi(WifiConfiguration mWifiConfiguration) {
mWifiManager.enableNetwork(mWifiConfiguration.networkId, true);
}
public void doPrint() {
try {
// it is taking some time to connect to printer.. so i used handler.. and waiting for its status.
mPrintStartHandler.postDelayed(new Runnable() {
@Override
public void run() {
mPrintStartHandler.postDelayed(this, TIME_OUT);
if (mPrinterConfiguration.status == WifiConfiguration.Status.CURRENT) {
if (mWifiManager.getConnectionInfo().getSupplicantState() == SupplicantState.COMPLETED) {
if (Util.computePDFPageCount(pdfFile) > 0) {
printDocument(pdfFile);
} else {
AlertDialog.Builder alert = new AlertDialog.Builder(mActivity);
alert.setMessage("Can''t print, Page count is zero.");
alert.setNeutralButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
dialog.dismiss();
switchConnection();
}
});
alert.show();
}
}
mPrintStartHandler.removeCallbacksAndMessages(null);
} else {
Toast.makeText(mActivity, "Failed to connect to printer!.", Toast.LENGTH_LONG).show();
switchConnection();
mPrintStartHandler.removeCallbacksAndMessages(null);
}
}
}, TIME_OUT);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(mActivity, "Failed to connect to printer!.", Toast.LENGTH_LONG).show();
switchConnection();
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public void printDocument(File pdfFile) {
mPrintManager = (PrintManager) mActivity.getSystemService(Context.PRINT_SERVICE);
String jobName = mActivity.getResources().getString(R.string.app_name) + " Document";
mCurrentPrintJob = mPrintManager.print(jobName, new PrintServicesAdapter(mActivity, mFragment, pdfFile), null);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public void completePrintJob() {
mPrintJobs = mPrintManager.getPrintJobs();
mPrintCompleteHandler.postDelayed(new Runnable() {
@Override
public void run() {
mPrintCompleteHandler.postDelayed(this, CONNECTION_TIME_OUT);
if (mCurrentPrintJob.getInfo().getState() == PrintJobInfo.STATE_COMPLETED) {
// remove that PrintJob from PrintManager.
for (int i = 0; i < mPrintJobs.size(); i++) {
if (mPrintJobs.get(i).getId() == mCurrentPrintJob.getId()) {
mPrintJobs.remove(i);
}
}
// switching back to previous connection..
switchConnection();
// stops handler..
mPrintCompleteHandler.removeCallbacksAndMessages(null);
} else if (mCurrentPrintJob.getInfo().getState() == PrintJobInfo.STATE_FAILED) {
switchConnection();
Toast.makeText(mActivity, "Print Failed!", Toast.LENGTH_LONG).show();
mPrintCompleteHandler.removeCallbacksAndMessages(null);
} else if (mCurrentPrintJob.getInfo().getState() == PrintJobInfo.STATE_CANCELED) {
switchConnection();
Toast.makeText(mActivity, "Print Cancelled!", Toast.LENGTH_LONG).show();
mPrintCompleteHandler.removeCallbacksAndMessages(null);
}
}
}, CONNECTION_TIME_OUT);
}
public void switchConnection() {
try {
if (!isMobileDataConnection) {
mOldWifiConfiguration = Util.getWifiConfiguration(mActivity, Constants.CONTROLLER_WIFI);
// get list of wifi available. if wifi configuration available then connect it.
// else.. show list of available wifi nearby.
boolean isWifiAvailable = false;
// scans nearby wifi.
mWifiManager.startScan();
setScanResults(mWifiScanner.getScanResults());
// checks this wifi in scan result list.
for (int i = 0; i < mScanResults.size(); i++) {
if (mOldWifiConfiguration.SSID.equals("/"" + mScanResults.get(i).SSID + "/"")) {
isWifiAvailable = true;
break;
}
}
if (isWifiAvailable) {
// connect to printer wifi and show print settings dialog and continue with print flow.
connectToWifi(mOldWifiConfiguration);
mWifiConnectHandler.postDelayed(new Runnable() {
@Override
public void run() {
mWifiConnectHandler.postDelayed(this, TIME_OUT);
if (mOldWifiConfiguration.status == WifiConfiguration.Status.CURRENT) {
if (mWifiManager.getConnectionInfo().getSupplicantState() == SupplicantState.COMPLETED) {
try {
mObservable.notifyObserver(true);
} catch (Exception e) {
e.printStackTrace();
}
mWifiConnectHandler.removeCallbacksAndMessages(null);
}
}
}
}, TIME_OUT);
} else {
showWifiListActivity(Constants.REQUEST_CODE_WIFI);
}
} else {
mWifiManager.setWifiEnabled(false);
mObservable.notifyObserver(true);
}
} catch (Exception e) {
mObservable.notifyObserver(true);
e.printStackTrace();
}
}
public void getPrinterConfigAndPrint() {
mPrinterConfiguration = Util.getWifiConfiguration(mActivity, Constants.CONTROLLER_PRINTER);
doPrint();
}
public void setScanResults(List<ScanResult> scanResults) {
this.mScanResults = scanResults;
}
public void onPrintCancelled() {
switchConnection();
}
@Override
public void update() {
mObservable.detach(this);
}
@Override
public void updateObserver(boolean bool) {
}
@Override
public void updateObserverProgress(int percentage) {
}
}
Con la ayuda de los siguientes enlaces, he creado esto.
Si desea imprimir su archivo solo llame print (archivo)
Si desea descargar un archivo e imprimirlo, llame a downloadAndPrint (fileUrl, fileName)
Star Micronics tiene un SDK para la impresión de Android a través de Bluetooth (además de wifi / ethernet y USB). Puede descargarlo aquí: http://www.starmicronics.com/support/SDKDocumentation.aspx .
Como se mencionó anteriormente, no puede imprimir de forma nativa en este momento, por lo que sus opciones son una API de impresora específica o una aplicación de impresión de un tercero.
En mi experiencia, es mejor usar una API y no una aplicación externa. La razón más importante es que obtenga un control total sobre el comportamiento de la impresora. Es fácil de implementar si la API está construida inteligentemente. Usar una aplicación de terceros es limitante porque no puede personalizar sus impresiones de la forma que desee.
El Star SDK al que te he vinculado tiene una aplicación de muestra realmente agradable que te permite probar y personalizar muchas funciones de la impresora para verlas en acción. Cada función está documentada en el código fuente. Los comandos y sus parámetros también están disponibles en la aplicación como una referencia rápida en pantalla que es conveniente. Además de todo eso, está bien documentado.
Si elige esta opción, puede enviar texto sin formato a la impresora junto con los comandos. La API se encarga de convertir los datos en lo que la impresora puede entender.
Zebra Technologies también proporciona un SDK para Android . He probado tanto su SDK como Bixolon (lo obtuve escribiendo a [email protected]). Ambos funcionan bien, pero si prefiere usar un lenguaje de descripción de página para definir sus documentos, probablemente sea mejor que use una impresora Zebra.