Android Support Repositoryが見つけられない

Gradleのお話

なんか今までサポートライブラリーv4を使うときはEclipseからの継承でlibsにandroid-support-v4.jarを突っ込んで使ってた。

でもGradleはなんかすげースゴイらしくてなんか使おうと思ってたけど不思議なことに↓のようなエラーがずっとでてた。

Error:Could not find com.android.support:support-v4:22.2.0.
Searched in the following locations:
https://repo1.maven.org/maven2/com/android/support/support-v4/22.2.0/support-v4-22.2.0.pom
https://repo1.maven.org/maven2/com/android/support/support-v4/22.2.0/support-v4-22.2.0.jar
Required by:
:MedicalMonitor:unspecified

Please install the Android Support Repository from the Android SDK Manager.
<a href=”openAndroidSdkManager”>Open Android SDK Manager</a>

だが、ここにきてcompile ‘com.roomorama:caldroid:2.1.0’を使う必要があった。

どうもそれにはcom.android.support:support-v4:22.2.0が必要っぽい

さて困ったぞと

結局何が悪かったかというと

task copyLibs(type : Copy) {
    configurations.compile.each {
        from it.toString()
        into 'libs'
        exclude {
            new File('libs', it.name).exists()
        }
    }
}

というタスクがgradleで動いてたのが原因だった。

なんかよくわからないままコピペ放置されていたプログラムだ。

これを消すとすんなり動いた。

動いたのだから深いことは考えない。

しかしこれのせいで3日も無駄になってしまった。

頑張って早く作らないと

AsyncTaskLoaderの挙動

AsyncTaskLoaderについてはさんざん悩まされてきたけど、また再びバグって大変だった。

具体的にはActivityから離れて戻ってきた時にonStartLoading→onLoadFinishedが流れるんだけど、何度も何度もActivityに戻るときに同じ処理が流れてて本当に謎でバグの原因だった。

今使っている自作のAsyncLoaderはJSONを元に使っているのだけど、JSONに変換出来ない場合がある。その時はNULLを流すようにしてるんだけどそれがイケなかったようだ。

@Override
public void deliverResult(JSONObject data) {
    if (isReset()) {
        if (this.result != null) {
            //this.result = null;
        }
        return;
    }

    String strerror="{\"" + "this" + "\"" + ":" +"\""+"ReConnect" + "\""+"}";//{"this":"FailConnect"}
    JSONObject aaa=new JSONObject();
    try{aaa=new JSONObject(strerror);}catch (JSONException e2) {}//なんかめんどくさい


    this.result = aaa;

    super.deliverResult(data);
    if (isStarted()) {
    }
}

@Override
protected void onStartLoading() {
    if (this.result != null) {
        deliverResult(this.result);
    }
    if (takeContentChanged() || this.result == null) {
        forceLoad();
    }
}

取り敢えず荒療治でむりやりResultに値をセットして、復帰時の処理を判別できるようにした。

これなら取り敢えずは forceLoad()に行かずにそのままdeliverResultしてくれる。

ゼッタイ何か問題ある気がするけど取り敢えず様子見。

 

取り敢えず今のところの挙動として、

なんか違うURLかつLoaderIDが同じでgetSupportLoaderManager().restartLoaderをすると、最初したURLのLoaderでonLoadFinishedが流れる。

でもなんか同じURLで同じLoaderIDだったらonLoadFinishedは一度しか流れず正常に行く感じ

つまりひとつのURLに1つのLoaderIDを指定すれば大丈夫ってこと???

謎だー

PHPでandroid,iphoneからの画像の回転処理

AndroidやiPhoneでは画像を保存した時縦横のサイズではなくExifのOrientationで画像の向きを管理しているらしい。

なるほど、そのまま縮小しても向きがおかしいはずだ。

よってOrientationを考慮した動作が必要になる。

// コピー元画像の指定
$targetImage = $target_path;
// ファイル名から、画像インスタンスを生成
$image = imagecreatefromjpeg($targetImage);
// コピー元画像のファイルサイズを取得
list($image_w, $image_h) = getimagesize($targetImage);

// 出力する画像サイズの指定
//$width =640;
//$height = $width*$image_h/$image_w;


$min_width = 800; // 幅の最低サイズ
$min_height = 800; // 高さの最低サイズ


if($image_w == $image_h) {
   $width = $min_width;
   $height = $min_height;
} else if($image_w > $image_h) {//横長の場合
   $width = $min_width;
   $height = $image_h*($min_width/$image_w);
} else if($image_w < $image_h) {//縦長の場合
   $width = $image_w*($min_height/$image_h);
   $height = $min_height;
}


