RK3399 Android7.1 系统打印方案(一)编译
Android默认实现了打印的框架,使用PrintManager+PrintManagerService
但是有些系统裁剪了打印服务
一.packages\apps\Settings\src\com\android\settings\SettingsActivity.java
setTileEnabled(new ComponentName(packageName,
Settings.PrintSettingsActivity.class.getName()),
pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm);
private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin,
PackageManager pm) {
if (UserHandle.MU_ENABLED && !isAdmin && getPackageName().equals(component.getPackageName())
&& !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, component.getClassName())) {
enabled = false;
}
setTileEnabled(component, enabled);
}
hasSystemFeature(String string).通过该函数判断系统是否有特定的模块功能
PackageManager pm = context.getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
Log.d("gatsby", "Feature android.software.print not available");
}
frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
@Override
public boolean hasSystemFeature(String name, int version) {
synchronized (mPackages) {
final FeatureInfo feat = mAvailableFeatures.get(name);
if (feat == null) {
return false;
} else {
return feat.version >= version;
}
}
}
mAvailableFeatures
public PackageManagerService(Context context, Installer installer,
……………………
SystemConfig systemConfig = SystemConfig.getInstance();
mGlobalGids = systemConfig.getGlobalGids();
mSystemPermissions = systemConfig.getSystemPermissions();
mAvailableFeatures = systemConfig.getAvailableFeatures();
这个列表读取的是/sytem/etc/permissions下面的xml文件的feature节点
SystemConfig() {
// Read configuration from system
readPermissions(Environment.buildPath(
Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);
// Read configuration from the old permissions dir
readPermissions(Environment.buildPath(
Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);
// Allow ODM to customize system configs around libs, features and apps
int odmPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_APP_CONFIGS;
readPermissions(Environment.buildPath(
Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag);
readPermissions(Environment.buildPath(
Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);
// Only allow OEM to customize features
readPermissions(Environment.buildPath(
Environment.getOemDirectory(), "etc", "sysconfig"), ALLOW_FEATURES);
readPermissions(Environment.buildPath(
Environment.getOemDirectory(), "etc", "permissions"), ALLOW_FEATURES);
}
二.frameworks\native\data\etc\tablet_core_hardware.xml 加入print feature
<!-- basic system services -->
<feature name="android.software.app_widgets" />
<feature name="android.software.voice_recognizers" />
<feature name="android.software.backup" />
<feature name="android.software.home_screen" />
<feature name="android.software.input_methods" />
<feature name="android.software.print" />
三.惠普打印机

打印测试demo HPprintsdksample.apk https://github.com/mobileprint/android-print-sdk
1.1.rk3399 打印测试demo 异常 找补不到图片资源
09-22 15:11:29.738 I/ActivityManager( 514): Displayed com.android.printspooler/.ui.PrintActivity: +246ms
09-22 15:11:29.747 D/skia ( 2888): ---- fAsset->read(8192) returned 0
09-22 15:11:29.747 D/skia ( 2888): --- SkAndroidCodec::NewFromStream returned null
09-22 15:11:29.748 D/AndroidRuntime( 2888): Shutting down VM
--------- beginning of crash
09-22 15:11:29.749 E/AndroidRuntime( 2888): FATAL EXCEPTION: main
09-22 15:11:29.749 E/AndroidRuntime( 2888): Process: com.android.printspooler, PID: 2888
09-22 15:11:29.749 E/AndroidRuntime( 2888): android.view.InflateException: Binary XML file line #113: Binary XML file line #273: Error inflating class android.widget.ImageView
09-22 15:11:29.749 E/AndroidRuntime( 2888): Caused by: android.view.InflateException: Binary XML file line #273: Error inflating class android.widget.ImageView
09-22 15:11:29.749 E/AndroidRuntime( 2888): Caused by: java.lang.reflect.InvocationTargetException
09-22 15:11:29.749 E/AndroidRuntime( 2888): at java.lang.reflect.Constructor.newInstance0(Native Method)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.createView(LayoutInflater.java:645)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:717)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:785)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.parseInclude(LayoutInflater.java:994)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflate(LayoutInflater.java:854)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:415)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.app.Activity.setContentView(Activity.java:2428)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.printspooler.ui.PrintActivity.onPrinterRegistryReady(PrintActivity.java:303)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.printspooler.ui.PrintActivity.-com_android_printspooler_ui_PrintActivity_lambda$2(PrintActivity.java:295)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.printspooler.ui.PrintActivity$-void_-com_android_printspooler_ui_PrintActivity_lambda$1_android_os_IBinder_documentAdapter_LambdaImpl0.run(PrintActivity.java)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.os.Handler.handleCallback(Handler.java:755)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.os.Handler.dispatchMessage(Handler.java:95)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.os.Looper.loop(Looper.java:154)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.app.ActivityThread.main(ActivityThread.java:6157)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at java.lang.reflect.Method.invoke(Native Method)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
09-22 15:11:29.749 E/AndroidRuntime( 2888): Caused by: android.content.res.Resources$NotFoundException: Drawable com.android.printspooler:drawable/ic_expand_more with resource ID #0x7f020005
09-22 15:11:29.749 E/AndroidRuntime( 2888): Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_expand_more.xml from drawable resource ID #0x7f020005
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:725)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:571)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.content.res.Resources.loadDrawable(Resources.java:858)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.content.res.TypedArray.getDrawable(TypedArray.java:928)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.View.<init>(View.java:4202)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.widget.ImageView.<init>(ImageView.java:155)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.widget.ImageView.<init>(ImageView.java:150)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.widget.ImageView.<init>(ImageView.java:146)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at java.lang.reflect.Constructor.newInstance0(Native Method)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.createView(LayoutInflater.java:645)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:717)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:785)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.parseInclude(LayoutInflater.java:994)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflate(LayoutInflater.java:854)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:415)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.app.Activity.setContentView(Activity.java:2428)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.printspooler.ui.PrintActivity.onPrinterRegistryReady(PrintActivity.java:303)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.printspooler.ui.PrintActivity.-com_android_printspooler_ui_PrintActivity_lambda$2(PrintActivity.java:295)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.printspooler.ui.PrintActivity$-void_-com_android_printspooler_ui_PrintActivity_lambda$1_android_os_IBinder_documentAdapter_LambdaImpl0.run(PrintActivity.java)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.os.Handler.handleCallback(Handler.java:755)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.os.Handler.dispatchMessage(Handler.java:95)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.os.Looper.loop(Looper.java:154)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.app.ActivityThread.main(ActivityThread.java:6157)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at java.lang.reflect.Method.invoke(Native Method)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
09-22 15:11:29.749 E/AndroidRuntime( 2888): Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #22: <bitmap> requires a valid 'src' attribute
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.BitmapDrawable.updateStateFromTypedArray(BitmapDrawable.java:787)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.BitmapDrawable.inflate(BitmapDrawable.java:747)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.DrawableInflater.inflateFromXml(DrawableInflater.java:130)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:1227)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.StateListDrawable.inflateChildElements(StateListDrawable.java:188)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:116)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.DrawableInflater.inflateFromXml(DrawableInflater.java:130)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:1227)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.graphics.drawable.Drawable.createFromXml(Drawable.java:1200)
09-22 15:11:29.749 E/AndroidRuntime( 2888): at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:715)
09-22 15:11:29.749 E/AndroidRuntime( 2888): ... 36 more
09-22 15:11:29.757 W/ActivityManager( 514): Force finishing activity com.android.printspooler/.ui.PrintActivity
09-22 15:11:29.760 W/ActivityManager( 514): Force finishing activity com.hp.mss.printsdksample/.activity.MainActivity
09-22 15:11:29.775 I/Process ( 2888): Sending signal. PID: 2888 SIG: 9
09-22 15:11:29.794 D/OpenGLRenderer( 2023): endAllActiveAnimators on 0x7f4ef8a800 (RippleDrawable) with handle 0x7f58536960
09-22 15:11:29.813 W/InputDispatcher( 514): channel '9f5c3d6 com.android.printspooler/com.android.printspooler.ui.PrintActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x9
09-22 15:11:29.813 E/InputDispatcher( 514): channel '9f5c3d6 com.android.printspooler/com.android.printspooler.ui.PrintActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
09-22 15:11:29.825 D/GraphicsStats( 514): Buffer count: 10
09-22 15:11:29.825 I/WindowManager( 514): WIN DEATH: Window{9f5c3d6 u0 com.android.printspooler/com.android.printspooler.ui.PrintActivity}
09-22 15:11:29.825 W/InputDispatcher( 514): Attempted to unregister already unregistered input channel '9f5c3d6 com.android.printspooler/com.android.printspooler.ui.PrintActivity (server)'
09-22 15:11:29.826 I/ActivityManager( 514): Process com.android.printspooler (pid 2888) has died
09-22 15:11:29.826 D/ActivityManager( 514): cleanUpApplicationRecord -- 2888
09-22 15:11:29.827 W/ActivityManager( 514): Scheduling restart of crashed service com.android.printspooler/.model.PrintSpoolerService in 1000ms
09-22 15:11:29.827 D/RemotePrintSpooler( 514): Error clearing print spooler client
09-22 15:11:29.827 D/RemotePrintSpooler( 514): android.os.DeadObjectException
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at android.os.BinderProxy.transactNative(Native Method)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at android.os.BinderProxy.transact(Binder.java:617)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at android.print.IPrintSpooler$Stub$Proxy.setClient(IPrintSpooler.java:647)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at com.android.server.print.RemotePrintSpooler.clearClientLocked(RemotePrintSpooler.java:679)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at com.android.server.print.RemotePrintSpooler.-wrap0(RemotePrintSpooler.java)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at com.android.server.print.RemotePrintSpooler$MyServiceConnection.onServiceDisconnected(RemotePrintSpooler.java:711)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at android.app.LoadedApk$ServiceDispatcher.doDeath(LoadedApk.java:1469)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1483)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at android.os.Handler.handleCallback(Handler.java:755)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at android.os.Handler.dispatchMessage(Handler.java:95)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at android.os.Looper.loop(Looper.java:154)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at com.android.server.SystemServer.run(SystemServer.java:359)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at com.android.server.SystemServer.main(SystemServer.java:226)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at java.lang.reflect.Method.invoke(Native Method)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
09-22 15:11:29.827 D/RemotePrintSpooler( 514): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
09-22 15:11:29.830 W/System.err( 1690): java.lang.IllegalStateException: Observer com.hp.android.printservice.service.o$h$a@197f3db was not registered.
09-22 15:11:29.830 W/System.err( 1690): at android.database.Observable.unregisterObserver(Observable.java:69)
09-22 15:11:29.831 W/System.err( 1690): at android.widget.BaseAdapter.unregisterDataSetObserver(BaseAdapter.java:42)
09-22 15:11:29.831 W/System.err( 1690): at com.hp.android.printservice.service.o$h.onStopPrinterDiscovery(PrintServiceHelperBase.java:4)
09-22 15:11:29.831 W/System.err( 1690): at android.printservice.PrinterDiscoverySession.stopPrinterDiscovery(PrinterDiscoverySession.java:511)
09-22 15:11:29.831 W/System.err( 1690): at android.printservice.PrintService$ServiceHandler.handleMessage(PrintService.java:498)
09-22 15:11:29.831 W/System.err( 1690): at android.os.Handler.dispatchMessage(Handler.java:102)
09-22 15:11:29.831 W/System.err( 1690): at android.os.Looper.loop(Looper.java:154)
09-22 15:11:29.831 W/System.err( 1690): at android.app.ActivityThread.main(ActivityThread.java:6157)
09-22 15:11:29.831 W/System.err( 1690): at java.lang.reflect.Method.invoke(Native Method)
09-22 15:11:29.831 W/System.err( 1690): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
09-22 15:11:29.831 W/System.err( 1690): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
09-22 15:11:29.832 I/art ( 1154): Ignoring second debugger -- accepting and dropping
09-22 15:11:29.848 I/art ( 514): Ignoring second debugger -- accepting and dropping
09-22 15:11:29.856 I/art ( 708): Ignoring second debugger -- accepting and dropping
1.2. PrintSpooler
系统打印是通过一个系统apk实现的,叫做com.android.printspooler,位置在/system/app/PrintSpooler/中
这个apk的另外一个作用是接收来自用户APP的打印请求。用户APP的打印请求先被PrintManger通过PrintJob方式封装,
然后通过Intent唤起PrintSpooler的PrintActivity进行预览。如果打印机设备厂商实现了Print Plugin并提供apk安装到系统,
那么PrintSpooler就可以找到对应打印机驱动进行打印。
Android系统提供的这个打印框架尽管简单,但是接口功能局限,不能实现很多自定义的需求。
1.3. Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_expand_more.xml from drawable resource ID #0x7f020005

1.4.解决法案
device\rockchip\common\device.mk
PRODUCT_AAPT_CONFIG ?= normal large xlarge hdpi xhdpi xxhdpi PRODUCT_AAPT_PREF_CONFIG ?= xhdpi PRODUCT_LOCALES := en_US zh_TW zh_CN
device\rockchip\rk3399\rk3399_all.mk
#PRODUCT_AAPT_CONFIG := normal large mdpi tvdpi hdpi xhdpi #PRODUCT_AAPT_PREF_CONFIG := hdpi

浙公网安备 33010602011771号