Android無線連接打印第三方開發的實現

[java] 
<span style="font-size:18px;"></span>  
         最近在做關於Android的項目,Android果然不是出於國內,很多東西都是國外已經成熟瞭或者已經開發好瞭,國內去效仿。為瞭找關於Android無線連接打印機並打印的第三方開發方案都非常的困難。由於最近項目需要用到這一塊,經過我的組員的努力,找到瞭一種解決方案,為瞭能夠和大傢分享一下,也為瞭自己以後的參考,在這裡稍作總結一下。經驗有限,希望有更好方案的可以不吝賜教,我也會在以後的學習中不斷修繕自己的方案。
        為瞭便於大傢的參考,本文涉及到的所有的相關工程文件都在本人的csdn下載部分有相關資料下載。
       1.背景:
               很多開發者在工作上或者學習中可能需要通過基於Android系統的手機或者平板終端連接打印機,並驅動打
       印機打印自己發送的圖片或者文本。本篇博客主要致力於解決這個問題。
       2.方案:
               本方案需要在android系統中安裝一個軟件send2print,在我的csdn下載頻道中有相應的中文破解版下載鏈
        接,然後再寫自己的程序,來調用其接口進行打印。事先需要在send2print中配置好默認打印機,我們寫的程序
        就是調用其默認打印機進行無線打印。
                    這個軟件可以安裝直接使用,可以搜索開著無線的打印機,並連接進行打印,目前隻有國外有賣該產品,
        國內網上可以下載漢化版,我的csdn下載中也有。漢化版有一定的缺陷,經過測試,佳能產品的大部分型號
        都無法實現打印,但是HP LaserJet 1536dnf MFP可以實現打印。
        4.代碼實現                我也不想貼代碼,但是,安裝好之後,配置上默認打印機,你隻需要兩個類就可以輕松實現無線打印瞭,
        由於代碼量不大,也很容易看懂,我就直接貼在下面瞭,如果需要測試打印的資源文件可以到我csdn下載頻道
        下載,這該死的博客怎麼沒有直接上傳資源功能,還是我沒有發現啊,誰發現瞭告訴我一聲啊,嘿嘿。
                PrintUtils.java
              
[html] 
package com.rcreations.testprint; 
 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
 
import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.pm.PackageInfo; 
import android.content.pm.PackageManager; 
import android.graphics.Bitmap; 
import android.graphics.Picture; 
import android.net.Uri; 
import android.os.Environment; 
import android.util.Log; 
 
 
 
