2012-06-18 21 views
13

Estoy tratando de comprender y resolver y error que estoy viendo en el registro del espacio de trabajo de Eclipse mientras trabajo en una aplicación de Android que implementa un IME. Soy nuevo en Android y Eclipse.Android - Servicio no admitido: audio

El error es "com.utterkaos.keyboard.LatinKeyboardView no pudo crear instancias".

El seguimiento de la pila asociada es:

java.lang.UnsupportedOperationException: Servicio no admitido: audio en com.android.layoutlib.bridge.android.BridgeContext.getSystemService (BridgeContext.java:434) en android.inputmethodservice.KeyboardView. (KeyboardView.java:376) en android.inputmethodservice.KeyboardView. (KeyboardView.java:279) en com.utterkaos.keyboard.LatinKeyboardView. (LatinKeyboardView.java:30) al sol .reflect.NativeConstructorAccessorImpl.newInstance0 (Nativo Método) en sun.reflect.NativeConstructorAccessorImpl.newInstance (origen desconocido) en sun.reflect.DelegatingConstructorAccessorImpl.newInstance (Desconocido Fuente) en java.lang.reflect.Constructor.newInstance (Desconocido Fuente) en com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass (ProjectCallback.java:402) en com.android.ide.eclipse.adt.internal.editors.layout. ProjectCallback.loadView (ProjectCallback.java:166) en android.view.BridgeInflater.loadCustomView (BridgeInflater.java:207) en android.view.BridgeInflater.createViewF romTag (BridgeInflater.java:135) en android.view.LayoutInflater.inflate (LayoutInflater.java:466) en android.view.LayoutInflater.inflate (LayoutInflater.java:372) en com.android.layoutlib.bridge. impl.RenderSessionImpl.inflate (RenderSessionImpl.java:321) en com.android.layoutlib.bridge.Bridge.createSession (Bridge.java:324) en com.android.ide.common.rendering.LayoutLibrary.createSession (LayoutLibrary .java: 325) en com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderService.createRenderSession (RenderService.java:372) en com.android.ide.eclipse.adt.internal .editors.layout.gle2.GraphicalEditorPart.renderWithBridge (GraphicalEditorPart.java:1361) en com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.recomputeLayout (GraphicalEditorPart.java:1115) en com.android.ide.eclipse.adt.internal.editors.layout. gle2.GraphicalEditorPart.activated (GraphicalEditorPart.java:941) en com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate.delegatePageChange (LayoutEditorDelegate.java:450) en com.android.ide. eclipse.adt.internal.editors.common.CommonXmlEditor.pageChange (CommonXmlEditor.java:358) en org.eclipse.ui.part.MultiPageEditorPart.setActivePage (MultiPageEditorPart.java:1067) en org.eclipse.ui. forms.editor.FormEditor.setActivePage (Formulario Editor.java:607) en com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor.selectDefaultPage (AndroidXmlEditor.java:380) en com.android.ide.eclipse.adt.internal.editors. AndroidXmlEditor.addPages (AndroidXmlEditor.java:285) en com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor.addPages (CommonXmlEditor.java:283) en org.eclipse.ui.forms.editor.FormEditor.createPages (FormEditor.java:138) en org.eclipse.ui.part.MultiPageEditorPart.createPartControl (MultiPageEditorPart.java: 348) en org.eclipse.ui.internal.EditorReference.createPartHelper (EditorReference.java:670) en org.eclipse.ui.internal.EditorReference.createPart (EditorReference.java:465) en org.eclipse .ui.internal.WorkbenchPartReference.getPart (WorkbenchPartReference.java:595) en org.eclipse.ui.internal.EditorReference.getEditor (EditorReference.java:289) en org.e clipse.ui.internal.WorkbenchPage.busyOpenEditorBatched (WorkbenchPage.java:2945) en org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor (WorkbenchPage.java:2850) en org.eclipse.ui.internal.WorkbenchPage. acceso $ 11 (WorkbenchPage.java:2842) en org.eclipse.ui.internal.WorkbenchPage $ 10.run (WorkbenchPage.java:2793) en org.eclipse.swt.custom.BusyIndicator.showWhile (BusyIndicator.java: 70) en org.eclipse.ui.internal.WorkbenchPage.openEditor (WorkbenchPage.java:2789) en org.eclipse.ui.internal.WorkbenchPage.openEditor (WorkbenchPage.java:2773) en org.e clipse.ui.internal.WorkbenchPage.openEditor (WorkbenchPage.java:2764) en org.eclipse.ui.ide.IDE.openEditor (IDE.java:651) en org.eclipse.ui.ide.IDE.openEditor (IDE.java:610) en org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.openInEditor (EditorUtility.java:355) en org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.openInEditor (EditorUtility) .java: 164) en org.eclipse.jdt.ui.actions.OpenAction.run (OpenAction.java:249) en org.eclipse.jdt.ui.actions.OpenAction.run (OpenAction.java:228) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun (SelectionDispatchAction.java:275) en org.eclipse.jdt.ui.actions.SelectionDispatchAction.run (SelectionDispatchAction.java: 251) en org.eclipse.jdt.internal.ui.packageview.PackageExplorerActionGroup.handleOpen (PackageExplorerActionGroup.java:376) en org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart $ 4.open (PackageExplorerPart.java : 538) en org.eclipse.ui.OpenAndLinkWithEditorHelper $ InternalListener.open (OpenAndLinkWithEditorHelper.java:48) en org.eclipse.jface.viewers.StructuredViewer $ 2.run (StructuredViewer.java:866) en org. eclipse.core.runtime.SafeRunner.run (SafeRunner.java:42) en org.eclipse.ui.internal.JFaceUtil $ 1.run (JFaceUtil.java:49) en org.eclipse.jface.util.SafeRunnable.run (SafeRunnable.java:175) en org.eclips e.jface.viewers.StructuredViewer.fireOpen (StructuredViewer.java:864) en org.eclipse.jface.viewers.StructuredViewer.handleOpen (StructuredViewer.java:1152) en org.eclipse.jface.viewers.StructuredViewer $ 6 .handleOpen (StructuredViewer.java:1256) en org.eclipse.jface.util.OpenStrategy.fireOpenEvent (OpenStrategy.java:275) en org.eclipse.jface.util.OpenStrategy.access $ 2 (OpenStrategy.java: 269) en org.eclipse.jface.util.OpenStrategy $ 1.handleEvent (OpenStrategy.java:309) en org.eclipse.swt.widgets.EventTable.sendEvent (EventTable.java:84) en org.eclipse. swt.widgets.Widget.sendEvent (Widget.java: 1053) en org.eclipse.swt.widgets.Display.runDeferredEvents (Display.java:4165) en org.eclipse.swt.widgets.Display.readAndDispatch (Display.java:3754) en org.eclipse .ui.internal.Workbench.runEventLoop (Workbench.java:2701) en org.eclipse.ui.internal.Workbench.runUI (Workbench.java:2665) en org.eclipse.ui.internal.Workbench.access $ 4 (Workbench.java:2499) en org.eclipse.ui.internal.Workbench $ 7.run (Workbench.java:679) en org.eclipse.core.databinding.observable.Realm.runWithDefault (Realm.java:332) en org.eclipse.ui.internal.Workbench.createAndRunWorkbench (Workbench.java:668) en org.eclipse.ui.PlatformUI.crea teAndRunWorkbench (PlatformUI.java:149) en org.eclipse.ui.internal.ide.application.IDEApplication.start (IDEApplication.java:123) en org.eclipse.equinox.internal.app.EclipseAppHandle.run (EclipseAppHandle.java:196) en org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication (EclipseAppLauncher.java:110) en org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start (EclipseAppLauncher.java:79) en org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:344) en org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java: 179) en sun.reflect.NativeMethodAccessorImpl.invoke0 (Nativo Método) en sun.reflect.NativeMethodAccessorImpl.invoke (origen desconocido) en sun.reflect.DelegatingMethodAccessorImpl.invoke (origen desconocido) en java.lang.reflect.Method.invoke (Origen desconocido) en org.eclipse.equinox.launcher.Main.invokeFramework (Main.java:622) en org.eclipse.equinox.launcher.Main.basicRun (Main.java:577) en org.eclipse.equinox .launcher.Main.run (Main.java:1410) en org.eclipse.equinox.launcher.Main.main (Main.java:1386)

