Android7 で android.os.FileUriExposedException が発生した時の対処方法です。 (文中の【】は読み替えて下さい) 0. 環境 [Windows] 7 [Java] 1.8 [Android] 5.1.1 [Android API] 26 1. 問題 Androidアプリから一時ファイルを作成して、そのURIを外部のアプリに渡すという処理を実装してました。 (ファイルを作成して、Gmailに添付するなど) Android7からfile://による指定ができなくなったため、下記のエラーが発生します。 android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/【アプリのパッケージ名】/temporary/【一時ファイル名】 exposed beyond app through ClipData.Item.getUri() URIはFileProviderで作らないといけないそうです。 2. 対策 2-1. AndroidManifest.xml まず、AndroidManifest.xmlにFileProviderの定義を追加します。 android:resourceには、2-2で作成するファイル名を指定。 2-2. res/xml/provider_paths.xml 次に、res/xml/provider_paths.xml を作成します。 後述の2-3でfileの保存先を Environment.getExternalStorageDirectory() の直下にしたので、それを表すexternal-pathを指定します。 また、直下なのでpathはカレントディレクトリになります。 2-3. 該当処理を行っているActivity 最後に、URIの生成を下記(1)から(2)に変更しました。 3. 参考 FileProviderリファレンス ...
MonitでApacheとMySQLを復旧
MonitでApacheとMySQLを復旧させる最低限の設定です。 (文中のドメイン名やメールアドレスは読み替えて下さい) 0. 環境 [CentOS] 6.4 (64bit版カーネル) [Monit] 5.25.1 [Apache] 2.2.15 [MySQL] 5.1.73 1. セットアップ インストール # yum install monit 自動起動を設定 # chkconfig monit on 2. 設定 2-1. Apacheの監視設定 httpd.conf を開いて、 # vim /etc/monit.d/httpd.conf 下記を記載。 check process httpd with pidfile /var/run/httpd/httpd.pid start program = "/etc/init.d/httpd start" stop program = "/etc/init.d/httpd stop" if 5 restarts within 5 cycles then timeout if failed host example. ...
【Androidアプリ開発】 "Socket is closed" エラー
0. 環境 [Windows] 7 [Java] 1.8 [Android] 5.1.1 [Android API] 26 1. 問題 Androidアプリの開発で、自前のAPIからデータを取得する処理を組んでいたところ、下記エラーが発生するようになりました。 java.net.SocketException: Socket is closed コードはこちら。 2. 対策 まずAPI側でApacheのログを確認したところ、ステータスコード200で問題なしでした。 127.0.0.1 - - [05/May/2018:22:55:02 +0900] "POST /api/test HTTP/1.0" 200 11130 正常終了するケースとの違いは、レスポンスのデータ量が多くなってることかな。(上記ログ右端) 次にAndroidアプリ側の処理があやしいと考えて、いろいろ試した結果、HttpsURLConnectionのクローズのタイミングが問題だと分かりました。 同オブジェクトを参照しているオブジェクトを全て使い終わってから、クローズする必要がありそうです。(上記(1)→(2)に移す) また、クローズ処理を消すだけでも冒頭のエラーは出なくなりましたが、なるべくオブジェクトは明示的に閉じた方が良いと思います。 なので、最終的にオブジェクトの作成順とは逆にクローズしていく処理を入れました。(下記(3)(4)) ...
Let's Encrypt - ドメイン削除
更新日:2018年05月01日 0. 環境 [CentOS] 6.4 (64bit版カーネル) [Apache] 2.2.15 1. 問題 あるドメインが不要になったのでDNSから削除しました。 Let’s Encryptで証明書を発行していたドメインだったので、証明書の更新時に下記エラーが出るようになりました。 (“example.net”は読み替えて下さい) それ以外のドメインについては成功メッセージが出ているにも関わらず、ブラウザで確認すると証明書が更新されず、困りました。 1 renew failure(s), 0 parse failure(s) IMPORTANT NOTES: - The following errors were reported by the server: Domain: example.net Type: None Detail: DNS problem: NXDOMAIN looking up A for example.net Automated renewal failed 2. 対策 下記を撤去することで、certbot-autoで証明書を更新する際にエラーは出なくなりました。 # mv /etc/letsencrypt/live/example.net/ /tmp/ # mv /etc/letsencrypt/renewal/example.net.conf /tmp/ さらにApache設定ファイルから、証明書などを指定した箇所を削除します。 この状態で起動するかチェックするため、Apacheを再起動しておきましょう。 <VirtualHost *:4430> ServerAdmin admin@example. ...
regファイルでvbscriptを有効にする
0. 環境 [OS] Windows 10 1. 問題 Windows UpdateしたらIE11でvbscriptが動かなくなりました。 おそらくバージョン1709から。 バージョンはWindows左下のボックスでwinverと入力すると表示されます。 前から予告されてたみたいですが、急に来た感が否めません。 僕みたいにレガシーシステムの保守をしてて困った人はいるのでは? 2. 対策 MicroSoft(以下MS)の下記ページに従ってグループポリシーの値を変えたら、vbscriptが有効になりました。 Internet Explorer のインターネット ゾーンおよび制限付きサイト ゾーン内の VBScript の実行を無効にするオプション もっと簡単な操作で変更したかったので、GUIではなく、同ページ内のレジストリファイルでのやり方を試しました。 ここでハマってしまい、いろいろ調べた結果、こちらのページのおかげで解決できました。 上記MSページのレジストリパスが違っていることが原因でした・・・ こちらのファイルをWindows上の適当な場所に置いてダブルクリックするとvbscriptが有効になります。 他にも調べたら、正しいレジストリパスを書いたページがありました。 うーん、MS本家が間違ってるってどういうことなんだろう? ...
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
0. 環境 [Mac] 10.11.6 [MySQL] 5.7.20 1. 問題 MacにMySQLをインストール後、接続しようとするとエラーが出ました。 $ brew install mysql $ mysql -uroot ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38) 2. 対策 ネットの情報をヒントに、エラーが出ているファイルの所有者を変えたら直りました。(ログインユーザー名は読み替えて下さい) $ ll /tmp/mysql.sock -rw-r--r-- 1 root wheel 0 11 19 23:46 /tmp/mysql.sock $ sudo chown [ログインユーザー名] /tmp/mysql.sock 念のためリスタート。 $ brew services restart mysql 接続できました。 $ mysql -uroot ...
【Androidアプリ開発】onPrepareActionModeが呼ばれない
0. 環境 [Windows] 7 [Java] 1.8 [Android] 5.1.1 [Android API] 26 1. 問題 build.gradleで下記の値を上げたところ、onPrepareActionModeが実行されなくなってました。 onPrepareActionModeは、ListViewのロングタップ時にアクションモードへ切り替えた後、アクションバー内のあるアイコンを隠す処理で使っていたので、困りました。 compileSdkVersion : 21 → 26 buildToolsVersion : 21.1.2 → 26.0.2 2. 対策 試しに下記 (A) にあった処理を (B) へ移してみたところ、思った通りの動きをしてくれました。 うーん、前はダメだったからonPrepareActionModeを使ったんだけどなあ。。 他にネットで情報を見つけられなかったので、一旦これにしておくか。 list1 = findViewById(R.id.listView1); list1.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { //(A) //MenuItem menuItem1 = menu.findItem(R.id.menu_item1); //menuItem1.setVisible(false); return false; } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = getMenuInflater(); inflater. ...
【Androidアプリ開発】ライブラリ追加時にビルドエラー
0. 環境 [Windows] 7 [Java] 1.8 [Android] 5.1.1 [Android API] 21 1. エラー内容 commons-langを使いたくなったので下記のように追記してビルドしたら、エラーが発生しました。 (文中の【】は読み替えて下さい) (アプリルート)/mobile/build.gradle dependencies { compile '【他のライブラリ】' compile '【他のライブラリ】' compile '【他のライブラリ】' compile 'org.apache.commons:commons-lang3:3.4' } エラー Error:duplicate files during packaging of APK C:\【パス】\mobile-debug-unaligned.apk Path in archive: META-INF/LICENSE.txt Origin 1: C:\【パス】\commons-cli-1.2.jar Origin 2: C:\【パス】\commons-lang3-3.4.jar You can ignore those files in your build.gradle: android { packagingOptions { exclude 'META-INF/LICENSE.txt' } } Error:Execution failed for task ':mobile:packageDebug'. ...
【Androidアプリ開発】「次回から表示しない」ボタン
0. 環境 [Android] 5.1.1 [Android API] 21 1. Preferenceで実装 Preferenceを使ってダイアログに「次回から表示しない」ボタンをつける方法をメモ。 ユーザーに1回だけ何かを伝えたい場合を想定しています。 (MainActivity.thisなど、適宜読み替えて下さい) 2. stethoでPreferenceを編集 開発中にPreferenceの値を変えたり、消したりしたくなると思いますが、そんな時はstethoが便利です。 stethoを起動し、[Local Storage]で該当のActivityを選択すると右側にPreferenceの値(上記コード17行目)が出ます。 右クリックで編集や削除が可能です。 stethoの設定方法は下記記事の「4. stetho 利用」を参照して下さい。 関連記事 AndroidのSQLite DBを参照 ...
【Androidアプリ開発】SQLiteのDB定義を変更する際の注意点
0.環境 [Android] 5.1.1 [Android API] 21 1.準備 Androidアプリ開発で、SQLiteのライブラリを使う際にハマった点をメモ。 まずコンストラクターでDBを使う準備をします。 import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; class DatabaseHelper extends SQLiteOpenHelper { public DatabaseHelper(Context context) { super(context, "test.db", null, 1); //(A)既存のDBを消すには下記コードを使用。 //context.deleteDatabase("DB name is here."); } //以下省略 第2引数でDB名を指定するとDBファイルがAndroid端末に作成されます。 第4引数ではDBバージョンを指定し、DB定義を変える際はこれを1つ上げるようにします。 (バージョンを下げるとクラッシュするので注意) また、開発中にDBを作り直したい場合は、上記(A)で削除しましょう。 2.ハマりポイント - DDL記載箇所 このライブラリは主に使うメソッドが2つあり、DBのバージョンによって下記の通り実行タイミングが異なります。 DBファイルが未作成の場合 : onCreate DBファイルが既にある場合(DBバージョン1以上) : onUpgrade ミスりやすいのが、DBバージョン2以降は、onCreateとonUpgradeの両方にDDLを書く必要があるという点です。 下記のようにusersテーブルがDBバージョン2で追加されたとして、もし、onUpgradeだけに書いてしまうと、DBバージョン1のユーザーにとっては問題ないですが、初期インストールの場合はonCreateしか実行されないため、usersテーブルが作られないことになります。 なので、DBバージョン2以降に追加するDDLはprivateメソッドに書いて、上記の両メソッドから呼ぶようにしたらいいと思います。 @Override public void onCreate(SQLiteDatabase db) { db.beginTransaction(); try { //DBバージョン1でcitiesテーブル作成。 String ddlCities = "CREATE TABLE IF NOT EXISTS cities (" + "city_id INTEGER PRIMARY KEY AUTOINCREMENT" + ", city_name TEXT" + ");"; db. ...