Подтвердить что ты не робот

Android - Неподдерживаемый сервис: аудио

Я пытаюсь понять и решить проблему и ошибку, которую я вижу в журнале рабочей области Eclipse, работая над Android-приложением, которое реализует IME. Я новичок в Android и Eclipse.

Ошибка: "com.utterkaos.keyboard.LatinKeyboardView не удалось создать экземпляр".

Связанная трассировка стека:

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

Соответствующая часть LatinKeyboardView.java:

public class LatinKeyboardView extends KeyboardView {

    static final int KEYCODE_OPTIONS = -100;

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

}

Строка 30 - это супер (контекст, attrs);

Глядя на KeyboardView.java, строка 376:

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

Здесь "Context.AUDIO_SERVICE" представляется строкой "audio", которая появляется в трассировке стека ошибок.

Соответствующий бит BridgeContext.java:

    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 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    }

То, что я нахожу особенно озадачивающим в этой подпрограмме, - это то, что я не вижу, как она может справиться с "звуковой" услугой, но BridgeContext.java и KeyboardView.java являются частью кода Android, а не классами, которые я написал неправильно.

Любые указатели, которые помогут мне понять, почему эта ошибка возникает и как ее избежать, было бы очень полезно.

4b9b3361

Ответ 1

Используете ли вы API 14 или выше? Если это так, проблема. Я предполагаю, что это ошибка в этой версии. В API 11 он работает.

Если вы попробуете API 11, вам нужно сделать некоторые взломы с переопределением метода getResources(). Для получения дополнительной информации просмотрите this. После этого он будет работать.

На самом деле я думаю, что нет никакого способа перескочить через это из вашего LatinKeyboardView на API 14 (или, может быть, выше), потому что вы даже не можете использовать isInEditMode(), потому что вам обязательно нужно вызвать конструктор View с супер. И этот конструктор попытается получить аудиосистему, которая просто просто терпит неудачу, потому что я предполагаю, что вы пытаетесь запустить ее в графическом редакторе eclipse (на самом деле я получил эту ошибку, когда попытался разместить свой собственный вид в макете в графическом редакторе макетов)

Я думаю, что единственный способ взломать это - реализовать собственный KeyboardView без getSystemService. Может быть, не следует вызывать этот метод, если isInEditMode == true.

Ответ 2

Это ошибка в android.inputmethodservice.KeyboardView

Ошибка кода

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

Он должен быть завернут в isInEditMode(), чтобы пропустить получение аудио-менеджера во время редактирования макета. Странно, но я не могу найти ни одной проблемы, о которой сообщалось в Android-трекер!

Ответ 3

Я нашел решение.

Используйте KeyboardViewFix в качестве замены 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);
        }       
    }
}

Одна заметка: перед запуском своего приложения перед любым другим кодом вам нужно установить KeyboardViewFix.inEditMode = false; или вы можете получить некоторые ошибки.

Ответ 4

Я улучшил решение @Enyvy, расширив ContextWrapper вместо Context (гораздо меньше кода). Использует класс ContextWrapper с делегированием всех методов в базовый контекст, за исключением метода getService(), который запрещает запрашивать "аудио":

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);
    }
}

Следующий шаг - создать собственный класс, расширяющий 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);
    }

}

И используйте KeyboardViewFix в качестве замены KeyboardView.

Одна заметка: перед запуском своего приложения перед любым другим кодом вам нужно установить KeyboardViewFix.inEditMode = false; или вы можете получить некоторые ошибки.

Ответ 5

У меня была эта проблема в прошлом, теперь я обновился до Android Studio 3.0.1, и я больше не могу воспроизвести (возможно, это было исправлено давно, я не открывал этот проект некоторое время).

Две конфигурации, которые я пробовал с AS3:

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

Возможно, произошли изменения в работе панели просмотра Android Studio.