🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

2回答

1067閲覧

続、TimePickerに対して端末設定言語と違う言語の設定について

jun74

総合スコア338

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

1クリップ

投稿2019/11/18 15:35

編集2019/11/18 16:25

前提・実現したいこと

Android4.4.4、5.1.1、7、8、9では問題なく動くのだが、Android4.1.2の端末GL07Sでは以下のエラーが発生し異常終了してしまうので、異常終了しないようにしたい。

TimePickerに対して端末設定言語と違う言語の設定について

試したこと

「Locale.UK」を「Locale.US」にしても異常終了します。
※言語として端末にUKはないがUSはあるのを確認しました。
「Locale.ENGLISH」でもダメでした。
また、「R.string.language_str」は「english」でも「japanese」でもダメです。
全て同じエラーで異常終了します。

発生している問題・エラーメッセージ

logcat

Caused by: java.lang.NullPointerException at android.view.ViewConfiguration.get(ViewConfiguration.java:343) at android.view.View.<init>(View.java:3243) at android.view.View.<init>(View.java:3307) at android.view.ViewGroup.<init>(ViewGroup.java:427) at android.widget.FrameLayout.<init>(FrameLayout.java:101) at android.widget.TimePicker.<init>(TimePicker.java:130) at com.a.b.CustomTimePicker.<init>(CustomTimePicker.java:26) at com.a.b.CustomTimePicker.<init>(CustomTimePicker.java:22)

該当のソースコード

※26行目と22行目のコメントは後付しました

java

1package com.a.b; 2 3import android.content.Context; 4import android.content.res.Configuration; 5import android.content.res.Resources; 6import android.os.Build; 7import android.support.annotation.Nullable; 8import android.support.v7.view.ContextThemeWrapper; 9import android.util.AttributeSet; 10import android.widget.TimePicker; 11 12import java.util.Locale; 13 14//stringsがenglishのときは英語設定用タイムピッカー 15public class CustomTimePicker extends TimePicker { 16 17 public CustomTimePicker(Context context) { 18 this(context, null); 19 } 20 21 public CustomTimePicker(Context context, @Nullable AttributeSet attrs) { 22//以下が22行目!! 23 this(context, attrs, Resources.getSystem().getIdentifier("timePickerStyle", "attr", "android")); 24 } 25 26 public CustomTimePicker(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 27//以下が26行目!! 28 super(new ContextLocaleWrapper(context, Locale.UK), attrs, defStyleAttr); 29 30 ((ContextLocaleWrapper) getContext()).resetDefaultLocale(); 31 } 32 33 private static class ContextLocaleWrapper extends ContextThemeWrapper { 34 35 @Nullable 36 private Locale defaultLocale = null; 37 38 private ContextLocaleWrapper(Context context, Locale locale) { 39 super(context, context.getTheme()); 40 41 Configuration configuration = new Configuration(context.getResources().getConfiguration()); 42 if(context.getString(R.string.language_str).equals("english") && Locale.getDefault().getLanguage().equals(Locale.ENGLISH.getLanguage()) == false){ 43 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 44 configuration.setLocale(locale); 45 configuration.setLayoutDirection(locale); 46 } else { 47 configuration.locale = locale; 48 } 49 } 50 applyOverrideConfiguration(configuration); 51 52 // N未満ではLocaleのデフォルト値を参照してしまうので対策 53 if(context.getString(R.string.language_str).equals("english") && Locale.getDefault().getLanguage().equals(Locale.ENGLISH.getLanguage()) == false){ 54 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && !Locale.getDefault().equals(defaultLocale)) { 55 defaultLocale = Locale.getDefault(); 56 Locale.setDefault(locale); 57 } 58 } 59 } 60 61 public void resetDefaultLocale() { 62 // N未満で書き換えたLocaleのデフォルト値を元に戻す 63 if(getString(R.string.language_str).equals("english") && Locale.getDefault().getLanguage().equals(Locale.ENGLISH.getLanguage()) == false){ 64 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && defaultLocale != null) { 65 Locale.setDefault(defaultLocale); 66 } 67 } 68 } 69 } 70}

