七転び八起き ~別に飽きてないよブログ~

七転び八起き ~別に飽きてないよブログ~

人生浮きっぱなしの俺が綴るクソ日記。
たまには有意義な情報が垂れ流せるようアンテナ張って生きたい。

Amebaでブログを始めよう!
おひさしぶりです。
このブログもはじめてからはや3年ぐらいたってるくさいです。

過去の内容を見るとしょっぺぇええええって思う程度には成長してます。

ついでに言うと就職してから1年たちました。
仕事の関係で2度目の引越しを経験し一気に老け込んだきがします。

バグを埋め込まない努力よりいい感じに謝る能力も身についてきた気がします。

こうやって人は夢や好奇心を忘れて行くのでしょう(遠い目)

そういえばワードプレスのブログも始めましたが、あっちはこぎれいにまとめ過ぎてアホな文章が置き辛いです。
あとつっこんだプラグインが賢すぎて検索上位にくるのでこっぱずかしいです。

要約すると私は元気です。
生き急ぎもしなければ、人類に絶望もしちゃいません。

PS. 味噌カツって味噌の割合まちがってね?
使用環境
Gimp 2.8.6 (Portable版)
※インストール版とポータブル版でフォルダ構成が違うらしいので注意

必要なもの
テキストエディタ
※改行コードの仕様上、メモ帳は不可。EmEditorやNotepad++などUNIX形式の改行コードを扱えるテキストエディタが必要

テーマのダウンロード
ダウンロードURL: Better GTK2 Themes for GIMP 2.8.zip

ファイルの解凍・配置
ダウンロードした Better GTK2 Themes for GIMP 2.8.zip を解凍する。
解凍した Better GTK2 Themes for GIMP 2.8.zip の中身を
GIMPPortable/App/gimp/share/gimp/2.0/themes
に配置する

テーマの変更
Gimpを起動する
「編集」->「設定」->「テーマ」で利用したいテーマを選択する
※ここでテーマがずらっと並んでいない場合はこれまでの手順のどこかで間違っている

フォントの変更
GIMPPortable/App/gimp/share/gimp/2.0/themes/フォントを変更したいテーマ/gtkrc
をテキストエディタで開く
※改行コードの仕様上、メモ帳は不可。EmEditorやNotepad++などUNIX形式の改行コードを扱えるテキストエディタが必要
style "default" の括弧の中に
font_name = "Meiryo 9"
を追加する
保存してGimpを再起動すればフォントが変更されている
カメラアプリに画像・動画の撮影を依頼(暗黙的インテント)して、結果をアプリが管理するフォルダ(/data/data/パッケージ/...)に保存させる方法

ContentProviderを使えば外部のアプリにファイルへのアクセスを渡せるのでこれを利用する
※カメラ関連の挙動は端末によって差異があるっぽいので要検証

・FileProvider.java

package com.example.providertest;

import java.io.File;
import java.io.FileNotFoundException;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;

public class FileProvider extends ContentProvider {

/** ディレクトリ名 */
public static final String DIR_NAME = "TEST_DIR";

/** ファイル名 */
public static final String FILE_NAME = "TEST_FILE";

/** ファイルタイプ: 画像 */
public static final String FILE_TYPE_IMAGE = "image";

/** ファイルタイプ: 動画 */
public static final String FILE_TYPE_VIDEO = "video";

/** パス */
public static final String CONTENT_PATH = "content://com.example.providertest.fileprovider/"; // TODO: マニフェストに登録する必要があります

/** このクラスを呼び出すためのURI */
public static final Uri URI_IMAGE = Uri.parse(CONTENT_PATH + FILE_TYPE_IMAGE);
public static final Uri URI_VIDEO = Uri.parse(CONTENT_PATH + FILE_TYPE_VIDEO);

/**
* 外部に公開するファイルを取得します。存在しない場合は作成します
*/
public static File createFile(Context context) {

// 外部に公開するファイル
File file = null;

try {
// アプリが管理するディレクトリを取得します
File filesDir = context.getFilesDir();
String filesPath = filesDir.getPath();

// 出力先ディレクトリのオブジェクトを生成します
String tempDirPath = filesPath + File.separator + DIR_NAME;
File tempDir = new File(tempDirPath);

// 出力先ディレクトリが作成されているかを調べて、無ければ作成します
if (!tempDir.exists()) {
if (!tempDir.mkdirs()) {
throw new Exception("failed to create the directory");
}
}

// 出力先ファイルのオブジェクトを作成します
String tempFilePath = tempDirPath + File.separator + FILE_NAME;
file = new File(tempFilePath);

// 出力先ファイルが作成されているかを調べて、無ければ作成します
if (!file.exists()) {
if (!file.createNewFile()) {
throw new Exception("failed to create a temporary file");
}
}
} catch (Exception e) {

// 例外を出力します
e.printStackTrace();

return null;
}

return file;
}

// 外部からアクセスさせるファイルを生成します。
@Override
public boolean onCreate() {
File file = createFile(getContext());

return file != null;
}

// 別のアプリがファイルを開くときに呼び出されます
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
{
// ファイルを取得します
File destFile = createFile(getContext());

// 取得に失敗した場合
if (destFile == null) {

// 例外を発生させます
throw new FileNotFoundException(uri.getPath());
}

ParcelFileDescriptor parcel
= ParcelFileDescriptor.open(destFile, ParcelFileDescriptor.MODE_READ_WRITE);

return parcel;
}

// 別のアプリがファイルタイプを取得するときに呼び出されます
@Override
public String getType(Uri uri) {

// パスの末尾の要素を取得します
String lastPath = uri.getLastPathSegment();

// 画像の場合
if (lastPath.equals(FILE_TYPE_IMAGE)) {
return "image/*";

// 動画の場合
} else if (lastPath.equals(FILE_TYPE_VIDEO)) {
return "video/*";

// 不明の場合
} else {
return null;
}
}

// 今回は未使用です
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
return 0;
}

