现在的位置: 首页 > 综合 > 正文

Android无线连接打印第三方开发的实现

2017年12月16日 ⁄ 综合 ⁄ 共 14407字 ⁄ 字号 评论关闭
 

         最近在做关于Android的项目,Android果然不是出于国内,很多东西都是国外已经成熟了或者已经开发好了,国内去效仿。为了找关于Android无线连接打印机并打印的第三方开发方案都非常的困难。由于最近项目需要用到这一块,经过我的组员的努力,找到了一种解决方案,为了能够和大家分享一下,也为了自己以后的参考,在这里稍作总结一下。经验有限,希望有更好方案的可以不吝赐教,我也会在以后的学习中不断修缮自己的方案。

        为了便于大家的参考,本文涉及到的所有的相关工程文件都在本人的csdn下载部分有相关资料下载。

       1.背景:

               很多开发者在工作上或者学习中可能需要通过基于Android系统的手机或者平板终端连接打印机,并驱动打

       印机打印自己发送的图片或者文本。本篇博客主要致力于解决这个问题。

       2.方案:

               本方案需要在android系统中安装一个软件send2print,在我的csdn下载频道中有相应的中文破解版下载链

        接,然后再写自己的程序,来调用其接口进行打印。事先需要在send2print中配置好默认打印机,我们写的程序

        就是调用其默认打印机进行无线打印。

       3.send2print:(我的csdn下载:http://download.csdn.net/detail/kunlong0909/4514502

                这个软件可以安装直接使用,可以搜索开着无线的打印机,并连接进行打印,目前只有国外有卖该产品,

        国内网上可以下载汉化版,我的csdn下载中也有。汉化版有一定的缺陷,经过测试,佳能产品的大部分型号

        都无法实现打印,但是HP LaserJet 1536dnf MFP可以实现打印。

        4.代码实现:(我的csdn工程源码下载:http://download.csdn.net/detail/kunlong0909/4514570

               我也不想贴代码,但是,安装好之后,配置上默认打印机,你只需要两个类就可以轻松实现无线打印了,

        由于代码量不大,也很容易看懂,我就直接贴在下面了,如果需要测试打印的资源文件可以到我csdn下载频道

        下载,这该死的博客怎么没有直接上传资源功能,还是我没有发现啊,谁发现了告诉我一声啊,嘿嘿。

                PrintUtils.java

               

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 "content://s2p_localfile/sdcard/logo.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="content://s2p_localfile/sdcard/logo.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

       

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=\"http://www.google.com/intl/en_ALL/images/logo.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=\"content://s2p_localfile/sdcard/logo.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=\"http://www.google.com/intl/en_ALL/images/logo.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=\"content://s2p_localfile/sdcard/logo.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!
 

抱歉!评论已关闭.