La parte pertinente de LatinKeyboardView.java es:

public class LatinKeyboardView extends KeyboardView { 

    static final int KEYCODE_OPTIONS = -100; 

    public LatinKeyboardView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

} 

La línea 30 es "super (context, attrs);"

En cuanto a KeyboardView.java, la línea 376:

mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 

aquí "Context.AUDIO_SERVICE" parece ser la cadena "audio", que aparece en el seguimiento de la pila de error.

El bit correspondiente de BridgeContext.java es:

public Object getSystemService(String service) { 
414  if (LAYOUT_INFLATER_SERVICE.equals(service)) { 
415   return mBridgeInflater; 
416  } 
417 
418  if (TEXT_SERVICES_MANAGER_SERVICE.equals(service)) { 
419   // we need to return a valid service to avoid NPE 
420   return TextServicesManager.getInstance(); 
421  } 
422 
423  // AutoCompleteTextView and MultiAutoCompleteTextView want a window 
424  // service. We don't have any but it's not worth an exception. 
425  if (WINDOW_SERVICE.equals(service)) { 
426   return null; 
427  } 
428 
429  // needed by SearchView 
430  if (INPUT_METHOD_SERVICE.equals(service)) { 
431   return null; 
432  } 
433 
434  throw new UnsupportedOperationException("Unsupported Service: " + service); 
435 } 

