web-dev-qa-db-fra.com

Impression Bluetooth et WIFI pour Android

Nous aurions besoin d'une imprimante portable (portable, c'est important) qui peut se connecter à Android téléphone via bluetooth ou wifi.

Ce que je sais actuellement:

  • Aucun SDK d'impression standard disponible pour Android cette fois
  • Il existe un SDK non officiel appelé iPrint SDK . Avez-vous déjà essayé via wifi ou bluetooth? Est-ce que ça marche?
  • Printershare prétend également être disponible par programme . Ce serait bien pour moi de payer les frais uniques de 5 $ par téléphone. Il a beaucoup de formats pris en charge. L'avez-vous essayé avec n'importe quel appareil portable? Je leur ai posé des questions sur la liste des imprimantes Bluetooth prises en charge (car il a un élément de menu "Rechercher une imprimante BT"), mais ils n'ont pas répondu.

Ce que je dois savoir au-dessus du déjà demandé:

  • Comment imprimer à partir de votre application Android Android?
  • Quel type d'imprimante utilisez-vous?
  • Est-il prévu dans le standard Android SDK pour inclure l'impression? Quelle est la feuille de route? Est-il disponible maintenant en version bêta ou quelque chose?
  • Si, d'une manière ou d'une autre (je ne pense pas), nous construisons notre propre solution d'impression via Bluetooth, pouvez-vous recommander des normes et des protocoles à vérifier et à apprendre?
43
Gábor Lipták

À partir de Android 4.4 vous pouvez imprimer des documents depuis un appareil vers une imprimante matérielle via wifi.

Les applications Android peuvent désormais imprimer tout type de contenu via Wi-Fi ou des services hébergés dans le cloud tels que Google Cloud Print. Dans les applications imprimables, les utilisateurs peuvent découvrir les imprimantes disponibles, modifier les formats de papier, choisir des pages spécifiques à imprimer et imprimer presque tout type de document, image ou fichier.

Un bref exemple de la façon de démarrer le processus d'impression:

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

où CustomPrintDocumentAdapter s'étend PrintDocumentAdapter .

Plus d'informations sont disponibles sur Développeurs Android .

19
Gunnar Karlsson

L'impression via Bluetooth sur Android n'est pas possible pour l'instant (à ma connaissance), car Android ne prend pas en charge les `` profils '' Bluetooth, tels que BPP ( Profil d'impression de base), HCRP (Profil de remplacement sur papier), BIP (Profil d'imagerie de base), etc., qui sont les profils couramment utilisés avec l'impression Bluetooth Réf. this pour en savoir plus sur l'impression des profils BT.

Actuellement, Android prend en charge OPP (Object Push Profile) qui est utilisé pour envoyer des fichiers via Bluetooth.

Pour que les profils Bluetooth d'impression soient implémentés dans la pile Bluetooth pour Android, vous pouvez vous référer à Sybase-iAnywhere-Blue-SDK-for-Android , qui fournit un SDK pour ajouter cette fonctionnalité à l'implémentation existante de la pile BT sur Android.

Pour l'impression Wifi, il existe de nombreuses applications sur le marché qui vous permettent d'imprimer divers documents et images à partir de votre Android téléphone. Voir PrinterShare pour une de ces applications. Pour Wifi l'impression, vous pouvez utiliser n'importe quelle imprimante que vous pouvez connecter via Ethernet (LAN).

Consultez également les imprimantes compatibles avec Google Cloud Print, qui utilisent le cloud pour imprimer sur une imprimante connectée n'importe où dans le monde, qui prend en charge ce protocole. C'est assez nouveau sur le marché, mais quelque chose qui va certainement gagner du terrain au cours des prochaines années. Découvrez Application d'impression cloud ici . et faq ici .

J'espère que cela vous aidera à retirer quelques questions de votre liste.

15
Roy Samuel

Désolé, je n'ai pas de connaissances sur l'impression à l'aide de périphériques Bluetooth .. Mais, j'ai fait des recherches sur l'impression à l'aide du wifi et publié ce code dans GitHub, vous pouvez vous y référer si nécessaire .. Android-wifi-print - GitHub

C'est le flux de ce prototype.

  1. vérifie la connectivité.
  2. Si connecté en WiFi .. je stocke cette configuration WiFi.
  3. Vérifier maintenant si j'ai déjà des informations sur l'imprimante (configuration WiFi de l'imprimante WiFi) est disponible ou non. Si disponible, je numériserai et obtiendra la liste des résultats de numérisation WiFi et se connectera à cela d'autre .. Il affichera la liste des WiFi et en cliquant dessus, l'utilisateur se connectera à l'imprimante et stockera cette configuration WiFi pour les futurs travaux d'impression.
  4. Une fois le travail d'impression terminé, je me connecte à ma précédente connexion de données WiFi ou mobile.
  5. Revenons maintenant à la 2e étape.
  6. Si l'utilisateur est connecté dans les données mobiles, j'active simplement le WiFi et suit la 3ème étape.
  7. Une fois le travail d'impression terminé, je désactive simplement le WiFi. de sorte que nous serons de nouveau connectés à la connexion de données mobile. (C'est Android par défaut).

La classe ci-dessous s'occupera de tous les travaux d'impression dans ce prototype.

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) {

    }

}