// サイズを指定して、背景用画像を生成
$canvas = imagecreatetruecolor($width, $height);

// 背景画像に、画像をコピーする
imagecopyresampled($canvas,  // 背景画像
      $image,   // コピー元画像
      0,        // 背景画像の x 座標
      0,        // 背景画像の y 座標
      0,        // コピー元の x 座標
      0,        // コピー元の y 座標
      $width,   // 背景画像の幅
      $height,  // 背景画像の高さ
      $image_w, // コピー元画像ファイルの幅
      $image_h  // コピー元画像ファイルの高さ
);



$exif_datas = exif_read_data($target_path);
//返り値として連想配列でExif情報が取得できます。

//var_dump($exif_datas);
if(isset($exif_datas["Orientation"])){
 if($exif_datas["Orientation"]==6){

 // 回転
 $canvas = imagerotate($canvas, 270, 0);

 }
 if($exif_datas["Orientation"]==8){

 // 回転
 $canvas = imagerotate($canvas, 90, 0);

 }
 if($exif_datas["Orientation"]==3){

 // 回転
 $canvas = imagerotate($canvas, 180, 0);

 }
 }
// 画像を出力する
imagejpeg($canvas,           // 背景画像
      "./shohou_image_m/".$new_dir."/" . basename( $_FILES['f1']['name'])."_0.jpg",    // 出力するファイル名(省略すると画面に表示する)
      100                // 画像精度(この例だと100%で作成)
);

// メモリを開放する
imagedestroy($canvas);

こんなところかなー

スクリーンのON時にFragmentDialog作成

スクリーンをOnにした時のイベントを取得した時

private BroadcastReceiver screenStatusReceiver = new BroadcastReceiver() {//スクリーンのON/OFFイベントを検出する
    @Override
    public void onReceive(Context context, Intent intent) {
        // Receive screen off


        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            // OFF
            LoginTimeSave();


        }
        if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            // ON fragmentだとIllegalStateExceptionでる
            LoginReqired();
        }
    }
};

でやるのだが、この時fragmentを生成しようとすると

java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.SCREEN_ON flg=0x50000010 } in com.medicalmonitor.MainActivity$20@451d81d0

Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

が出て強制終了してしまう。

onSaveInstanceState()はonPause()/onStop()の直後に発生するから、onPause()からonResume()の間に操作しなければ解決する。

結果的にcommitAllowingStateLossを使うことで解決できた。

でもこれActivityが再構築された時とかにおかしくなるからあんまり使わないほうがいいらしい。まぁとりあえずこれで様子見。

Fragment prev = getSupportFragmentManager().findFragmentByTag("DigLogin");
if (prev == null) {//これがないと何個もダイアログ作られる

    //Dialog_LoginReqired newFragment = Dialog_LoginReqired.newInstance(null);
    //newFragment.show(getSupportFragmentManager(), "DigLogin");//DigDrugはTAG findFragmentByTagでみつけれる

    Dialog_LoginReqired dialog = new Dialog_LoginReqired();
    //dialog.show(getSupportFragmentManager(), null);
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.add(dialog, "DigLogin");
    ft.commitAllowingStateLoss();

}

ListViewのクセ

なにかと使い勝手が悪いandroidのListviewだけど、globals関数を想定した使い方のメモ。

まず取り敢えず一番良さそうなのがMainActivityに

 ArrayList<CustomData> localobjects = new ArrayList<CustomData>();//ローカルオブジェクト
 globals.kanjaAdapter = new CustomItemView(this, 0,localobjects);

を定義してadapterを形成。

そしてfragmentに

ListView lv;
lv.setAdapter(globals.kanjaAdapter);

でListviewにアダプターを設定する。

なんかfragmentにadapterを形成してもいいけど、その場合fragmentから離れた場合にあたりまえだけど初期化されるから内容を保持したい場合はやっぱりMainActivityに書くのがよさそう

ちなみによくわからないけどglobals.kanjaobjectsとかobjectにはグローバルは使えなさそう。

なにかとilligalCatchClass的な例外が出る。

でもこれも違うクラスからglobals.kanjaAdapter.addしたりすると動いたり、よくわからない。

とりあえずlocalで定義するのが良さそうだ。

 

追記:globalsで定義して全然問題なかった。

他の処理でglobalsのobjectを操作してたからおかしくなってただけだった。

上の記事はあんまりどころか全く参考にならないかも