public class PrintUtils 

    // for logging 
    private static final String TAG = PrintUtils.class.getSimpleName(); 
 
    // Send 2 Printer package name 
    private static final String PACKAGE_NAME = "com.rcreations.send2printer"; 
     
    // intent action to trigger printing 
    public static final String PRINT_ACTION = "com.rcreations.send2printer.print"; 
 
    // content provider for accessing images on local sdcard from within html content 
    // sample img src shoul be something like /wp-content/images1/20181015/20120821021535608117.gif" 
    public static final String LOCAL_SDCARD_CONTENT_PROVIDER_PREFIX = "content://s2p_localfile"; 
 
     
    /** 
     * Returns true if "Send 2 Printer" is installed.  
     */ 
    public static boolean isSend2PrinterInstalled( Context context ) 
    { 
        boolean output = false; 
        PackageManager pm = context.getPackageManager(); 
        try {  
            PackageInfo pi = pm.getPackageInfo( PACKAGE_NAME, 0 ); 
            if( pi != null ) 
            { 
                output = true; 
            } 
        } catch (PackageManager.NameNotFoundException e) {} 
        return output; 
    } 
     
     
    /** 
     * Launches the Android Market page for installing "Send 2 Printer" 
     * and calls "finish()" on the given activity. 
     */ 
    public static void launchMarketPageForSend2Printer( final Activity context ) 
    { 
        AlertDialog dlg = new AlertDialog.Builder( context ) 
        .setTitle("Install Send 2 Printer") 
        .setMessage("Before you can print to a network printer, you need to install Send 2 Printer from the Android Market.") 
        .setPositiveButton( android.R.string.ok, new DialogInterface.OnClickListener() { 
            @Override 
            public void onClick( DialogInterface dialog, int which ) 
            { 
                // launch browser 
                Uri data = Uri.parse( "http://market.android.com/search?q=pname:" + PACKAGE_NAME ); 
                Intent intent = new Intent( android.content.Intent.ACTION_VIEW, data ); 
                intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP ); 
                context.startActivity( intent ); 
                 
                // exit 
                context.finish(); 
            } 
        } ) 
        .show();     
    } 
     
     
    /** 
     * Save the given picture (contains canvas draw commands) to a file for printing. 
     */ 
    public static File saveCanvasPictureToTempFile( Picture picture ) 
    { 
        File tempFile = null; 
                 
        // save to temporary file 
        File dir = getTempDir(); 
        if( dir != null ) 
        { 
            FileOutputStream fos = null; 
            try 
            { 
                File f = File.createTempFile( "picture", ".stream", dir ); 
                fos = new FileOutputStream( f ); 
                picture.writeToStream( fos ); 
                tempFile = f; 
            } 
            catch( IOException e ) 
            { 
                Log.e( TAG, "failed to save picture", e ); 
            } 
            finally 
            { 
                close( fos ); 
            } 
        }        
         
        return tempFile; 
    } 
     
     
    /** 
     * Sends the given picture file (returned from {@link #saveCanvasPictureToTempFile}) for printing. 
     */ 
    public static boolean queuePictureStreamForPrinting( Context context, File f ) 
    { 
        // send to print activity 
        Uri uri = Uri.fromFile( f ); 
        Intent i = new Intent( PRINT_ACTION ); 
        i.setDataAndType( uri, "application/x-android-picture-stream" ); 
        i.putExtra( "scaleFitToPage", true ); 
        context.startActivity( i ); 
         
        return true; 
    } 
     
     
    /** 
     * Save the given Bitmap to a file for printing. 
     * Note: Bitmap can be result of canvas draw commands. 
     */ 
    public static File saveBitmapToTempFile( Bitmap b, Bitmap.CompressFormat format ) 
    throws IOException, UnknownFormatException 
    { 
        File tempFile = null; 
                 
        // save to temporary file 
        File dir = getTempDir(); 
        if( dir != null ) 
        { 
            FileOutputStream fos = null; 
            try 
            { 
                String strExt = null; 
                switch( format ) 
                { 
                    case PNG: 
                        strExt = ".pngx"; 
                        break; 
                         
                    case JPEG: 
                        strExt = ".jpgx"; 
                        break; 
                         
                    default: 
                        throw new UnknownFormatException( "unknown format: " + format ); 
                } 
                File f = File.createTempFile( "bitmap", strExt, dir ); 
                fos = new FileOutputStream( f ); 
                b.compress( format, 100, fos ); 
                tempFile = f; 
            } 
            finally 
            { 
                close( fos ); 
            } 
        }        
         
        return tempFile; 
    } 
     
     
    /** 
     * Sends the given image file for printing. 
     */ 
    public static boolean queueBitmapForPrinting( Context context, File f, Bitmap.CompressFormat format ) 
    throws UnknownFormatException 
    { 
        String strMimeType = null; 
        switch( format ) 
        { 
            case PNG: 
                strMimeType = "image/png"; 
                break; 
                 
            case JPEG: 
                strMimeType = "image/jpeg"; 
                break; 
                 
            default: 
                throw new UnknownFormatException( "unknown format: " + format ); 
        } 
         
        // send to print activity 
        Uri uri = Uri.fromFile( f ); 
        Intent i = new Intent( PRINT_ACTION ); 
        i.setDataAndType( uri, strMimeType ); 
        i.putExtra( "scaleFitToPage", true ); 
        i.putExtra( "deleteAfterPrint", true ); 
        context.startActivity( i ); 
         
        return true; 
    } 
     
 
    /** 
     * Sends the given text for printing. 
     */ 
    public static boolean queueTextForPrinting( Context context, String strContent ) 
    { 
        // send to print activity 
        Intent i = new Intent( PRINT_ACTION ); 
        i.setType( "text/plain" ); 
        i.putExtra( Intent.EXTRA_TEXT, strContent ); 
        context.startActivity( i ); 
         
        return true; 
    } 
         
     
    /** 
     * Save the given text to a file for printing. 
     */ 
    public static File saveTextToTempFile( String text ) 
    throws IOException 
    { 
        File tempFile = null; 
                 
        // save to temporary file 
        File dir = getTempDir(); 
        if( dir != null ) 
        { 
            FileOutputStream fos = null; 
            try 
            { 
                File f = File.createTempFile( "text", ".txt", dir ); 
                fos = new FileOutputStream( f ); 
                fos.write( text.getBytes() ); 
                tempFile = f; 
            } 
            finally 
            { 
                close( fos ); 
            } 
        }        
         
        return tempFile; 
    } 
     
     
    /** 
     * Sends the given text file for printing. 
     */ 
    public static boolean queueTextFileForPrinting( Context context, File f ) 
    { 
        // send to print activity 
        Uri uri = Uri.fromFile( f ); 
        Intent i = new Intent( PRINT_ACTION ); 
        i.setDataAndType( uri, "text/plain" ); 
        i.putExtra( "deleteAfterPrint", true ); 
        context.startActivity( i ); 
         
        return true; 
    } 
     
     
    /** 
     * Sends the given html for printing. 
     *  
     * You can also reference a local image on your sdcard using the "content://s2p_localfile" provider. 
     * For example: <img src=/wp-content/images1/20181015/20120821021535608117.gif"> 
     */ 
    public static boolean queueHtmlForPrinting( Context context, String strContent ) 
    { 
        // send to print activity 
        Intent i = new Intent( PRINT_ACTION ); 
        i.setType( "text/html" ); 
        i.putExtra( Intent.EXTRA_TEXT, strContent ); 
        context.startActivity( i ); 
         
        return true; 
    } 
         
     
    /** 
     * Sends the given html URL for printing. 
     *  
     * You can also reference a local file on your sdcard using the "content://s2p_localfile" provider. 
     * For example: "content://s2p_localfile/sdcard/test.html" 
     */ 
    public static boolean queueHtmlUrlForPrinting( Context context, String strUrl ) 
    { 
        // send to print activity 
        Intent i = new Intent( PRINT_ACTION ); 
        //i.setDataAndType( Uri.parse(strUrl), "text/html" );// this crashes! 
        i.setType( "text/html" ); 
        i.putExtra( Intent.EXTRA_TEXT, strUrl ); 
        context.startActivity( i ); 
         
        return true; 
    } 
         
     
    /** 
     * Save the given html content to a file for printing. 
     */ 
    public static File saveHtmlToTempFile( String html ) 
    throws IOException 
    { 
        File tempFile = null; 
                 
        // save to temporary file 
        File dir = getTempDir(); 
        if( dir != null ) 
        { 
            FileOutputStream fos = null; 
            try 
            { 
                File f = File.createTempFile( "html", ".html", dir ); 
                fos = new FileOutputStream( f ); 
                fos.write( html.getBytes() ); 
                tempFile = f; 
            } 
            finally 
            { 
                close( fos ); 
            } 
        }        
         
        return tempFile; 
    } 
     
     
    /** 
     * Sends the given html file for printing. 
     */ 
    public static boolean queueHtmlFileForPrinting( Context context, File f ) 
    { 
        // send to print activity 
        Uri uri = Uri.fromFile( f ); 
        Intent i = new Intent( PRINT_ACTION ); 
        i.setDataAndType( uri, "text/html" ); 
        i.putExtra( "deleteAfterPrint", true ); 
        context.startActivity( i ); 
         
        return true; 
    } 
     
     
    /** 
     * Return a temporary directory on the sdcard where files can be saved for printing. 
     * @return null if temporary directory could not be created. 
     */ 
    public static File getTempDir() 
    { 
        File dir = new File( Environment.getExternalStorageDirectory(), "temp" ); 
        if( dir.exists() == false && dir.mkdirs() == false ) 
        { 
            Log.e( TAG, "failed to get/create temp directory" ); 
            return null; 
        } 
        return dir; 
    } 
         
     
    /** 
     * Helper method to close given output stream ignoring any exceptions. 
     */ 
    public static void close( OutputStream os ) 
    { 
        if( os != null ) 
        { 
            try 
            { 
                os.close(); 
            } 
            catch( IOException e ) {} 
        } 
    } 
     
 
    /** 
     * Thrown by bitmap methods where the given Bitmap.CompressFormat value is unknown. 
     */ 
    public static class UnknownFormatException extends Exception 
    { 
        public UnknownFormatException( String msg ) 
        { 
            super( msg ); 
        } 
    } 

             以上是工具類,下面的是測試類:
         MainActivity.java
      