// 今回は未使用です
@Override
public Uri insert(Uri arg0, ContentValues arg1) {
return null;
}

// 今回は未使用です
@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
String arg4) {
return null;
}

// 今回は未使用です
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
return 0;
}
}

コンテントプロバイダをマニフェストに登録します
・AndroidManifest.xml

<provider
android:name=".FileProvider"
android:authorities="com.example.providertest.fileprovider"></provider>


カメラを暗黙的インテントで呼び出します

Uri uri = FileProvider.URI_VIDEO; // 画像の場合はURI_IMAGE

Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE); // 画像の場合はACTION_IMAGE_CAPTURE
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivity(intent);


以上です。
と言いたいところですが、意外と困るのが/data/data/パッケージ/以下に保存したであろうファイルが本当に保存されているか確認する作業なのです。
エミュレータならパースペクティブのDDMSのFile Explorerから閲覧できるのですが実機だとパーミッションの関係で/data以下が閲覧できません。
ですので、実機で/data以下を確認する方法を紹介します

platform-toolsのadbコマンドを利用します
コマンドプロンプトを開いて

adb shell # シェル起動
run-as com.example.providertest # アプリのユーザに切り替え(パッケージ名は適切書き換えてください)
cd ./files # ファイルが作成されているであろうディレクトリに移動
ls -l # ファイルを詳細付きで一覧表示
# TEST_DIR が表示されていればディレクトリは問題なく作成されてます
cd ./TEST_DIR # さらにディレクトリをたどる
ls -l # ファイルを一覧表示
# TEST_FILE が表示されて且つファイルサイズが0で無ければ問題無いと思われます
# File#mkdirsメソッドの仕様上、ファイルを作成するつもりがうっかりディレクトリを作ってしまっている事もあるので注意。

# 以下、ファイルをPCにコピーします
cd .. # ディレクトリをひとつ遡って/data/data/パッケージ/files以下に移動します
chmod -R 777 TEST_DIR # 一時的にファイルのパーミッションをフルアクセスにします
exit # run-asを完了します
exit # shellを抜けます
adb pull /data/data/com.example.providertest/files/TEST_DIR/TEST_FILE /users/USER/desktop/TEST.mp4
# 端末からPCにデータを転送します com.example.providertestはパッケージ名なので適切書き換えてください
# 最後の引数がPCでの出力先となります
# PCの方で撮影した動画が再生できればファイル保存が正しくできていると考えられる


以上、実機でのファイル確認方法でした。

ちなみに・・・
画像・動画をプレビューするための暗黙的インテント送信

Uri uri = FileProvider.URI_VIDEO; // 画像の場合はURI_IMAGE

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(uri, "video/*"); // 画像の場合は"image/*"
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);


PS. この記事が書きたかったというよりSyntaxHighlighterを使いたかっただけなのは内緒。

public class TestMkII extends Test {
private int yaruki = 0;

public TestMkII(int yaruki) {
this.yaruki = 0;
}

public void setYaruki(int yaruki) {
yaruki *= 100;
this.yaruki = 0;
}

public void getYaruki() {
return 0;
}
}


SyntaxHighlighterを導入してみたよ
ソース晒しが捗るね!!