Lo que me parece particularmente desconcertante en esta rutina es que no veo cómo podría manejar el servicio de "audio", sin embargo BridgeContext.java y KeyboardView.java son ambos parte del código de Android, no las clases que he escrito incorrectamente.

Me agradecerán cualquier información que me ayude a comprender por qué ocurre este error y cómo evitarlo.

+0

Estoy enfrentando el mismo problema. Avíseme si resolvió este problema. Aquí está mi pregunta. [http://stackoverflow.com/questions/13884677/android-custom-keyboard-the-following-classes-could-not-be-instantiated] –

Respuesta

4

¿Está utilizando API 14 o superior? Si es así, ese es el problema. Supongo que es un error en esa versión. En API 11 funciona.

Si prueba API 11 tiene que hacer algún truco al anular el método getResources().Compruebe this para más información. Después de esto, funcionará.

En realidad, creo que no hay forma de pasar por esto desde su LatinKeyboardView en la API 14 (o tal vez superior) porque ni siquiera puede usar isInEditMode() porque definitivamente tiene que invocar el constructor de View con super. Y ese constructor intentará obtener el servicio del sistema de audio que simplemente falla porque supongo que intenta ejecutar esto en el editor gráfico de eclipse (en realidad recibí este error cuando traté de colocar mi vista personalizada en un diseño en el editor de diseño grafico)

Creo que la única forma de hackear esto es implementar su propio KeyboardView sin el getSystemService. Tal vez no debería llamar a ese método si isInEditMode == true.

+0

Por otros motivos, he eliminado el teclado de la aplicación, por lo tanto, esto es ya no es un problema para mí, pero puede serlo de nuevo si intento implementar otro teclado, gracias por la guía. – Ian

4

trata de un error en android.inputmethodservice.KeyboardView

El código no es

public KeyboardView(Context context, AttributeSet attrs, int defStyle) { 
... 
    mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 
... 
} 

Debe ser envuelto en isInEditMode() de verificación para omitir conseguir gestor de audio durante la edición de diseño. ¡Extraño pero no puedo encontrar ningún problema en el rastreador de errores de Android!

2

Encontré la solución.

Uso KeyboardViewFix como reemplazar KeyboardView:

public class KeyboardViewFix extends KeyboardView { 
    public static boolean inEditMode = true; 

    @TargetApi(21) // Build.VERSION_CODES.L 
    public KeyboardViewFix(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(inEditMode ? new ContextWrapperInner(context) : context, attrs, defStyleAttr, defStyleRes); 
    } 

    public KeyboardViewFix(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(inEditMode ? new ContextWrapperInner(context) : context, attrs, defStyleAttr); 
    } 

    public KeyboardViewFix(Context context, AttributeSet attrs) { 
     super(inEditMode ? new ContextWrapperInner(context) : context, attrs); 
    } 

    public static class ContextWrapperInner extends ContextWrapper { 
     Context base; 
     public ContextWrapperInner(Context base) { 
      super(base); 
      this.base = base; 
     } 
     public Object getSystemService(String name) { 
      return Context.AUDIO_SERVICE.equals(name) ? null : base.getSystemService(name); 
     }  
    } 
} 

Una nota: Al arrancar la aplicación, antes de cualquier otro código que necesita establecer KeyboardViewFix.inEditMode = false; o puede obtener algunos errores.

+0

Hola @Enyby, utilicé tu solución, pero edítala con la siguiente mejora (en mi nueva respuesta más abajo). – SRombauts

+0

@SRombauts Tienes razón. Este código es incorrecto y causará problemas. En particular, el 6 de Android. ContextWrapper necesita usar para este propósito. En casa corregí y luego lo olvidé. – Enyby

1

Mejoré la solución con @Enyvy al extender ContextWrapper en lugar de Context (mucho menos código). Usos clase ContextWrapper con la delegación de todos los métodos al contexto de base, excepto por el método getService() que se quiera pedir "audio":

public class ContextWrapperFix extends ContextWrapper { 
    private boolean editMode; 

    public ContextWrapperFix(Context context, boolean editMode) { 
     super(context); 
     this.editMode = editMode; 
    } 

    public Object getSystemService(String name) { 
     if (editMode && Context.AUDIO_SERVICE.equals(name)) { 
      return null; 
     } 
     return super.getSystemService(name); 
    } 
} 

El siguiente paso es crear propia clase extiende KeyboardView:

public class KeyboardViewFix extends KeyboardView { 
    public static boolean inEditMode = true; 

    @TargetApi(21) // Build.VERSION_CODES.L 
    public KeyboardViewFix(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(new ContextWrapperFix(context, inEditMode), attrs, defStyleAttr, defStyleRes); 
    } 

    public KeyboardViewFix(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(new ContextWrapperFix(context, inEditMode), attrs, defStyleAttr); 
    } 

    public KeyboardViewFix(Context context, AttributeSet attrs) { 
     super(new ContextWrapperFix(context, inEditMode), attrs); 
    } 

} 

Y use KeyboardViewFix como reemplazar KeyboardView.

Una nota: al iniciar su aplicación, antes de cualquier otro código debe configurar KeyboardViewFix.inEditMode = false; o puede obtener algunos errores.

+0

Si está utilizando un popupKeyboard con su teclado personalizado, al tocar el botón de cerrar en la ventana emergente causa una NullPointerException. – tagy22

0

He tenido este problema en el pasado, ahora lo actualicé a Android Studio 3.0.1 y no puedo reproducirlo más (puede haberse solucionado hace mucho tiempo, no abrí este proyecto por un tiempo) .

dos configuraciones que probé con AS3:

minSdkVersion 10, compileSdkVersion 26, support library 25.4.0 
minSdkVersion 14, compileSdkVersion 26, support library 27.0.2 

probablemente hubo un cambio en cómo funciona la Vista previa de Android Studio.

Cuestiones relacionadas