蓝牙,无线打印,安卓
题
我们需要一个便携式打印机(手持,它是重要的),可以连接到移动设备通过蓝牙或无线网络。
什么我知道现:
- 没有标准的打印SDK免费的这个时候
- 有一个非官方的SDK叫 正SDK.你试图通过无线或蓝牙?它的工作原理?
- 个别地访问 还要求是 programmaticly提供.它将确定我支付一次性费用5元为它每话。它有很多支持的格式。你有没有试过用任何手持设备?我问了他们有关的列表支持的蓝牙打印机(由于它有一个菜单项目"搜索BT打印机"),但他们并没有回答。
什么我需要知道上面已经询问:
- 你怎么从你的安卓程序?
- 什么样的打印机做你用?
- 这是计划在标准的安卓SDK包括印刷吗?什么是路线图?是它现在可以作为测试或什么的吗?
- 如果我们在某种程度上(我不这样认为)建立自己的解决方案,用于印刷通过蓝牙,你可以推荐标准和协议,检查和了解吗?
解决方案
从...开始 Android 4.4 您可以通过WiFi将文档从设备打印到硬件打印机。
Android应用程序现在可以通过Wi-Fi或云托管服务(例如Google Cloud Print)打印任何类型的内容。在支持印刷的应用程序中,用户可以发现可用的打印机,更改纸张尺寸,选择要打印的特定页面,并打印几乎所有类型的文档,图像或文件。
如何开始打印过程的简短示例:
private void doPrint() {
PrintManager printManager = (PrintManager) getActivity().getSystemService(Context.PRINT_SERVICE);
printManager.print("My document", new CustomPrintDocumentAdapter(getActivity()), null);
}
CustomPrintDocumentAdapter扩展的位置 printDocumentAdapter.
有关更多信息 Android开发人员.
其他提示
到目前为止(据我所知),由于Android不支持蓝牙“配置文件”,例如BPP(基本打印配置文件),HCRP(HARDCOPY替换配置文件),BIP(基本成像配置文件),因此无法通过蓝牙进行打印,因为Android不支持蓝牙“配置文件”。等等是蓝牙打印的常见配置文件。参考。 这个 了解打印BT配置文件。
当前,Android支持OPP(对象推送配置文件),该OPP用于通过蓝牙发送文件。
要在Android的蓝牙堆栈中实现打印蓝牙配置文件,您可以参考 sybase-anywhere-blue-sdk-for-android, ,它提供了一个SDK,可以将此功能添加到Android上现有的BT堆栈实现中。
对于WiFi打印,市场上有许多应用程序,可让您从Android手机中打印各种文档和图像。看 打印机 对于一个这样的应用程序。对于WiFi打印,您可以使用任何可以通过以太网(LAN)连接的打印机。
还可以查看启用“ Google Cloud Print”的打印机,该打印机使用云将其打印到世界上任何地方的打印机,支持该协议。这在市场上是很新的,但是在未来几年中肯定会吸引它。查看 云打印应用在这里. 。和 常见问题解答在这里.
希望这有助于从您的清单中提出一些问题。
抱歉,我对使用蓝牙设备打印的知识不知道。但是,我做了一些有关使用WiFi打印并在Github发布该代码的研究,您可以在需要时参考。 Android-Wifi-Print-Github
这是该原型的流程。
- 检查连接性。
- 如果在WiFi中连接。正在存储该WiFi配置。
- 现在检查我是否已经提供了打印机的信息(WiFi打印机的WiFi配置)。如果有的话,我将扫描并获取WiFi扫描仪的列表并连接到其他。它将显示wifi列表并单击该列表,用户将连接到打印机和存储WiFi配置以进行将来的打印作业。
- 打印作业完成后,我将连接到以前的WiFi或移动数据连接。
- 现在回到第二步。
- 如果用户在移动数据中连接,我只是启用WiFi并遵循第三步。
- 打印作业完成后,我只是禁用WiFi。这样,我们将连接回移动数据连接。 (那是Android默认值)。
下班下方将照顾该原型中的所有印刷作业。
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) {
}
}
在以下链接的帮助下,我创建了这个。
如果要打印文件,请致电 打印(文件)
如果要下载文件并打印该文件,请致电 downloadandprint(Fileurl,文件名)
我唯一能够集成的印刷是Bixolon SPP-R200。他们有一个不错的SDK可用,很容易找到。我正在寻找8 1/2 x 11的蓝牙功能,但是现在的SDK现在似乎是一个非常艰巨的任务
斯大精密有一个适用于安卓印刷通过蓝牙(以及无线网络/网和USB)。你可以在这里下载: http://www.starmicronics.com/support/SDKDocumentation.aspx.
如上所述,你不可以打印本身在这个时间点那你的选择是任何一个特定的打印机API或一个第3方印刷的应用程序。
以我的经验,最好使用API而不是外部的应用程序。最大的原因是你获得完全的控制权的打印机的行为。它很容易实现,如果API是建立智能。使用一个第3方的应用程序是限制性的,因为你不能自己打印出你想要的方式。
星SDK我连你有一个非常好的样本应用程序,可以测试和定制一个很大的打印机的功能看到他们的行动。每个功能是记录在案的源码。该命令及其参数,也可在本程序本身作为一个快速的屏幕上的参考方便。在所有的顶部,这是很好的记录。
如果你选择这种方式,可以发送普通的文本,以打印机的命令。API处理将数据转换成什么样的打印机可以理解的。
Android还有另一个称为APF的SDK。它基于杯子,因此最多支持的打印机得到了支持。网站: isb-vietnam.com
斑马技术还提供了 SDK用于Android. 。我尝试过他们的SDK和Bixolon's(通过写信给TechSupp@bixolon.de来获得它)。两者都可以正常工作,但是如果您喜欢使用 页面描述语言 要定义您的文档,您最好使用斑马打印机。