Avec l'aide des liens suivants, j'ai créé cela.

Si vous souhaitez imprimer votre fichier, appelez simplement print (file)

Si vous souhaitez télécharger un fichier et l'imprimer, appelez downloadAndPrint (fileUrl, fileName)

8
SureshCS50

La seule impression que j'ai pu intégrer est celle du Bixolon SPP-R200. Ils ont un SDK décent disponible et est assez facile à trouver. Je suis à la recherche de capacités Bluetooth 8 1/2 x 11 mais un SDK pour quelque chose comme ça semble être une tâche assez difficile en ce moment

7
TMLZ77

Star Micronics dispose d'un SDK pour Android impression via Bluetooth (ainsi que wifi/ethernet et USB). Vous pouvez le télécharger ici: http://www.starmicronics.com/ support/SDKDocumentation.aspx .

Comme mentionné ci-dessus, vous ne pouvez pas imprimer en mode natif à ce stade, vos options sont donc une API d'imprimante spécifique ou une application d'impression tierce.

D'après mon expérience, il est préférable d'utiliser une API et non une application externe. La principale raison est que vous obtenez un contrôle total sur le comportement de l'imprimante. Il est facile à mettre en œuvre si l'API est conçue intelligemment. L'utilisation d'une application tierce est limitative car vous ne pouvez pas personnaliser vos impressions comme vous le souhaitez.

Le SDK Star auquel je vous ai lié a un exemple d'application vraiment sympa qui vous permet de tester et de personnaliser de nombreuses fonctions de l'imprimante pour les voir en action. Chaque fonction est documentée dans le code source. Les commandes et leurs paramètres sont également disponibles dans l'application elle-même comme référence rapide à l'écran, ce qui est pratique. En plus de tout cela, c'est bien documenté.

Si vous choisissez cette méthode, vous pouvez envoyer du texte brut à l'imprimante avec des commandes. L'API gère la conversion des données en ce que l'imprimante peut comprendre.

3
LtH

Il existe un autre SDK d'impression pour Android appelé APF. Il est basé sur CUPS donc jusqu'à des milliers d'imprimantes prises en charge. Site Web: isb-vietnam.com

2
sangtan

Zebra Technologies fournit également un SDK pour Android . J'ai essayé à la fois leur SDK et Bixolon (obtenu en écrivant à [email protected]). Les deux fonctionnent bien, mais si vous préférez utiliser un langage de description de page pour définir vos documents, vous feriez probablement mieux d'utiliser une imprimante Zebra.

2
JAGP