補足情報(FW/ツールのバージョンなど)

Android Studio3.4
APIレベル14から28まで対象

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2019/11/18 19:11

デバッガでトレースの上, GL07S (か, カスタマイズされていなければ 4.1.2)の Android のソースを探して確認するのが一番かと思います.
jun74

2019/11/18 22:30

いつもありがとうございます。4.1.2のソースを探して確認とは具体的にどのようにすれば確認できるのでしょうか?
jimbe

2019/11/19 02:23

ブレークポイントを設定して実行すればある程度ソースが見えますので具体的に何が起きているのかは確認できると思いますが, メソッド呼び出しであちこち飛んで全体が見えにくいので, ソースがあると調べ易いです. ソースは, 例外に表示されたクラス名に source や download 等のキーワードを付けて検索すると Github 等に見つかることがあります. Android4 がどこまであるか(残っているか?) 分かりませんが.
jun74

2019/11/19 03:52

ありがとうございます。原因分かったような気がするので、試せたら続報書きます。
jun74

2019/11/19 16:24

無事問題解消できました! ありがとうございました。
guest

回答2

0

自己解決

jimbe様のヒントから原因特定できました。ありがとうございました。

以下、よりAndroid4.1.2のTimePickerのjavaを確認すると、「applyOverrideConfiguration」が丁度Android4.1.2から前で存在していないことが分かりました。

Androidソースコード検索サービス

従って以下のように改修し、問題が解消しました。

java

1 if (Build.VERSION.SDK_INT > 16) { 2 applyOverrideConfiguration(configuration); 3 }

投稿2019/11/19 16:23

jun74

総合スコア338

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakajika

2019/11/25 08:54

私のコードについてのご質問なのに遅くなっていまいすみません。android.support.v7.view.ContextThemeWrapperの内部で、API17未満の環境ではapplyOverrideConfigurationを呼んだ後にgetResourcesがnullを返してしまうようです。 https://android.googlesource.com/platform/frameworks/support/+/300475fc42431cefb0d8f1bfc70de1a7a052a501/v7/appcompat/src/main/java/android/support/v7/view/ContextThemeWrapper.java#111 これはこれでちょっと問題な気もしますがそれは置いておくとして、ご回答いただいた方法で対応としては問題ないと思います。
jun74

2019/11/25 17:52

いえいえ。いつもありがとうございます。 詳細と問題ないとのこと、ありがとうございます。
guest

0

at com.a.b.CustomTimePicker.<init>(CustomTimePicker.java:22)

エラーの最後の行が22行目と言っているのだから、まずはこちらから調べるべきです。

Java

1 public CustomTimePicker(Context context, @Nullable AttributeSet attrs) { 2//以下が22行目!! 3 this(context, attrs, Resources.getSystem().getIdentifier("timePickerStyle", "attr", "android")); 4 }

わざわざResources.getSystem().getIdentifier()を使う理由がわかりませんが、
これをandroid.R.attr.timePickerStyleに変えてあげると
Field requires API level 21という警告が出ます。
つまり、Android 5から追加されたので、それ以前では使えません。
(4.4.4で問題なく動く、とおっしゃっていますが、そこは謎ですが…)

投稿2019/11/19 11:44

編集2019/11/19 11:45
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jun74

2019/11/19 16:28

いつもありがとうございます。 何故か「ContextLocaleWrapper」の中のステップではエラーが表示されなかったのですが、「ContextLocaleWrapper」の中に原因がありました。 22行目はAndroid4.1.2でも直さなくても動くので、このままでと考えてます。
kakajika

2019/11/25 09:04

一応補足しておくと、android.R.attr.timePickerStyleはAndroid 3.xの頃から存在します。APIとしては公開されていなかっただけでAndroid内部では使われているので、Resources.getSystem().getIdentifier()を利用することによりアクセスすることができます。
退会済みユーザー

退会済みユーザー

2019/11/25 10:32

補足ありがとうございます。 なるほど、非公開のAPIでしたか。
jun74

2019/11/25 17:54

補足ありがとうございます。 非公開ってものもあるんですね。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問