Pigのインストール
最近、仕事でよくPigを使います。
ただ、先輩の真似をしているだけなので
勉強していきたいと思います。
PigはPig Latinという言語を使って、簡単にjoin・group・filter・sortをしたり
sumやcountをしたりできるものです。
まずはPigのダウンロード。
http://pig.apache.org/releases.html
からダウンロードします。
$ tar xzf pig-0.12.1.tar.gz $ export PATH=$PATH:/pig-0.12.1/bin
よし。
$ pig Error: JAVA_HOME is not set.
JAVA_HOMEを設定する。
$ export JAVA_HOME=/Library/Java/Home
Pigの実行。-x localを付けるとローカルで実行できる。
$ pig -x local
参考
Pigのインストール
http://d.hatena.ne.jp/osaca_z4/20100603/1275557688
MacでのJava_Home
http://qiita.com/seri_k/items/e978c1339ce51f13e297
JAVA_HOMEとPATHの違い
http://okwave.jp/qa/q4061702.html
git grep
Git grepを便利に使う-eオプションについて - Qiita
を参考にgit grepを使ってみました。
です。
-eオプション
-eの後にgrepしたい条件を書くことで、正規表現による絞り込みができます。
$ git grep -e 'GET /apache' log.ltsv:host:127.0.0.1 user:frank epoch:1372694390 req:GET /apache_pb.gif HTTP/1.0 stat log.ltsv:host:127.0.0.1 user:john epoch:1372794390 req:GET /apache_pb.gif HTTP/1.0 stat log.ltsv:host:127.0.0.1 user:- epoch:1372894390 req:GET /apache_pb.gif HTTP/1.0 status:503 log.ltsv:host:127.0.0.1 user:frank epoch:1372694390 req:GET /apache_pb.gif HTTP/1.0 stat main.pl: req => 'GET /apache_pb.gif HTTP/1.0', main_v2.pl: req => 'GET /apache_pb.gif HTTP/1.0', t/01_use.t: req => 'GET /apache_pb.gif HTTP/1.0', t/log.t: req => 'GET /apache_pb.gif HTTP/1.0', t/parser.t:is $parsed->[0]->{'req'}, 'GET /apache_pb.gif HTTP/1.0'; t/parser.t:is $parsed->[1]->{'req'}, 'GET /apache_pb.gif HTTP/1.0'; t/parser.t:is $parsed->[2]->{'req'}, 'GET /apache_pb.gif HTTP/1.0'; t/parser.t:is $parsed->[3]->{'req'}, 'GET /apache_pb.gif HTTP/1.0';
--andオプションと--orオプション
andやorという形で条件を指定できます。
$ git grep -e 'GET' --and -e 'frank' --or -e 'john' log.ltsv:host:127.0.0.1 user:frank epoch:1372694390 req:GET /apache_pb.gif HTTP/1.0 stat log.ltsv:host:127.0.0.1 user:john epoch:1372794390 req:GET /apache_pb.gif HTTP/1.0 stat log.ltsv:host:127.0.0.1 user:frank epoch:1372694390 req:GET /apache_pb.gif HTTP/1.0 stat t/parser.t:is $parsed->[1]->{'user'}, 'john';
やってくれていることは、'GET'かつ'frank'、あるいは'jhon'の検索です。
スマホが振られたのを検知してみる。
一ヶ月振りの更新。
加速度センサーを利用して、スマホを振ったのを検知してみました!
ネットで拝借したソースコードにコメントアウトで解釈(間違いがありましたらご指摘ください)を加えたものを以下に記述させていただきます。
ざっくり言うと、ある程度の速度で3回以上連続して振られていたらシェイクと判定するという感じです。
package com.hatenablog.a01.hoge; import android.hardware.SensorListener; import android.hardware.SensorManager; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.view.Menu; // SensorListenerインターフェイスをimplementsする。 /* onSensorChanged(int sensor, float values[])メソッドとonAccuracyChanged(int sensor, int accuracy)メソッドを実装。 onSensorChangedはセンサーの値が変更される毎に呼び出される。 sensorはセンサーを識別する整数。valuesはデータ自体を表現する浮動小数点数で、センサーによって提供される値の数は異なる。 onAccuracyChangedはセンサーの精度が変わると呼ばれる。今回は使わない。 */ public class ShakeListener extends Activity implements SensorListener { private static final int FORCE_THRESHOLD = 350; private static final int TIME_THRESHOLD = 100; private static final int SHAKE_TIMEOUT = 500; private static final int SHAKE_DURATION = 100; private static final int SHAKE_COUNT = 3; private SensorManager mSensorManager; private float mLastX = -1.0f, mLastY = -1.0f, mLastZ = -1.0f; private long mLastTime; private OnShakeListener mShakeListener; private Context mContext; private int mShakeCount = 0; private long mLastShake; private long mLastForce; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hoge; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_hoge, menu); return true; } @Override public void onAccuracyChanged(int sensor, int accuracy) { } @Override public void onSensorChanged(int sensor, float[] values) { //SensorManager.SENSOR_ACCELEROMETER=加速度センサーでなければreturnする。 if ( sensor != SensorManager.SENSOR_ACCELEROMETER ) return; //System.currentTimeMillisを使い現在時刻をミリ秒で取得。 long now = System.currentTimeMillis(); //最後に動かしてから500ミリ秒経過していたら、連続していないのでカウントを0に戻す。 if ( ( now - mLastForce ) > SHAKE_TIMEOUT ) { mShakeCount = 0; } //最後に振ってから100ミリ秒経っていたら以下の処理。 if ( ( now - mLastTime ) > TIME_THRESHOLD ) { long diff = now - mLastTime; //端末の加速度から前回の加速度=if ( speed > 350 )を引いたものをMath.absで絶対値にする。それを経過時間で割ったものに10000を掛けて10秒間でどれだけ加速したかを求めているよう。 /* XYZ軸の概念は http://seesaawiki.jp/w/moonlight_aska/d/%B2%C3%C2%AE%C5%D9%A5%BB%A5%F3%A5%B5%A1%BC%A4%CE%C3%CD%A4%F2%BC%E8%C6%C0%A4%B9%A4%EB が参考になりました。 */ float speed = Math.abs(values[SensorManager.DATA_X] + values[SensorManager.DATA_Y] + values[SensorManager.DATA_Z] - mLastX - mLastY - mLastZ ) / diff * 10000; /*350より大きい速度で、振られたのが3回目(以上)でかつ、最後にシェイクを検知してから100ミリ秒以上経っていたら 今の時間を残して、シェイク回数を0に戻す。onShakeメソッドを呼ぶ。 */ if ( speed > FORCE_THRESHOLD ) { if ( ( ++mShakeCount >= SHAKE_COUNT ) && now - mLastShake > SHAKE_DURATION ) { mLastShake = now; mShakeCount = 0; if ( mShakeListener != null ) { mShakeListener.onShake(); } } mLastForce = now; } mLastTime = now; mLastX = values[SensorManager.DATA_X]; mLastY = values[SensorManager.DATA_Y]; mLastZ = values[SensorManager.DATA_Z]; } } public interface OnShakeListener { public void onShake(); } public ShakeListener ( Context context ) { mContext = context; resume(); } public void setOnShakeListener ( OnShakeListener listener ) { mShakeListener = listener; } public void resume () { mSensorManager = (SensorManager) mContext.getSystemService(SENSOR_SERVICE); if ( mSensorManager == null ) { throw new UnsupportedOperationException("Sensor not suported"); } boolean supported = mSensorManager.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_GAME); if ( !supported ) { mSensorManager.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER); throw new UnsupportedOperationException("Acceleroneter not supported"); } } public void pause() { if ( mSensorManager != null ) { mSensorManager.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER); mSensorManager = null; } } }
後はメインのアクティビティを書けば完成!
mShaker = new ShakeListener(this); mShaker.setOnShakeListener(new ShakeListener.OnShakeListener() { @Override public void onShake() { //振られたときの処理。 } });
スプラッシュ画像の表示方法
アプリを立ち上げたときに出てくるスプラッシュ画像。
設定してみました。
① 最初に表示したい面を用意します。
splash.xml
<?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" > <ImageView android:layout_width="90dp" android:layout_height="90dp" android:scaleType="fitCenter" android:src="@drawable/splash" /> </LinearLayout>
② スプラッシュ画像=splash.xmlを出すアクティビティを記述。
SplashActivity.java
package パッケージ名; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.view.Window; public class SplashActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // タイトルを非表示。 requestWindowFeature(Window.FEATURE_NO_TITLE); // splash.xmlをviewに指定。 setContentView(R.layout.splash); Handler handler = new Handler(); // 500ms遅延させてsplashHandlerを実行。 handler.postDelayed(new splashHandler(), 500); } class splashHandler implements Runnable { public void run() { // MainActivityはいつも一番はじめに呼ばれるやつです。 Intent intent = new Intent( getApplication(), MainActivity.class); startActivity(intent); SplashActivity.this.finish(); } } }
③ はじめにSplashActivity.javaを呼ぶようマニフェストファイルを書き換える。
Manifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="パッケージ名" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="SplashActivity" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault.Light" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="MainActivity"></activity> </application> </manifest>
カッコよく出ました!
Unable to execute dex…
Androidプロジェクトを起動しようとするとこんなエラーが出ました。
[2014-02-10 00:58:34 - Dex Loader] Unable to execute dex: Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoVersionImpl; [2014-02-10 00:58:34 - ProjectName] Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoVersionImpl;
原因は二つあり、
① 必要なライブラリがエクスポートされていないこと
② jarファイルが重複
でした。
解決法としては
① プロジェクト名を右クリック→ビルド・パス→ビルドパスの構成→順序およびエクスポート→Android4.2とAndroid Dependenciesをチェック→OK
② プロジェクト以下にも、プロジェクト内のlibsディレクトリ以下にも、同じjarファイルがあったのでlibsにあるほうを削除。
でエラーが解消しました。
参考
android - Unable to execute dex: Multiple dex files define Lcom/myapp/R$array; - Stack Overflow
アプリ実行時になんかエラーが出る - 日々精進
途中でAPIレベルを変更する方法
androidアプリを作っていて、途中で使いたいと思ったデザインが
あるAPIレベル以上じゃないと利用できない、でも最初に設定した
ミニマムSDKバージョンはそれに達していない…!ということ、ありませんか。
そんなときはManifestファイルです。
use-sdkタグの変えたい箇所を書き換えます。
before
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="17" />
after
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
参考URL
APIレベル変更方法
コチョナナバ: Androidアプリの開発途中でAPI levelを変更する
SDKバージョンとOSバージョンの対応表
AndroidのバージョンとAPIレベルの対応関係
NetworkOnMainThreadExceptionの解決方法
APIを叩くAndroidアプリ作ってたらこんなエラーが出ました。
android.os.NetworkOnMainThreadException
Android 開発Tips: FTPファイル送信
によるとAndroid3.1からStrictModeがデフォルトでオンになっていて
解除する必要があるそうです。
解除は
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
でできます。
StrictModeは
開発者がアプリケーションをモニターし、パフォーマンスを改善するための機能