tag:blogger.com,1999:blog-86595554444628269102024-09-05T16:54:45.015+09:00Androyer in JapanAndroidのプログラミングの記事です。Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]Blogger177125tag:blogger.com,1999:blog-8659555444462826910.post-37489812934179389262017-03-08T16:28:00.000+09:002017-03-08T16:30:17.947+09:00Some file crunching failedSome file crunching failed<br /><br />Android Studioを2.3に改版すると下記のエラーが発生した。<br /><br />Information:Gradle tasks [clean, :(省略):generateDebugSources, :(省略):generateDebugAndroidTestSources, :(省略):mockableAndroidJar, :(省略):prepareDebugUnitTestDependencies, :(省略):compileDebugSources, :(省略):compileDebugAndroidTestSources, :(省略):compileDebugUnitTestSources, :app:generateDebugSources, :app:mockableAndroidJar, :app:prepareDebugUnitTestDependencies, :app:generateDebugAndroidTestSources, :app:compileDebugSources, :app:compileDebugUnitTestSources, :app:compileDebugAndroidTestSources]<br /><br />15:54:20.374 [ERROR] [org.gradle.api.Project] AAPT err(Facade for 727369730): \\?\C:\Users\漢字\.android\build-cache\91d4fc3623f1db2e13d9719feb5cd41e8a96b0c9\output\res\drawable-xxhdpi-v4\googleg_standard_color_18.png ERROR: Unable to open PNG file<br /><br />解答は次のサイトを参照してください。<br />http://stackoverflow.com/questions/42580645/errorsome-file-crunching-failed-see-logs-for-details-afer-update-gradle<br /><br />原因:Windowsにおけるフォルダーの名前に2バイト文字を使用していたため。<br />解決方法:プロジェクトのルートにあるgradle.propertiesファイル内に、次の1行を書きこんでください。<br />android.enableBuildCache=false<br /> <br />又は、上記の値をtrueにした上で、ASCII文字だけで構成されるフォルダー名を下記のように設定します。<br />android.buildCacheDir=C:/akan-mata-bagu-ya/build-cacheAndroyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-72649541371018173702017-01-04T18:47:00.000+09:002017-01-06T09:39:08.903+09:00MY_PACKAGE_REPLACEDの動作確認MY_PACKAGE_REPLACEDの動作確認<br /> <br /> Android Studioで、初期設定のままでデバッグを行うと、開発中のアプリのインストールと起動とが連続して行われてしまう。本番の環境では連続して行われることはない。<br /> このままだと、action.MY_PACKAGE_REPLACEDに基づく動作確認が正確にできないかもしれない。<br /> <br /> これを別々に行うには下記の設定をする。<br /> Android Studio &gt; Run &gt; Edit Configurations... において、左上端の「+」を押し下げる。<br /> 「Android App」を選択する。<br /> General &gt; Installation Options &gt; Deploy 及び General &gt; Launch Options &gt; Launch には、各々「Nothing」という項目があるので、この項目を活用すれば、インストールと起動とを別々に(連続させずに)行うことができる。Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-50763038847567972692017-01-04T18:23:00.000+09:002017-01-04T18:23:15.687+09:00action.MY_PACKAGE_REPLACEDによる受信ができないaction.MY_PACKAGE_REPLACEDによる受信ができない<br /> <br /> デバッグ環境において、今まで正常に動作していたMY_PACKAGE_REPLACEDによる受信ができなくなった。<br /> Android端末を再起動すれば、受信できるようになりました。Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-63023093889630197022017-01-03T19:10:00.001+09:002017-01-03T19:11:09.221+09:00ContentResolver#query() return nullContentResolver#query() return null<br /> <br /> 古い機種は、端末の電源投入後、起動完了状態になるまで、1分以上かかる。<br /> この間(起動が完了していない状態。起動途中の段階)で、ContentResolver#query()を使うと、nullが返る。<br /> <br /> 起動途中の段階でgetContentResolver()を実行した場合であっても、利用可能なContentResolverが返されてくる。<br /> <br /> ContentResolver#query()を使いnullが返された場合、その原因が、起動途中の段階なのか、それともAndroidシステムに異常があるのか確認した方が良いかもしれない。<br /> 例えば、SystemClock#elapsedRealtime()とThread#sleep()を併用して、2分程度待つようにすれば良い。<br /> なお、elapsedRealtime()は、電源投入を起点とした経過時間をミリ秒単位で返す。<br /> <div> <br /></div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-6906589117157173402016-10-01T14:32:00.000+09:002016-10-01T14:32:03.334+09:00Android端末がWindowsで認識しないAndroid端末がWindowsで認識しない<br /> <br /> 今まで問題なく認識できていたAndroid端末が、2016年10月1日に、Windows10で認識できなくなりました。<br /> 私の事例の場合、Windows10に接続するUSB機器を、キーボード、マウス及びAndroid端末の3個だけにすれば、問題なくAndroid端末を認識できるようになりました。<br /> 第四番目に接続させていたUSB機器との相性が悪かったのかと思います。Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-11212756022835383852016-07-11T18:14:00.003+09:002016-07-11T18:14:54.971+09:00「データがありません」ANRに関する報告の受け取り「データがありません」ANRに関する報告の受け取り<br /> <br /> ANRの報告に「データがありません」という表示がされる場合があります。<br /> この場合、半日程度経ってから、ドラム缶アイコンから「クラッシュとANR」を選択し、ANRデータをCSVファイルで開発機にダウンロードして、見てください。<br /> そうすると、ある程度情報が記載させています。<br /> <br /> <br />Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-63901167090533779732016-03-09T19:36:00.000+09:002016-03-09T19:36:46.073+09:00BroadcastReceiverでIntent.ACTION_PACKAGE_REPLACEDを受け取るBroadcastReceiverでIntent.ACTION_PACKAGE_REPLACEDを受け取る<br /> <br /> アプリの改版を行った場合、アプリは、BroadcastReceiverでandroid.intent.action.PACKAGE_REPLACEDを受け取ります。<br /> このPACKAGE_REPLACEDに基づき実行されるコードは、旧版でしょうか、それとも新版でしょうか。<br /> <br /> 解答は、新版です。<br /> <br /> 何の根拠も無く、間違った方で、自分勝手に思い込みをしてしまわないようにしましょう。Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-89310773339156329712016-02-29T22:58:00.000+09:002016-02-29T23:05:46.808+09:00PreferenceFragmentを使って複雑なViewGroupを表示・操作したい場合PreferenceFragmentを使って複雑なViewGroupを表示・操作したい場合<br /> <br /> 表示する画面のxml:preference_version.xml<br /> &lt;?xml version="1.0" encoding="utf-8"?&gt;<br /> &lt;LinearLayout<br /> &nbsp; &nbsp; xmlns:android="http://schemas.android.com/apk/res/android"<br /> &nbsp; &nbsp; android:layout_width="match_parent"<br /> &nbsp; &nbsp; android:layout_height="wrap_content"<br /> &nbsp; &nbsp; android:orientation="vertical"<br /> &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &lt;TextView<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:layout_width="match_parent"<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:layout_height="wrap_content"<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:autoLink="web"<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:text="@string/test"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &lt;/TextView&gt;<br /> &nbsp; &nbsp; &lt;RelativeLayout<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:layout_width="match_parent"<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:layout_height="wrap_content"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &lt;TextView<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_width="wrap_content"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_height="wrap_content"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_centerVertical="true"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_alignParentLeft="true"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_alignParentStart="true"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:paddingTop="20dp"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:text="@string/app_name"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &lt;/TextView&gt;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &lt;TextView<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:id="@+id/TextView_Preference_Version"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_width="wrap_content"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_height="wrap_content"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_alignParentRight="true"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_alignParentEnd="true"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:layout_centerVertical="true"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:paddingTop="20dp"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &lt;/TextView&gt;<br /> &nbsp; &nbsp; &lt;/RelativeLayout&gt;<br /> &lt;/LinearLayout&gt;<br /> <br /> \res\xml\preferences.xml<br /> &lt;?xml version="1.0" encoding="utf-8"?&gt;<br /> &lt;PreferenceScreen<br /> &nbsp; &nbsp; xmlns:android="http://schemas.android.com/apk/res/android"<br /> &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &lt;PackageName.VersionPreference<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:key="PreferenceScreen_Version"<br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; android:layout="@layout/preference_version"ここがポイント</span><br /> <span style="color: red;">widgetLayoutを使うと適切に表示されない。</span><br /> &nbsp; &nbsp; &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &lt;/PackageName.VersionPreference&gt;<br /> &lt;/PreferenceScreen&gt;<br /> <br /> PackageName.VersionPreference.java<br /> public class VersionPreference extends Preference{<br /> &nbsp; &nbsp; private Context con;<br /> &nbsp; &nbsp; public VersionPreference(Context context){<br /> &nbsp; &nbsp; &nbsp; &nbsp; super(context);<br /> &nbsp; &nbsp; &nbsp; &nbsp; con = context;<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; @TargetApi(Build.VERSION_CODES.LOLLIPOP)<br /> &nbsp; &nbsp; public VersionPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {<br /> &nbsp; &nbsp; &nbsp; &nbsp; super(context, attrs, defStyleAttr, defStyleRes);<br /> &nbsp; &nbsp; &nbsp; &nbsp; con = context;<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; @TargetApi(Build.VERSION_CODES.LOLLIPOP)<br /> &nbsp; &nbsp; public VersionPreference(Context context, AttributeSet attrs, int defStyleAttr) {<br /> &nbsp; &nbsp; &nbsp; &nbsp; super(context, attrs, defStyleAttr);<br /> &nbsp; &nbsp; &nbsp; &nbsp; con = context;<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; public VersionPreference(Context context, AttributeSet attrs) {<br /> &nbsp; &nbsp; &nbsp; &nbsp; super(context, attrs);<br /> &nbsp; &nbsp; &nbsp; &nbsp; con = context;<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; @Override<br /> &nbsp; &nbsp; protected void onBindView(View view){<br /> &nbsp; &nbsp; &nbsp; &nbsp; super.onBindView(view);<br /> &nbsp; &nbsp; &nbsp; &nbsp; LinearLayout llParent = (LinearLayout) view;<br /> &nbsp; &nbsp; &nbsp; &nbsp; TextView tv = (TextView) llParent.findViewById(R.id.TextView_Preference_Version);<br /> &nbsp; &nbsp; &nbsp; &nbsp; PackageInfo pi;<br /> &nbsp; &nbsp; &nbsp; &nbsp; try{<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pi = con.getPackageManager().getPackageInfo(<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; con.getPackageName(),<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PackageManager.GET_ACTIVITIES<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Resources r = con.getResources();<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String s = r.getString(R.string.Version) + pi.versionName;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tv.setText(s);<br /> &nbsp; &nbsp; &nbsp; &nbsp; }<br /> &nbsp; &nbsp; &nbsp; &nbsp; catch(PackageManager.NameNotFoundException e){<br /> &nbsp; &nbsp; &nbsp; &nbsp; }<br /> &nbsp; &nbsp; }<br /> }<br /> <div> <br /></div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-67608867643620446642016-02-29T22:18:00.000+09:002016-02-29T22:18:29.520+09:00ListPreferenceを使って、longのデータを保存・読込を行うListPreferenceを使って、longのデータを保存・読込を行う<br /> <br /> ListPreferenceをそのまま使うと、保存・読込のデータはStringになる。<br /> これは不便だ。そこで、longによりデータの保存・読込を行う。<br /> <br /> public class myLP extends ListPreference{<br /> &nbsp; &nbsp; public myLP(Context context){<br /> &nbsp; &nbsp; &nbsp; &nbsp; super(context);<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; @TargetApi(Build.VERSION_CODES.LOLLIPOP)<br /> &nbsp; &nbsp; public myLP(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {<br /> &nbsp; &nbsp; &nbsp; &nbsp; super(context, attrs, defStyleAttr, defStyleRes);<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; @TargetApi(Build.VERSION_CODES.LOLLIPOP)<br /> &nbsp; &nbsp; public myLP(Context context, AttributeSet attrs, int defStyleAttr) {<br /> &nbsp; &nbsp; &nbsp; &nbsp; super(context, attrs, defStyleAttr);<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; public myLP(Context context, AttributeSet attrs) {<br /> &nbsp; &nbsp; &nbsp; &nbsp; super(context, attrs);<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; @Override<br /> &nbsp; &nbsp; protected void onSetInitialValue(boolean restoreValue, Object defaultValue){<br /> &nbsp; &nbsp; &nbsp; &nbsp; if(restoreValue){//long型データをファイルから読む。<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long lValue;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String s;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lValue = //PreferenceManager.getDefaultSharedPreferences()を使ってデータを読む。<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = String.valueOf(lValue);<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setValue(s);<br /> &nbsp; &nbsp; &nbsp; &nbsp; }<br /> &nbsp; &nbsp; &nbsp; &nbsp; else{//ファイルへ保存する。<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //このファイルへ保存する部分は、別途本体において、自分でプログラムする。<br /> &nbsp; &nbsp; &nbsp; &nbsp; }<br /> &nbsp; &nbsp; }<br /> }<br /> <div> <br /></div> <div> class SettingsFragment extends PreferenceFragmentにて</div> <div> &nbsp; &nbsp; @Override</div> &nbsp; &nbsp; public boolean onPreferenceChange(Preference preference, Object newValue){<br /> &nbsp; &nbsp; &nbsp; &nbsp; String sValue = (String)newValue;<br /> &nbsp; &nbsp; &nbsp; &nbsp; //Long.parseLong(sValue)を<br /> &nbsp; &nbsp; &nbsp; &nbsp; //PreferenceManager.getDefaultSharedPreferences()を使って保存する<br /> &nbsp; &nbsp; &nbsp; &nbsp; return true;<br /> &nbsp; &nbsp; }<br /> <div> <br /></div> <div> (参考)</div> <div> <a href="http://qiita.com/mumei_himazin/items/ce165941488aba6732a1" target="_blank">ListPreferenceで設定してある内容を表示</a></div> <div> <br /></div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-86876290631477357242016-02-06T18:51:00.001+09:002016-02-29T22:50:25.223+09:00PreferenceFragmentの評価<br /> <div> <span style="font-size: large;">PreferenceFragmentの評価</span></div> <div> Preference情報を基調としているPreferenceFragmentの評価はどうなのだろうか。</div> <div> CheckBoxPreference等ごく限られた道具しかない。データの出し入れに特化したものだ。画面表示関係には弱い。</div> <div> 例えば、PreferenceScreenにButtonを配置したい場合、どうするのか。</div> <div> <br /></div> <div> <div> &nbsp; &nbsp; @Override</div> <div> &nbsp; &nbsp; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; Preference preferenceButton = findPreference("PreferenceScreen_btnClose");</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; preferenceButton.setLayoutResource(R.layout.preference_button);</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; preferenceButton.setOnPreferenceClickListener(this);</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; return super.onCreateView(inflater, container, savedInstanceState);</div> <div> &nbsp; &nbsp; }</div> <div> <br /></div> </div> <div> <div> &nbsp; &nbsp; @Override</div> <div> &nbsp; &nbsp; public boolean onPreferenceClick(Preference preference){</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; if(preference==findPreference("PreferenceScreen_btnClose")){</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //ここでButton押し下げ関係処理をする</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; }</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; return false;</div> <div> &nbsp; &nbsp; }</div> </div> <div> <br /></div> <div> <div> &lt;?xml version="1.0" encoding="utf-8"?&gt;</div> <div> &lt;PreferenceScreen</div> <div> &nbsp; &nbsp; xmlns:android="http://schemas.android.com/apk/res/android"</div> <div> &nbsp; &nbsp; &gt;</div> <div> &nbsp; &nbsp; &lt;Preference</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; android:key="PreferenceScreen_btnClose"</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &gt;</div> <div> &nbsp; &nbsp; &lt;/Preference&gt;</div> <div> &lt;/PreferenceScreen&gt;</div> </div> <div> <br /></div> <div> R.layout.preference_button</div> <div> <div> &lt;?xml version="1.0" encoding="utf-8"?&gt;</div> <div> &lt;Button</div> <div> &nbsp; &nbsp; xmlns:android="http://schemas.android.com/apk/res/android"</div> <div> &nbsp; &nbsp; android:text="@string/aaaa"</div> <div> &nbsp; &nbsp; android:layout_width="match_parent"</div> <div> &nbsp; &nbsp; android:layout_height="wrap_content"</div> <div> <span style="color: red;">&nbsp; &nbsp; android:clickable="false"(必要)</span><br /> <span style="color: red;">&nbsp; &nbsp; android:focusable="false"</span><span style="color: red;">(必要)</span><br /> &nbsp; &nbsp; android:drawableStart="@android:drawable/ic_menu_close_clear_cancel"</div> <div> &nbsp; &nbsp; &gt;</div> <div> &lt;/Button&gt;</div> </div> <div> <br /></div> <div> 単純にクリックするだけであれば悩まない。</div> <div> 複雑なViewGroupを表示・操作したい場合どうするのか。</div> <div> <a href="http://typea.info/blg/glob/2010/10/android-android-hacks.html" target="_blank">Android 設定画面を簡単に作成する (ANDROID HACKS)</a></div> <div> <a href="http://stackoverflow.com/questions/5066405/how-do-i-change-the-layout-of-preferences-screen-in-android" target="_blank">how do i change the layout of preferences screen in android</a></div> <div> <a href="http://stackoverflow.com/questions/28290049/how-to-use-preference-setlayoutresource-using-object" target="_blank">How to use Preference.setLayoutResource() using object</a></div> <div> Preferenceを拡張して行うということである。職人技ですね。普通のプログラマーが自力だけでこのコードを書けるとは思えない。<br /> 「複雑な形状のViewの表示は別途画面を設けてください」というのが、本システム設計者の考え方かもしれない。<br /> <br /> <br /> <br /></div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-82688992262451403512016-02-06T18:50:00.001+09:002016-03-03T00:03:38.545+09:00SharedPreferencesSharedPreferences<br /> <br /> SharedPreferencesを用いてデータを保存する方法は2通りある。<br /> <br /> <span style="font-size: large;">その1.</span><br /> <div> Context.getSharedPreferences("thisName", Context.MODE_PRIVATE)を使う方法</div> <div> 簡単なサンプルは次のとおりです。<br /> <div> <blockquote class="tr_bq"> boolean b;<br /> SharedPreferences sp;<br /> sp = con.getSharedPreferences("thisName", Context.MODE_PRIVATE);<br /> b = sp.getBoolean("thisKey", false);</blockquote> </div> <div> <br /></div> <span style="font-size: large;">その2.</span><br /> PreferenceManager.getDefaultSharedPreferences()を使う方法<br /> <a href="http://techbooster.jpn.org/andriod/application/468/" target="_blank">データを簡単に保存する方法(Preference編)</a><br /> <br /> 両者の違いは次のサイトに解説されている。<br /> <a href="http://stackoverflow.com/questions/5946135/difference-between-getdefaultsharedpreferences-and-getsharedpreferences" target="_blank">Difference between getDefaultSharedPreferences and getSharedPreferences</a><br /> <div> 保存する名前(保存先)が異なるとのことである。機能に違いは無い。各々独立したデータとして取り扱うことになる。</div> <div> <br /> <span style="font-size: large;">仕掛け</span><br /> Preferencesによるデータはファイルに保存される。<br /> このファイル名は、Context.getSharedPreferences()であれば、その第一引数に指定した文字列になる。<br /> PreferenceManager.getDefaultSharedPreferences()の場合は、context.getPackageName() + "_preferences"という、固定された名前(プログラマーが指定できない名前)になる。<br /> <br /> このような名前を持つファイルの中に、任意の個数の、任意の名前のKeyが存在することになる。各々のKeyには、1個の何らかの値がくっついている。<br /> Keyを指定することにより、値を操作することができる。<br /> <br /> 保存先がファイルであるから、複数設けるとアクセスに時間がかかるかもしれない。ファイルは1個にまとめれば効率的かもしれない。<br /> <br /> <span style="font-size: large;">PreferenceFragmentで使いたい場合</span><br /> 既にContext.getSharedPreferences()を用いてアプリを運用してしまっている場合であって、これをPreferenceFragmentで使用したい場合、取り扱うデータをContext.getSharedPreferences()で保存・読込ができるようにしなければならない。<br /> \res\xml\preferences.xml<br /> &lt;PreferenceScreen<br /> &nbsp; &nbsp; xmlns:android="http://schemas.android.com/apk/res/android"<br /> &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &lt;CheckBoxPreference<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:key="ここにContext.getSharedPreferences()で使っているKeyを設定する"<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:title="...."<br /> &nbsp; &nbsp; &nbsp; &nbsp; android:summary="...."<br /> &nbsp; &nbsp; &nbsp; &nbsp; &gt;<br /> &nbsp; &nbsp; &lt;/CheckBoxPreference&gt;<br /> &lt;/PreferenceScreen&gt;<br /> <br /> PreferenceFragment.java<br /> &nbsp; &nbsp; @Override<br /> &nbsp; &nbsp; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){<br /> &nbsp; &nbsp; &nbsp; &nbsp; PreferenceManager pm;<br /> &nbsp; &nbsp; &nbsp; &nbsp; cbQuit = (CheckBoxPreference)findPreference("キー");<br /> &nbsp; &nbsp; &nbsp; &nbsp; pm = cbQuit.getPreferenceManager();<br /> &nbsp; &nbsp; &nbsp; &nbsp; pm.setSharedPreferencesName("名前");//取り扱うファイル名を変更する。<br /> &nbsp; &nbsp; &nbsp; &nbsp; boolean "値" = "変更後のファイルのキーから値を取得する"<br /> &nbsp; &nbsp; &nbsp; &nbsp; cbQuit.setChecked("値");<br /> <br /> チェックボックスが1個だけなら良いが、2個以上の場合、onPreferenceChange()においてしっかりと値を保存しておかねばならない(意味不明)。<br /> &nbsp; &nbsp; &nbsp; &nbsp; pbQuit.setOnPreferenceChangeListener(this);<br /> &nbsp; &nbsp; &nbsp; &nbsp; return super.onCreateView(inflater, container, savedInstanceState);<br /> &nbsp; &nbsp; }<br /> <br /> &nbsp; &nbsp; @Override<br /> &nbsp; &nbsp; public boolean onPreferenceChange(Preference preference, Object newValue){<br /> &nbsp; &nbsp; &nbsp; &nbsp; if(preference==cbQuit){<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; boolean b = (boolean)newValue;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ここで値を保存しておく)<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;<br /> &nbsp; &nbsp; &nbsp; &nbsp; }<br /> &nbsp; &nbsp; &nbsp; &nbsp; return false;<br /> &nbsp; &nbsp; }<br /> <div> <br /></div> <div> <br /></div> </div> </div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-39301175985729938462016-01-22T09:48:00.002+09:002016-01-22T09:48:58.358+09:00MountService No primary storage defined yet hacking together a stubMountService No primary storage defined yet hacking together a stub<br /> <br /> Android 6.0のエミュレータで上記のエラーが発生します。<br /> これが原因で他のアプリが動かなくなります。<br /> 解決方法は、このエラーが発生するエミュレータを捨てて、Android Virtual Device Managerで新規にエミュレータを作成してください。残念です。Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-73893550257248708922015-12-06T02:39:00.000+09:002015-12-06T02:39:06.506+09:00Windows 10 KB3116908 0x80070570Windows 10 KB3116908 0x80070570<br /> <br /> これは、パソコンのWindows 10 のシステム更新に関する情報です。<br /> <br /> x64 ベース システム用 Windows 10 バージョン 1511 の累積的な更新プログラム (KB3116908)<br /> に関する更新をしようとすると、<br /> エラーコード:(0x80070570)<br /> が発生します。これに関する回答は次のサイトにあります。<br /> <a href="http://answers.microsoft.com/en-us/windows/forum/windows_10-update/error-code-0x80070570-when-trying-to-download/0775e346-43fa-43d4-b6ef-2cbb4434f97f?auth=1" target="_blank">Error code: (0x80070570) - When trying to download Win10 pro cumulative (KB3116908)</a><br /> <br /> パソコンの"C:\Windows\SoftwareDistribution\Download"にあるフォルダーやファイルを全て削除すれば、上記エラーは無くなり、更新ができます。Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-20277462702896388782015-11-19T20:41:00.001+09:002015-11-19T20:41:56.564+09:00.InstantiationExceptionInstantiationException<br /> <br /> E/AndroidRuntime: &nbsp;Caused by: java.lang.InstantiationException: java.lang.Class&lt;xxxx.xxxx.xxxx&gt; cannot be instantiated<br /> <br /> 上記のエラーが出ました。原因は、下記のように、abstractが付いてしまっていたためでした。これを消すと直りました。何かの拍子に自動的に付加されてしまったものです。<br /> <br /> public abstract class MainActivity extends Activity<br /> <br /> 参考<br /> <a href="http://stackoverflow.com/questions/20225482/java-lang-instantiationexception-cant-instantiate-class-no-empty-constructor" target="_blank">java.lang.InstantiationException: can't instantiate class; no empty constructor</a>Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-33803466215316226582015-11-04T18:10:00.003+09:002015-11-04T18:14:13.204+09:00Resources: Converting to string: TypedValueResources: Converting to string: TypedValue<br /> <br /> W/Resources: Converting to string: TypedValue{t=0x12/d=0x0 a=1 r=0x1020351}<br /> 上記のような警告がLogに表示されることがあります。<br /> この警告が不要であれば、Android端末の「設定」&gt;「開発者向けオプション」&gt;「表示属性検査を有効にする」のチェックを外してください。Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-22155586727912256402015-11-03T01:29:00.000+09:002015-11-03T01:29:50.789+09:00MiniThumbFile: Unable to create .thumbnails directoryMiniThumbFile: Unable to create .thumbnails directory<br /><br />Android 6.0で上記エラーが発生しました。<br />AndroidManifest.xmlファイルに下記のとおり追記すると解決しました。<br />&lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&gt;<div> <br /></div> <div> 参考</div> <div> <a href="http://stackoverflow.com/questions/9734394/create-a-thumbnail-of-a-video-file-in-sdcard" target="_blank">Create a thumbnail of a video file in sdcard</a></div> <div> <br /></div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-8447145128543253312015-10-25T21:54:00.000+09:002015-10-30T01:56:19.314+09:00Requesting Permissions at Run TimeRequesting Permissions at Run Time<br /> <br /> AndroidのエミュレーターをAndroid 6.0 (API level 23、Marshmallow)にすると、mkdir()が動作しなくなった。<br /> また、次のようなエラーも出るようになった。<br /> Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/video/media from pid=2627, uid=10058 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()<br /> <div> <br /></div> これは次の事情による。<br /> <a href="http://developer.android.com/intl/ja/about/versions/marshmallow/android-6.0-changes.html#behavior-runtime-permissions" target="_blank">Android 6.0 Changes</a> &gt; Runtime Permissions<br /> <a href="http://developer.android.com/intl/ja/training/permissions/requesting.html" target="_blank">Requesting Permissions at Run Time</a><br /> <br /> この問題をとりあえず解決するには、そのエミュレータ(端末)の「設定」&gt;アプリ&gt;(開発中のアプリを選択)&gt;Permissionsを選択し、必要とするpermissionにチェックを入れればよろしい。<br /> <br /> でも、その程度で解決する話ではないんだよね。<br /> <br /> 6.0では実行時に、permissionの許諾を端末利用者から得ることになる。インストール時ではない。<br /> <br /> 6.0からは、従前のpermissionに対し、上位概念のpermissionが設けられた。<br /> 従前のpermisssionは、例えば、ファイル操作関係であれば次のようなものだ。<br /> &nbsp; &nbsp; &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;<br /> AndroidManifest.xmlファイルにある、お馴染みさんである。<br /> <br /> これに対して、6.0では、上位概念のpermissionとして、例えば、「STORAGE」が設けられた。<br /> STORAGEは、下位に、READ_EXTERNAL_STORAGEとWRITE_EXTERNAL_STORAGEの2個のpermissionを含んでいる。<br /> この上位-下位の関係性は<a href="http://developer.android.com/intl/ja/guide/topics/security/permissions.html#normal-dangerous" target="_blank">System Permissions</a>の表に掲示されている。上位概念は「Permission Group」という用語で説明されている。<br /> <br /> 上述の操作「設定」&gt;アプリ&gt;(開発中のアプリを選択)&gt;Permissionsにおいて表示される文字列(コマンド)は、この上位概念のpermissionである。このpermissionに許可を与えれば、READ_EXTERNAL_STORAGEとWRITE_EXTERNAL_STORAGEの2個の許可を与えたことになる(アプリが、それらを使うのであれば)。<br /> <br /> Javaのプログラミング上では、上述の「上位概念」(Permission Group)は登場しないし、書く必要はない。引き続き、従前のpermission用語を使えば良い。<br /> <br /> 1個の下位概念のpermissionの使用に対して端末利用者の許諾を得たのであれば、その上位概念の許諾を得たことになるので、配下の他の下位概念で許諾を得る必要はない。<br /> 上位概念単位で端末利用者に許可を得ることになっている。<br /> <br /> どのpermissionで対応すべきかは、上記のように、エラーメッセージの中に記されている。<br /> <br /> <div> 端末利用者に許諾を得るタイミングは、permissionに関するメソッドを使用する前であれば、いつでも良い。一般的には、onCreate()において実施することになるのであろう。<br /> <br /> 留意すべきは、これは「許諾を得る」という次元の話である。<br /> プログラムの実行時の制約は、下位概念のpermission毎に個別に異なる。例えば、readだけを使って上位概念の許諾を得ていた場合、writeの実行はできない。この場合、writeの実行時には地味なエラーになる。一旦許諾を得てしまえば、上記のような親切なエラーメッセージは何も表示されないので、何故エラーなのか悩むかもしれない。<br /> readができるように許諾を得た後で、こそっと、その許諾に関するコードをwriteに変更したとしても、許諾関連には何も影響はない。そして、writeを実行できるようになる。</div> <div> <br /></div> <div> Javaのコードは、教科書<a href="http://developer.android.com/intl/ja/training/permissions/requesting.html" target="_blank">Requesting Permissions at Run Time</a>に書かれてあるとおりである。</div> <div> なお、build.gradleファイルには次のとおり追加する。</div> <div> <div> dependencies {</div> <div> &nbsp; &nbsp; compile 'com.android.support:support-v4:23.1.0'</div> <div> }</div> </div> <div> <br /></div> <div> <pre style="background-color: white;"><span style="font-family: Lucida Sans Typewriter;"><span style="font-size: 14.4px;"> /* onCreate()から呼ばれる。 */ private boolean MyCheckPermission(){ if(BuildConfig.DEBUG) Log.d(TAG, "MyCheckPermission()"); int i; i = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); if(i==PackageManager.PERMISSION_GRANTED){//既に許諾を得ている場合。 //Android 6.0未満の場合、自動的にここに来る。バージョンによる振り分けをする必要はない。 if(BuildConfig.DEBUG) Log.d(TAG, "MyCheckPermission() checkSelfPermission() is GRANTED"); return true;//起動に必要な残りの処理を実行する。 } //一度許諾を与えると、2度と、下記処理を行わない。 else{//まだ許諾を得ていない場合 boolean b; b = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE); if(b){//いきなり設定画面を表示するのではなく、permissionの必要性を(開発者の言葉で)説明する画面を表示する(任意)。 //普通は、ここに来る。 if(BuildConfig.DEBUG) Log.d(TAG, "MyCheckPermission() shouldShowRequestPermissionRationale is true"); Intent it = new Intent(MainActivity.this, PermissionActivity.class); startActivityForResult(it, Nippon.ID_REQUEST_READ_EXTERNAL_STORAGE); } else{ if(BuildConfig.DEBUG) Log.d(TAG, "MyCheckPermission() shouldShowRequestPermissionRationale is false"); /* 端末利用者が「二度とこの質問をしない」というチェックボックスにチェックしている場合、ここに来る。</span></span></pre> <pre style="background-color: white;"><span style="font-family: Lucida Sans Typewriter;"><span style="font-size: 14.4px;"> 下記を実行することにより、過去の回答を自動で読み取る。画面に質問用画面を表示しない。</span></span></pre> <pre style="background-color: white;"><span style="font-family: Lucida Sans Typewriter;"><span style="font-size: 14.4px;">また、アンインストールをした後、再度インストールをした場合も、ここに来る。この場合、画面に質問用画面を表示する。 </span></span></pre> <pre style="background-color: white;"><span style="font-family: Lucida Sans Typewriter;"><span style="font-size: 14.4px;"> */ ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Nippon.ID_REQUEST_READ_EXTERNAL_STORAGE ); } return false;//処理を、一旦、中断する。 } }</span></span><span style="font-family: 'Lucida Sans Typewriter'; font-size: 10.8pt;"> </span></pre> <div> <br /></div> <pre style="background-color: white;"><span style="font-family: Lucida Sans Typewriter;"><span style="font-size: 14.4px;"> @Override protected void onActivityResult(int iRequest, int iResult, Intent it){ if(BuildConfig.DEBUG) Log.d(TAG, "onActivityResult()"); switch(iRequest){ case Nippon.ID_REQUEST_READ_EXTERNAL_STORAGE: if(iResult==RESULT_OK){ /* 下記を実行するとAndroidシステム御用達の画面が表示され、READ_EXTERNAL_STORAGEを許可しますか? という趣旨の文言で聞かれる。 端末利用者の選択結果はonRequestPermissionsResult()で受け取る。 端末利用者が「二度とこの質問をしない」というチェックボックスにチェックすると、「拒否」しか選択できない表示になる(「承諾」を選択できない) アプリの運用途中で「拒否」&「2度と質問しない」をしてしまい、かつ、やっぱり気が変わって使いたいって思った場合、 端末利用者は、手動で設定を変更しなければならない。 */ ActivityCompat.requestPermissions( this, //一度に、複数のpermissionを設定できるようにするため、配列形式になっている。 new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Nippon.ID_REQUEST_READ_EXTERNAL_STORAGE ); } else finish();//「戻る」キーで戻った場合 break; } super.onActivityResult(iRequest, iResult, it); } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case Nippon.ID_REQUEST_READ_EXTERNAL_STORAGE: if (grantResults.length &gt; 0 &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) { continue_onCreate(); } else finish(); } }</span></span></pre> <pre style="background-color: white;"></pre> </div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-12543633766674017272015-10-10T08:40:00.001+09:002015-10-10T09:25:56.039+09:00google.android.gms.ads.AdActivitygoogle.android.gms.ads.AdActivity<br /> <br /> google.android.gms.ads.AdActivityを使用しない場合(Admobの広告を使用しない場合)であっても、<br /> \app\build\intermediates\manifests\full\debug\AndroidManifest.xmlファイルの下方には、次のように自動的に記載される。何故このような仕様にしているのかは問わない。<br /> <br /> &nbsp; &nbsp; &nbsp; &nbsp; &lt;!-- Include the AdActivity and InAppPurchaseActivity configChanges and themes. --&gt;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &lt;activity<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:name="com.google.android.gms.ads.AdActivity"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:theme="@android:style/Theme.Translucent" /&gt;<br /> &nbsp; &nbsp; &nbsp; &nbsp; &lt;activity<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:name="com.google.android.gms.ads.purchase.InAppPurchaseActivity"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; android:theme="@style/Theme.IAPTheme" /&gt;<br /> <div> <br /></div> <div> 普段は人畜無害なので冬眠中の虫のようなものだ。</div> <div> しかし、この記述内のandroid:configChangesの記載にエラーがあるという趣旨で、Build&gt;Rebuild Projectの時、及びGenerate Signed APK...の時にエラーが発生した、</div> <div> <br /></div> <div> 止むを得ないので、gms系のを全部削除した。<br /> すると、新たなエラーが発生した。<br /> gms系のエラーは真の原因では無く、闇の大ボスがいるようである。むむむ!<br /> <br /> そこで、<span style="background-color: white; font-family: 'Lucida Sans Typewriter'; font-size: 10.8pt;">Proguardの設定ファイル内に次の行を書き込んでみた。</span><br /> <pre style="background-color: white; font-family: 'Lucida Sans Typewriter'; font-size: 10.8pt;">-dontwarn com.google.android.gms.**</pre> <pre style="background-color: white; font-family: 'Lucida Sans Typewriter'; font-size: 10.8pt;">すると、闇の大ボスは出なくなった。</pre> <pre style="background-color: white; font-family: 'Lucida Sans Typewriter'; font-size: 10.8pt;">gmsを使ってないのに!!!</pre> <br /> Androidのプログラミングの難易度は結構高めです。</div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-31683209800511620482015-09-06T05:12:00.002+09:002015-09-06T05:12:54.983+09:00動画を連続再生させるアプリ動画を連続再生させるアプリ<br /> <br /> 動画を連続再生させるアプリ「動画ん君」を開発・公開しました。<br /> アプリ起動時に、自動的に、再生リストに基づき、動画の再生を開始できます。<br /> お気軽にお使いください。<br /> <br /> <a href="https://play.google.com/store/apps/details?id=jp.androyer.playmp4">https://play.google.com/store/apps/details?id=jp.androyer.playmp4</a><br /> <br />Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-44492672741983983602015-08-30T04:30:00.000+09:002015-08-30T04:30:00.300+09:00launchMode="singleTop"に設定しているにも関わらずlaunchMode="singleTop"に設定しているにも関わらず<br /><br />端末利用者によるHomeKeyの押し下げにより、Activityは見えなくなるが、存在はする。<br />アプリのアイコンをクリックすると、当該Activityは、onCreate()ではなく、onStart()から始まり、表示される。<br />HomeKeyを押し下げてActivityが消えた時点で、<br />端末利用者がファイラーを使って、関連ファイルをクリックし、ImplicitIntentにより、当該Activityの起動が試みられると、<br />launchMode="singleTop"に設定しているにも関わらず。<br />既存のActivityがonNewIntent()でメッセージを受けるのではなく、<br />新たなActivityがonCreate()で起動してくる。<br />こうなると、2個のActivityが存在することになる。オブジェクトとしては別物である。<br />アプリのアイコンをクリックすると、古い方のActivityが動作・表示される。<br />こんな仕様だとは思わなかった。アプリを作りこんでから分かった。むむむ!Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-8100967753041344582015-08-28T00:05:00.000+09:002015-08-28T00:06:35.368+09:00MediaControllerのバグかもしれないMediaControllerのバグかもしれない<br /> <br /> <ol> <li>VideoViewを使って、横位置FullScreenで動画を再生させる。</li> <li>MediaControllerを使って、pauseを手動で行う。動画は停止状態になる。</li> <li>端末を縦位置にする。configuration changeを発生させる。</li> <li>Logが真っ赤になる。</li> </ol> <br /> 真っ赤に流れるボクのLogCat<br /> 同じことを2回行うと、端末が反応しなくなり、再起動が必要になる。<br /> <br /> <span style="color: red;">E/WindowManager﹕ android.view.WindowLeaked: Activity jp.androyer.playmp4.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{2210feb8 V.E..... R....... 0,0-1280,117} that was originally added here</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl.&lt;init&gt;(ViewRootImpl.java:370)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.widget.MediaController.show(MediaController.java:349)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.widget.MediaController.show(MediaController.java:306)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.widget.VideoView.toggleMediaControlsVisiblity(VideoView.java:697)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.widget.VideoView.onTouchEvent(VideoView.java:638)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.View.dispatchTouchEvent(View.java:7767)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1931)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1931)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1931)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1931)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1931)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2072)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1518)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.app.Activity.dispatchTouchEvent(Activity.java:2531)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2020)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.View.dispatchPointerEvent(View.java:8004)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4136)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3990)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3548)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3598)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3567)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3674)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3575)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3731)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3548)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3598)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3567)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3575)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3548)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5817)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5797)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5768)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.os.MessageQueue.nativePollOnce(Native Method)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.os.MessageQueue.next(MessageQueue.java:138)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.os.Looper.loop(Looper.java:131)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.app.ActivityThread.main(ActivityThread.java:5257)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at java.lang.reflect.Method.invokeNative(Native Method)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at java.lang.reflect.Method.invoke(Method.java:515)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)</span><br /> <span style="color: red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at dalvik.system.NativeStart.main(Native Method)</span><br /> <br /> 解答は次のサイトにあった。<br /> <a href="http://stackoverflow.com/questions/21678444/android-mediaplayer-with-mediacontroller-logcat-error-activity-has-leaked-wind" target="_blank">Android MediaPlayer with MediaController: LogCat error “Activity has leaked window that was originally added here”</a><br /> <br /> <pre style="background-color: white; font-family: 'Lucida Sans Typewriter'; font-size: 10.8pt;"><span style="background-color: #e4e4ff;">onSaveInstanceState()や</span><span style="font-size: 10.8pt;">onCreate(Bundle </span><span style="background-color: #e4e4ff; font-size: 10.8pt;">savedInstanceState</span><span style="font-size: 10.8pt;">)による作り込みを完成させてから、こんな現象が発生することを知った。むむむ!</span></pre> <pre style="background-color: white; font-family: 'Lucida Sans Typewriter'; font-size: 10.8pt;"></pre> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-6584192920822536842015-08-18T19:14:00.000+09:002015-08-18T19:14:11.898+09:00常駐考察メモ<div> 常駐考察メモ</div> <div> <br /></div> 私の出荷済アプリにおいては、参照カウンターを設けて、これがゼロになると、データベースを閉じる&アプリ終了するという方法を採用していた。<br />しかしながら、下記エラーが発生するという報告が利用者から来た。<br /><br />Caused by: java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.<br /><br />上記エラーへの対応方法をネットで調べると、「データベースを閉じるな」という方法が提案されている。<br />onDestroy()においてデータベースclose()しているにも関わらず、上記エラーが発生しているという状況から察するに、このclose()の後で、onStartCommand()がメッセージを受け取っているということが推測させる。<br />もはや、どうすることもできません。<br /><br />●データベースを管理する。<br />●外部から不意のメッセージを受け取る<br />この2個の条件を満足させるためには、常駐化しかないかも。<div> <br /></div> <div> 参考:NotificationListenerServiceを実装させたアプリでは、NotificationListenerServiceは常駐している。また、類似アプリの振る舞いを観察しても、常駐させている。</div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-73641661527873721332015-08-18T18:23:00.001+09:002015-08-18T18:23:57.618+09:00NotificationListenerServiceに関する実験メモNotificationListenerServiceに関する実験メモ<br /><br />【1】bindについて<br />NotificationListenerServiceは、Serviceであるため、まさにそのとおりに使えるのではないかという仮説を立てて、<br />1.Activityとbindで結ぶ<br />2.データベースの管理<br />3.NotificationListenerServiceとしての本来機能<br />の3個を、この順番で、実行をさせてみた。<br />上位2個までは順に順調に実行が完了していった。<br />本体の「設定」&gt;「通知へのアクセス」&gt;本アプリの選択したあと、通知(Notification)を受け取るようにしてみたところ、次のようなエラーが出た。<br /><br />W/Parcel﹕ **** enforceInterface() expected 'android.os.IMessenger' but read 'android.service.notification.INotificationListener' W/Binder﹕ Caught a RuntimeException from the binder stub implementation. java.lang.SecurityException: Binder invocation to an incorrect interface at android.os.Parcel.nativeEnforceInterface(Native Method) at android.os.Parcel.enforceInterface(Parcel.java:451) at android.os.IMessenger$Stub.onTransact(IMessenger.java:48) at android.os.Binder.execTransact(Binder.java:404) at dalvik.system.NativeStart.run(Native Method)<br /><br />残念なことに、私には詳細を調べる能力や気力はありません。<br />NotificationListenerServiceは、本体設定&gt;「通知へのアクセス」の設定が行われた直後に、本来機能として「何か」とbindします。<br />しかしながら、上記実験プログラムでは、NotificationListenerServiceは、一番最初にActivityとbindしてしまっているため、上記エラーが発生したものと推測します。<br /><br />推測ですが、NotificationListenerServiceは、「Avtivityとのbind」との共存はできないのかもです。<div> <br /></div> <div> 【2】他のアプリからのIntent</div> <div> 他のアプリからIntentで、NotificationListenerServiceにアクセスしようとすると、クラッシュする。<br /><div> 6736-6736/jp.androyer.vivitovib E/AndroidRuntime﹕ FATAL EXCEPTION: main</div> <div> &nbsp; &nbsp; Process: jp.androyer.vivitovib, PID: 6736</div> <div> &nbsp; &nbsp; java.lang.SecurityException: Not allowed to start service Intent { flg=0x20000000 cmp=jp.Androyer.NotificationLauncher/.NService (has extras) } without permission android.permission.BIND_NOTIFICATION_LISTENER_SERVICE</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1571)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.app.ContextImpl.startService(ContextImpl.java:1548)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.content.ContextWrapper.startService(ContextWrapper.java:495)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at jp.androyer.vivitovib.Nippon$exportList.onPostExecute(Nippon.java:651)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at jp.androyer.vivitovib.Nippon$exportList.onPostExecute(Nippon.java:638)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.os.AsyncTask.finish(AsyncTask.java:632)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.os.AsyncTask.access$600(AsyncTask.java:177)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.os.Handler.dispatchMessage(Handler.java:102)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.os.Looper.loop(Looper.java:149)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at android.app.ActivityThread.main(ActivityThread.java:5257)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at java.lang.reflect.Method.invokeNative(Native Method)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at java.lang.reflect.Method.invoke(Method.java:515)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)</div> <div> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; at dalvik.system.NativeStart.main(Native Method)</div> <div> <br /></div> クラッシュを引き起こさせるとは、とても思い罪を犯したということですね。</div> <div> <br /></div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-2070105063083499422015-07-27T20:03:00.001+09:002015-07-27T20:03:38.436+09:00鳴り分け君1号新作アプリを開発・公開しました。<br /><br />通知の内容を基に、音楽や振動パターンを鳴り分けます。<br />無料ですのでお気軽にお使いください。<br /><br />製品名:鳴り分け君1号<br />読み方:なりわけくんいちごう<br /><br /><a href="https://play.google.com/store/apps/details?id=jp.Androyer.NotificationLauncher">https://play.google.com/store/apps/details?id=jp.Androyer.NotificationLauncher</a><br /><div> <br /></div> <div> <br /></div> <div> その2</div> <div> <div> 端末の振動パターンを編集できるアプリです。</div> <div> 編集後の振動パターンは拙作「鳴り分け君1号」で利活用することになります。</div> <div> 無料ですのでお気軽にお使いください。</div> </div> <div> <br /></div> <div> <div> 製品名:びびっとバイブ</div> <div> 英語名:ViviToVib</div> </div> <div> <br /></div> <div> <a href="https://play.google.com/store/apps/details?id=jp.androyer.vivitovib" target="_blank">https://play.google.com/store/apps/details?id=jp.androyer.vivitovib</a></div> <div> <br /></div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0tag:blogger.com,1999:blog-8659555444462826910.post-41624237995516795292015-06-08T00:32:00.000+09:002016-01-05T18:57:58.629+09:00Could not reserve enough space for object heap以前下記のような趣旨のエラーが出たように記憶しており、その回避のために、Android Studio&gt;File&gt;Settings&gt;Build Tools&gt;Compiler&gt;VM Options欄にheapサイズを大きくすべく -Xmx????m などと書いた。<br /> しかしながら、また、下記のエラーが出た。今回は、VM Options欄を空欄にしてみた。そうすれば、エラーは無くなった。むむむ!<br /> <br /> そして、その後また同様のエラーが発生した。<br /> -Xmx512m と書くとエラーが無くなった。数値が大きければ良いというものでは無いらしい。<br /> <br /> Error:Unable to start the daemon process.<br /> This problem might be caused by incorrect configuration of the daemon.<br /> For example, an unrecognized jvm option is used.<br /> Please refer to the user guide chapter on the daemon at http://gradle.org/docs/2.2.1/userguide/gradle_daemon.html<br /> Please read the following process output to find out more:<br /> -----------------------<br /> Error occurred during initialization of VM<br /> Could not reserve enough space for object heap<br /> Error: Could not create the Java Virtual Machine.<br /> Error: A fatal exception has occurred. Program will exit.<br /> <br /> <br /> その後、Android Studioが1.3になると、VM Options欄が消失していた。いままでの苦労はなんだったんだろうか。<br /> <br /> 2015/08/08 また出てしまった。<br /> Error:Unable to start the daemon process: could not reserve enough space for object heap.<br /> Please assign more memory to Gradle in the project's gradle.properties file.<br /> For example, the following line, in the gradle.properties file, sets the maximum Java heap size to 1,024 MB:<br /> <div> Windowsを再起動したり、Android Studioを再起動したりすると、このエラーは消える。むむむ!<br /> <br /> 2015/08/13 また出てしまった。Android Studio 1.3.1<br /> Error:Unable to start the daemon process: could not reserve enough space for object heap.<br /> Please assign more memory to Gradle in the project's gradle.properties file.<br /> For example, the following line, in the gradle.properties file, sets the maximum Java heap size to 1,024 MB:<br /> org.gradle.jvmargs=-Xmx1024m<br /> <br /> 2015/08/27 また同じのが出てしまった。Android Studio 1.3.2<br /> Error:Unable to start the daemon process: could not reserve enough space for object heap.<br /> Please assign more memory to Gradle in the project's gradle.properties file.<br /> For example, the following line, in the gradle.properties file, sets the maximum Java heap size to 1,024 MB:<br /> org.gradle.jvmargs=-Xmx1024m<br /> Windowsを再起動すれば直るため、このエラーメッセージの内容は参考程度ですね。<br /> <br /> 2016/01/05 Android Studio 1.5.1<br /> この問題は、Android Studio の問題では無く、Windowsが発生させているようです。<br /> 上記のように、オプション欄にいろいろ数値を代入していじくっても解決しません。<br /> よく発生するのは、Windowsのシステムアップデートの時です。事前に、Windowsのシステムアップデートをしっかり定着させておきましょう。<br /> それでも、本日は、頻繁に発生してしまいました。Windowsのいわゆる「起動マネージャ」を使い、Windowsの起動時に起動されてしまうアプリを見直してみましょう。私の場合、この確認行為をしただけで、実際には何も変更を加えていないにも関わらず、Android studioの問題が消失しました。むむむ。</div> Androyerhttp://www.blogger.com/profile/15862475742364888493[email protected]0