web-dev-qa-db-ja.com

AndroidのBluetoothおよびWIFI印刷

Bluetoothまたはwifiを介してAndroid電話に接続できるポータブルプリンター(ハンドヘルド、重要))が必要です。

私が現在知っていること:

  • Android今回は利用可能な標準印刷SDKはありません
  • iPrint SDK という非公式のSDKがあります。 WiFiやBluetoothで試したことはありますか?動作しますか?
  • Printershare は、 プログラムで利用可能 であると主張しています。電話ごとに5ドルの1回限りの料金を支払うことは問題ありません。サポートされているフォーマットがたくさんあります。ハンドヘルドデバイスで試しましたか?サポートされているBluetoothプリンターのリストについて質問しました(メニュー項目に「BTプリンターの検索」があるため)。彼らは答えませんでした。

すでに尋ねられた以上に知っておくべきこと:

  • Androidアプリからどのように印刷しますか?
  • どのようなプリンターを使用していますか?
  • 標準のAndroid SDKで印刷を含める予定はありますか?ロードマップとは何ですか?現在ベータ版または何かとして利用可能ですか?
  • ブルートゥース経由で印刷するための独自のソリューションを何らかの形で構築する場合(そうは思わない)、チェックして学習するための標準とプロトコルを推奨できますか?
43
Gábor Lipták

Android 4.4 から始めて、wifi経由でデバイスからハードウェアプリンターにドキュメントを印刷できます。

Androidアプリは、Wi-FiまたはGoogleクラウドプリントなどのクラウドホスト型サービスを介して、あらゆるタイプのコンテンツを印刷できるようになりました。印刷対応アプリでは、ユーザーは利用可能なプリンターを見つけたり、用紙サイズを変更したり、印刷する特定のページを選択したり、ほぼすべての種類のドキュメント、画像、ファイルを印刷したりできます。

印刷プロセスを開始する方法の簡単な例:

private void doPrint() {
    PrintManager printManager = (PrintManager) getActivity().getSystemService(Context.PRINT_SERVICE);
    printManager.print("My document", new CustomPrintDocumentAdapter(getActivity()), null);
}

customPrintDocumentAdapterは PrintDocumentAdapter を拡張します。

詳細については、 Android Developers をご覧ください。

19
Gunnar Karlsson

Androidは現在のところ(私の知る限りでは)不可能です。AndroidはBPP( Bluetooth印刷で使用される一般的なプロファイルである基本印刷プロファイル)、HCRP(ハードコピー交換プロファイル)、BIP(基本イメージングプロファイル)など参照。 this BTプロファイルの印刷について知るため。

現在、Androidは、Bluetooth経由でファイルを送信するために使用されるOPP(オブジェクトプッシュプロファイル)をサポートしています。

BluetoothスタックをAndroid用Bluetoothスタック内に実装するには、 Sybase-iAnywhere-Blue-SDK-for-Android を参照してください。これにより、既存のBTスタック実装にこの機能を追加するSDKが提供されます。アンドロイド。

Wifi印刷の場合、Android電話。さまざまなドキュメントや画像を印刷できるアプリが市場に多数あります。そのようなアプリについては PrinterShare を参照してください。印刷では、イーサネット(LAN)経由で接続できる任意のプリンターを使用できます。

また、「Googleクラウドプリント」が有効になっているプリンターもチェックしてください。クラウドを使用して、このプロトコルをサポートする世界中のどこにでも接続されているプリンターに印刷します。これは市場ではまったく新しいものですが、今後数年間で確実に注目を集めるものです。 クラウドプリントアプリはこちら をご覧ください。および ここでよくある質問

これがリストからいくつかの質問を取り除くのに役立つことを願っています。

15
Roy Samuel

申し訳ありませんが、Bluetoothデバイスを使用した印刷に関する知識はありません。しかし、wifiを使用した印刷に関する調査を行い、そのコードをGitHubに投稿しました。必要に応じて参照できます。 Android-wifi-print- GitHub

これがそのプロトタイプの流れです。

  1. 接続を確認します。
  2. WiFiで接続している場合、そのWiFi設定を保存しています。
  3. プリンターの情報(WiFiプリンターのWiFi構成)が既にあるかどうかを確認できるようになりました。可能であれば、WiFi ScanResultsのリストをスキャンして取得し、他のリストに接続します。WiFiのリストが表示され、それをクリックすると、ユーザーはプリンターに接続し、将来の印刷ジョブのためにそのWiFi構成を保存します。
  4. 印刷ジョブが完了した後、以前のWiFiまたはモバイルデータ接続に接続しています。
  5. 次に、第2ステップに戻ります。
  6. ユーザーがモバイルデータに接続している場合、私はWiFiを有効にし、3番目のステップに従っています。
  7. 印刷ジョブが完了したら、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) {

    }

}

次のリンクの助けを借りて、私はこれを作成しました。

ファイルを印刷する場合は、print(file)を呼び出すだけです。

ファイルをダウンロードして印刷する場合は、downloadAndPrint(fileUrl、fileName)を呼び出します

8
SureshCS50

私が統合できた唯一の印刷は、ビクソロンSPP-R200用です。適切なSDKが利用可能であり、見つけるのは非常に簡単です。私は8 1/2 x 11のBluetooth機能を探していますが、そのようなもののsdkは今かなり高い注文のようです

7
TMLZ77

Star Micronicsには、Android Bluetooth(およびwifi/ethernetおよびUSB)による印刷用のSDKがあります。ここからダウンロードできます: http://www.starmicronics.com/ support/SDKDocumentation.aspx

上記のように、現時点ではネイティブに印刷できないため、オプションは特定のプリンターAPIまたはサードパーティの印刷アプリのいずれかです。

私の経験では、外部アプリケーションではなくAPIを使用するのが最善です。最大の理由は、プリンターの動作を完全に制御できることです。 APIがインテリジェントに構築されている場合、実装は簡単です。サードパーティのアプリを使用することは制限されています。これは、印刷を希望どおりにカスタマイズできないためです。

私があなたにリンクしたStar SDKには、多くのプリンター機能をテストおよびカスタマイズして、それらが実際に動作するのを確認できる、本当に素晴らしいサンプルアプリがあります。各機能はソースコードに記載されています。コマンドとそのパラメーターは、便利な画面上のクイックリファレンスとしてアプリ自体でも使用できます。それに加えて、十分に文書化されています。

この方法を選択した場合、コマンドとともにプレーンテキストをプリンターに送信できます。 APIは、データをプリンターが理解できるものに変換します。

3
LtH

Android APFと呼ばれる別の印刷SDKがあります。CUPSに基づいているため、最大数千台のプリンターがサポートされています。ウェブサイト: isb-vietnam.com

2
sangtan

Zebra Technologiesでは、 SDK for Android も提供しています。私は彼らのSDKとBixolonの両方を試しました([email protected]に書いてそれを手に入れました)。どちらも正常に機能しますが、ドキュメントを定義するために ページ記述言語 を使用したい場合は、Zebraプリンターを使用することをお勧めします。

2
JAGP