android.view.accessibility.CaptioningManager $ 1.onChange中的NullPointerException

时间:2016-02-12 06:39:50

标签: android accessibilityservice

我从我的应用中看到了奇怪的崩溃报告。

android.view.accessibility.CaptioningManager$1.onChange (CaptioningManager.java:226)
android.database.ContentObserver.onChange (ContentObserver.java:145)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:703)

http://crashes.to/s/db9e325f0f5

启用辅助功能时似乎存在问题。但是我如何检测出错误出现在哪个UI元素或屏幕上?

我尝试在自己的设备上启用辅助功能并浏览所有应用程序屏幕,但是没有收到例外。

修改

在TextView中使用Span会导致此错误吗?

 // welcome text
 TextView welcome = (TextView) view.findViewById(R.id.home_user_name);
 welcome.setText(Html.fromHtml(getString(R.string.home_welcome_text, accountManager.getActiveUser())));
 // change...
 welcome.append(" ");
 SpannableString str = SpannableString.valueOf(getString(R.string.home_user_change));
 str.setSpan(new URLSpan(getString(R.string.home_user_change)) {
        @Override
        public void onClick(View view) {
            mGuiHandler.sendEmptyMessage(MESSAGE_CHANGE_USER);
        }
 }, 0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 welcome.append(str);
 welcome.setMovementMethod(LinkMovementMethod.getInstance());

1 个答案:

答案 0 :(得分:1)

首先,这不是可访问性服务API的一部分。它是View的可访问性实现的一部分。查看Google代码项目。 CaptioningManager位于core/java/android/view/accessibility包中。因此,无论可访问性是否开启,或者至少与可访问性服务无关,都会发生此崩溃。

在第235行的字幕管理器中(Google代码上的版本已过期,但非常接近。)。 onChange函数是这样的:

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        final String uriPath = uri.getPath();
        final String name = uriPath.substring(uriPath.lastIndexOf('/') + 1);
        if (Secure.ACCESSIBILITY_CAPTIONING_ENABLED.equals(name)) {
            notifyEnabledChanged();
        } else if (Secure.ACCESSIBILITY_CAPTIONING_LOCALE.equals(name)) {
            notifyLocaleChanged();
        } else if (Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE.equals(name)) {
            notifyFontScaleChanged();
        } else {
            // We only need a single callback when multiple style properties
            // change in rapid succession.
            mHandler.removeCallbacks(mStyleChangedRunnable);
            mHandler.post(mStyleChangedRunnable);
        }
    }

这是由ContentObserver类调用的,从这一点开始:

    /**
 * Dispatches a change notification to the observer. Includes the changed
 * content Uri when available and also the user whose content changed.
 *
 * @param selfChange True if this is a self-change notification.
 * @param uri The Uri of the changed content, or null if unknown.
 * @param userId The user whose content changed. Can be either a specific
 *         user or {@link UserHandle#USER_ALL}.
 *
 * @hide
 */
public void onChange(boolean selfChange, Uri uri, int userId) {
    onChange(selfChange, uri);
}

请注意,ContentObserver类的文档中明确指出uri可以为null,但CaptioningManager会立即调用getPath而不检查fi值是否为null。这就是崩溃的原因。传递给onChange的uri为空。

现在,这是一个有点模糊的地方。其余是私密的,Google Code上没有。所以,我们只能猜测合子正在做什么。虽然,即使我们能够看到它,它也可能不会有所帮助。

现在,我们可以从中收集什么。在CaptioningManager的文档中,我们看到了以下解释:

  

包含访问和监控首选视频的方法   字幕状态和视觉属性。

因此,基于所有这些,检查应用程序中任何视频和其他媒体元素的任何URI或其他属性......