Androidのアプリ開発関連のブログ

イベント関連の問題点

先日よりFTPクライアントの制作を開始しているが、イベント関連の問題点に遭遇している。


まず、昨日ドラッグ&ドロップをやったんだが、
View.startDrag(引数);
でドラッグが始まり、ドロップ対象のViewにsetOnDragListenerでドロップ時の処理を設定しておけばできる。
startDragでドラッグが始まった際にタッチ状態でなければ即終了してしまうので、startDragはタッチ開始時やロングクリック時に開始する必要がある。
ロングでないクリック時だと、タッチ終了時にイベントが発生するので無理。

ListViewのアイテムをドラッグ&ドロップしたいのだが、
setOnItemLongClickListenerでstartDragすると、スムーズに行かないので、タッチイベントで開始も試みたのだが、
startDragでドラッグが開始するとListViewのスクロールができなくなってしまう・・・
スクロールができないのもまずいので、タッチ後の移動方向を取得して、ドロップ方向に移動しているならstartDrag。
とやってみたのだが、画面の向きが縦向きならレイアウトを上下に並べるつもりなんで、スクロール方向と同じことに気づいた。
どうにもならないと思うんで、タッチでのstartDragは諦めてロングタッチでstartDragするようにした・・・


次に今日遭遇した問題なんだが、LinearLayout全体に対してクリックイベントを設定したいんだが、
LinearLayoutの親が更にLinearLayoutになってて、クリックしたいLinearLayoutはlayout_weightで拡大するようになってる。
LinearLayoutでなくてFrameLayoutとか他のViewGroup(というか、すべてのView)でもダメみたいなんだが、
layout_weightで拡大すると見た目は拡大するが、クリック領域は拡大しないみたいで、
子要素のある領域以外だとクリックが反応しない。
試しにbackgroundつけてみたが、backgroundは拡大しているんだが、子要素のある部分しかクリック反応がない。
layout_weightせずにmatch_parentすれば全体が対象になるのかもしれないが、
AdMobつけるつもりなんで、AdMobが表示できるようにwrap_contentで領域を残しつつ拡大する必要がある。
Android4.2のエミュレータでテストしてるんで、別のバージョンなら問題なかったりするかもしれない。
まあ、諦めて別の操作方法を考えようと思う。

FTPクライアントの制作始める

テキストエディターの配信開始まで漕ぎ着けて、昨日はブログエディターの微調整した以外作業なし。

テキストエディターにFTP機能持たせて、一部コードの流用ができるから、次はFTPクライアントを作ろうと思っていたが、
FTP機能があり直接編集できるテキストエディターがあるのに、別にFTPクライアントが必要か?
とも思ったんだが、
テキストファイル以外のダウンロードとかもあるから、むしろFTPクライアントを主にしてエディターを呼び出せる感じのほうが良いのかもしれんね。
そういうわけで、やはりFTPクライアントの制作始めることにした。

ボタン類排除して、タッチでドラッグ&ドロップするかんじのUIがいいかなと思うんだが、
まずシンプルな2ペインのレイアウトで作って、それを横向き用のレイアウトにする。
ある程度出来上がったら縦向き用のレイアウトを作成で、縦向き用のレイアウトは片方の領域を作業ディレクトリの表示のみの小さい領域にして、
タッチで領域切り替えと、そこにドラッグしてアップダウンする感じにしようと思う。


FTPの機能的には、テキストエディターで使った機能以外にパーミッション関連を追加する程度かな。
今まではAsyncTaskLoaderは常にrestartLoader()を使って毎回破棄してたが、連続転送も考えるとid管理してinitLoader()使う感じにしなきゃかな。
ドラッグ&ドロップ系がやったことないから手こずりそう・・・

公開した

3週間近くかかったのかな。
結構苦労したが、制作していたテキストエディター、公開まで漕ぎ着けた。




対応プロトコルを追加したりとか修正可能な点はいくつか思いつくんだが、
とりあえず現状で配信して、需要とか見て考える。


これで今月3アプリ配信したが、何かネタ考えてどんどん作っていきたい。
とりあえず今回のでFTPを使ったんで、オーソドックスなFTPクライアントもすぐ作れると思うんで、それやろうと思う。

スクリーンショットの撮り方

Google Playでアプリを配信するのにスクリーンショットが必要だが、ADBでスクリーンショットを撮る方法。

adb -s emulator-5554 shell screencap -p /sdcard/ss1.png
adb -s emulator-5554 pull /sdcard/ss1.png
adb shellでscreencapコマンドを使うことで-pオプションで指定した場所にスクリーンショットが作られるので、pullでもってくる。
adbの-sオプションはデバイスの指定。エミュレーターも含めて複数デバイスがつながっている場合は-sで指定。


layout.xmlでAdMob

制作中のテキストエディターも概ね完成してきたんで、AdMobつけてみたのだが、
前にブログエディターにAdMobをつけた際は、layout.xmlで設置するのがうまく行かなかったんだが、できた。
ググってもEclipseでのやり方ばかり出てきて、コマンドライン開発でのやり方が出てこないんだよね・・・

手元の開発環境では、
/opt/android-sdk/extras/google/google_play_services/libproject/google-play-services_lib
にAdMobのライブラリが存在するが、まず開発用のディレクトリにまるごとコピーする。

コピー先のディレクトリに対して、プロジェクトのアップデートを行う。
android update project -t 5 -p lib/google-play-services_lib
こんな感じで、-pオプションでコピー先のディレクトリを指定して、-tオプションでターゲットAPIレベルを変更する。
元のプロジェクトが「target=android-9」になってるんで、ターゲットAPIレベルを変更しないとダメぽい。

AndroidManifest.xmlの変更
<manifest>
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  <application>
    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
    <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent"/>
  </application>
</manifest>
変更箇所のみでこんな感じ。

layout.xmlの編集
<LinearLayout
  xmlns:ads="http://schemas.android.com/apk/res-auto"
>
  <com.google.android.gms.ads.AdView
    android:id="@+id/adView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true"
    ads:adSize="SMART_BANNER"
    ads:adUnitId="AdMobのID"
  />
</LinearLayout>
ルート要素(ルートじゃなくても良いのかな?)でxmlnsを追加して、AdViewを設置。
LinearLayoutでコンテンツと並べて下にAdMobを設置しているが、AdMobは十分な領域サイズがないと表示されないので、
LinearLayoutで縦に並べる場合はLinearLayoutの子要素全てがandroid:layout_height="wrap_content"でないと表示されないので注意。

MainActivity.javaの編集
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
public void onCreate(Bundle savedInstanceState){
  AdView mAdView=(AdView)findViewById(R.id.adView);
  mAdView.loadAd(new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build());
}
変更箇所のみでこんな感じ。
ブログエディターの時はonCreate以外にonDestroyとかにも処理を書いたんだが、どうもonCreateだけでいいみたい。

これで表示された。