[java]
package com.rcreations.testprint; 
 
import java.io.File; 
import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Picture; 
import android.graphics.Rect; 
import android.graphics.Typeface; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
 
/**
 * Various print samples.
 */ 
public class MainActivity extends Activity 

    private static final String TAG = MainActivity.class.getSimpleName(); 
     
    static final String HELLO_WORLD = "Hello World"; 
     
     
    /**
     * Called when the activity is first created.
     */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
 
        // 
        // check for and install Send 2 Printer if needed 
        // 
         
        if( PrintUtils.isSend2PrinterInstalled(this) == false ) 
        { 
            PrintUtils.launchMarketPageForSend2Printer( this ); 
            return; 
        } 
         
        // 
        // setup GUI buttons 
        // 
         
        Button btnTestCanvas = (Button)findViewById( R.id.btnTestCanvas ); 
        btnTestCanvas.setOnClickListener( new View.OnClickListener() { 
            @Override 
            public void onClick(View v) 
            { 
                printCanvasExample(); 
            } 
        }); 
         
        Button btnTestCanvasAsBitmap = (Button)findViewById( R.id.btnTestCanvasAsBitmap ); 
        btnTestCanvasAsBitmap.setOnClickListener( new View.OnClickListener() { 
            @Override 
            public void onClick(View v) 
            { 
                printCanvasAsBitmapExample(); 
            } 
        }); 
 
        Button btnTestText = (Button)findViewById( R.id.btnTestText ); 
        btnTestText.setOnClickListener( new View.OnClickListener() { 
            @Override 
            public void onClick(View v) 
            { 
                printTextExample(); 
            } 
        }); 
 
        Button btnTestHtml = (Button)findViewById( R.id.btnTestHtml ); 
        btnTestHtml.setOnClickListener( new View.OnClickListener() { 
            @Override 
            public void onClick(View v) 
            { 
                printHtmlExample(); 
            } 
        }); 
         
        Button btnTestHtmlUrl = (Button)findViewById( R.id.btnTestHtmlUrl ); 
        btnTestHtmlUrl.setOnClickListener( new View.OnClickListener() { 
            @Override 
            public void onClick(View v) 
            { 
                printHtmlUrlExample(); 
            } 
        }); 
         
        Button btnTestTextFile = (Button)findViewById( R.id.btnTestTextFile ); 
        btnTestTextFile.setOnClickListener( new View.OnClickListener() { 
            @Override 
            public void onClick(View v) 
            { 
                printTextFileExample(); 
            } 
        }); 
 
        Button btnTestHtmlFile = (Button)findViewById( R.id.btnTestHtmlFile ); 
        btnTestHtmlFile.setOnClickListener( new View.OnClickListener() { 
            @Override 
            public void onClick(View v) 
            { 
                printHtmlFileExample(); 
            } 
        }); 
    } 
     
  
    /**
     * Send canvas draw commands for printing.
     * NOTE: Android 1.5 does not properly support drawBitmap() serialize/deserialize across process boundaries.
     * If you need to draw bitmaps, then see the {@link #printCanvasAsBitmapExample()} example. 
     */ 
    void printCanvasExample() 
    { 
        // create canvas to render on 
        Picture picture = new Picture(); 
        Canvas c = picture.beginRecording( 240, 240 ); 
         
        // fill background with WHITE 
        c.drawRGB( 0xFF, 0xFF, 0xFF ); 
         
        // draw text 
        Paint p = new Paint(); 
        Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD); 
        p.setTextSize( 18 ); 
        p.setTypeface( font ); 
        p.setAntiAlias(true);        
        Rect textBounds = new Rect(); 
        p.getTextBounds( HELLO_WORLD, 0, HELLO_WORLD.length(), textBounds ); 
        int x = (c.getWidth() – (textBounds.right-textBounds.left)) / 2; 
        int y = (c.getHeight() – (textBounds.bottom-textBounds.top)) / 2; 
        c.drawText( HELLO_WORLD, x, y, p ); 
         
        // draw icon 
        Bitmap icon = BitmapFactory.decodeResource( getResources(), R.drawable.icon ); 
        c.drawBitmap( icon, 0, 0, null ); 
 
        // stop drawing 
        picture.endRecording(); 
         
        // queue canvas for printing 
        File f = PrintUtils.saveCanvasPictureToTempFile( picture ); 
        if( f != null ) 
        { 
            PrintUtils.queuePictureStreamForPrinting( this, f ); 
        } 
    } 
     
     
    /**
     * Draw to a bitmap and then send the bitmap for printing.
     */ 
    void printCanvasAsBitmapExample() 
    { 
        // create canvas to render on 
        Bitmap b = Bitmap.createBitmap( 240, 240, Bitmap.Config.RGB_565 ); 
        Canvas c = new Canvas( b ); 
         
        // fill background with WHITE 
        c.drawRGB( 0xFF, 0xFF, 0xFF ); 
         
        // draw text 
        Paint p = new Paint(); 
        Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD); 
        p.setTextSize( 18 ); 
        p.setTypeface( font ); 
        p.setAntiAlias(true);        
        Rect textBounds = new Rect(); 
        p.getTextBounds( HELLO_WORLD, 0, HELLO_WORLD.length(), textBounds ); 
        int x = (c.getWidth() – (textBounds.right-textBounds.left)) / 2; 
        int y = (c.getHeight() – (textBounds.bottom-textBounds.top)) / 2; 
        c.drawText( HELLO_WORLD, x, y, p ); 
         
        // draw icon 
        Bitmap icon = BitmapFactory.decodeResource( getResources(), R.drawable.icon ); 
        c.drawBitmap( icon, 0, 0, null ); 
 
        // queue bitmap for printing 
        try 
        { 
            File f = PrintUtils.saveBitmapToTempFile( b, Bitmap.CompressFormat.PNG ); 
            if( f != null ) 
            { 
                PrintUtils.queueBitmapForPrinting( this, f, Bitmap.CompressFormat.PNG ); 
            } 
        } 
        catch( Exception e ) 
        { 
            Log.e( TAG, "failed to save/queue bitmap", e ); 
        } 
    } 
     
     
    /**
     * Send text for printing.
     */ 
    void printTextExample() 
    { 
        PrintUtils.queueTextForPrinting( this, HELLO_WORLD ); 
    } 
     
     
    /**
     * Send html for printing.
     */ 
    void printHtmlExample() 
    { 
        StringBuilder buf = new StringBuilder(); 
        buf.append( "<html>" ); 
        buf.append( "<body>" ); 
        buf.append( "<h1>" ).append( HELLO_WORLD ).append( "</h1>" );            
        buf.append( "<p>" ).append( "blah blah blah…" ).append( "</p>" );   
        buf.append( "<p><img src=/wp-content/images1/20181015/20120821021535595118.gif\" /></p>" ); 
        // you can also reference a local image on your sdcard using the "content://s2p_localfile" provider (see below)  
        //buf.append( "<p><img src=\/wp-content/images1/20181015/20120821021535608117.gif\" /></p>" ); 
        buf.append( "</body>" );           
        buf.append( "</html>" ); 
 
        PrintUtils.queueHtmlForPrinting( this, buf.toString() ); 
    } 
     
     
    /**
     * Send html URL for printing.
     */ 
    void printHtmlUrlExample() 
    { 
        PrintUtils.queueHtmlUrlForPrinting( this, "http://www.google.com" ); 
    } 
     
     
    /**
     * Send text file for printing.
     */ 
    void printTextFileExample() 
    { 
        try 
        { 
            File f = PrintUtils.saveTextToTempFile( HELLO_WORLD ); 
            if( f != null ) 
            { 
                PrintUtils.queueTextFileForPrinting( this, f ); 
            } 
        } 
        catch( Exception e ) 
        { 
            Log.e( TAG, "failed to save/queue text", e ); 
        } 
    } 
     
     
    /**
     * Send html file for printing.
     */ 
    void printHtmlFileExample() 
    { 
        try 
        { 
            StringBuilder buf = new StringBuilder(); 
            buf.append( "<html>" ); 
            buf.append( "<body>" ); 
            buf.append( "<h1>" ).append( HELLO_WORLD ).append( "</h1>" );            
            buf.append( "<p>" ).append( "blah blah blah…" ).append( "</p>" );   
            buf.append( "<p><img src=/wp-content/images1/20181015/20120821021535595118.gif\" /></p>" ); 
            // you can also reference a local image on your sdcard using the "content://s2p_localfile" provider (see below)  
            //buf.append( "<p><img src=\/wp-content/images1/20181015/20120821021535608117.gif\" /></p>" ); 
            buf.append( "</body>" );           
            buf.append( "</html>" ); 
             
            File f = PrintUtils.saveHtmlToTempFile( buf.toString() ); 
            if( f != null ) 
            { 
                PrintUtils.queueHtmlFileForPrinting( this, f ); 
            } 
        } 
        catch( Exception e ) 
        { 
            Log.e( TAG, "failed to save/queue html", e ); 
        } 
    } 
     
     

        其實整體上的邏輯很簡單,連接無線打印機和驅動打印都是通過send2printer來實現的,我們隻是需要調用它,將我們需要打印的信息發送給它就行,so easy!
 

發佈留言