ラベル Android の投稿を表示しています。 すべての投稿を表示
ラベル Android の投稿を表示しています。 すべての投稿を表示

2012年10月11日木曜日

Androidでボリュームキーのビープ音を消す

該当Activity内でdispatchKeyEvent(KeyEvent event)をOverrideします。

調べてみるとキーがUpするときにビープ音が呼ばれているようですので、
Up時にはtrueを返して以降の処理をさせないようにします。

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
  
  switch(event.getKeyCode()) {
    
    case KeyEvent.KEYCODE_VOLUME_UP:
      if(event.getAction() == KeyEvent.ACTION_UP) {
        return true;
      }
      break;
    case KeyEvent.KEYCODE_VOLUME_DOWN:
      if(event.getAction() == KeyEvent.ACTION_UP) {
        return true;
      }
      break;
      
  }
  
  super.dispatchKeyEvent(event);
  
  return false;
}

2012年7月8日日曜日

IntentServiceでjava.lang.NullPointerExceptionが出る

IntentServiceを使用してバックエンドで動作する機能を実装していたら標題の件で、半日悩むことになった。

原因はオーバーライドしたonCreateの中で親のonCreate(super.onCreate())が呼ばれてなかったため。

まぬけだ。

基底クラスによっては呼ばなくても良い場合もあるのでついつい忘れがちになるが、IntentServiceではNullPointerExceptionになるので必ず呼ぶ必要がある。


@Override
public void onCreate()
{
 // 初期化の処理
 
 super.onCreate();
}

参照元: stackoverflow

2012年7月4日水曜日

Androidでpdfファイルを開く

開きたいpdfファイルがローカルなファイルシステム上にある場合。

File file = ("ファイルのパス"); 
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://"+file.getPath()), "application/pdf"); 
startActivity(intent); 

開きたいpdfファイルがインターネット上にある場合。

String url = "pdfファイルのurl";
Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setDataAndType(Uri.parse("http://docs.google.com/viewer?url=" + url), "text/html");
startActivity(intent);

ちなみに、AndroidのAdobe Readerでは、urlを指定してインターネット上のpdfファイルを開くことできない、たぶん。

 参照元: stackoverflow

2012年6月18日月曜日

Android SDKとAptana+ADTをアップグレードしたらjava.lang.NoClassDefFoundErrorが出るようになった。

現象としては、projectをビルドする際に関連jarファイルへのリンクが正しく行われないために、実行時にjava.lang.NoClassDefFoundErrorが発生する。 

結論から言うと、project内のjarファイルを格納したフォルダの名前に原因あり。 

上記のフォルダ名をデフォルトのlibsという名前に変更して、再度jarファイルをプロジェクトに追加しなおすと 問題は解消される

参照元: stackoverflow

calling startActivity() from outside of an Activity


Activity以外からstartActivityを使用すると、

Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

といった感じで怒られます。

言われたとおりにintentにFLAG_ACTIVITY_NEW_TASKフラッグを立ててやると問題は解消されまます。
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);

2012年6月8日金曜日

模擬的にブロードキャストなインテントを発生させる

実機をPCに繋いで、コマンドプロンプト上で以下のコマンドを打つ。
PCにandroid-sdkがインストールされていて、更にadbへのパスが通っている必要がある。
参照元: stackoverflow.com


adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
adb shell am broadcast -a android.intent.action.BATTERY_LOW


以下ブロードキャストなインテントの一覧。
参照元: http://developer.android.com/reference/android/content/Intent.html

android.intent.action.AIRPLANE_MODE
android.intent.action.BATTERY_CHANGED
android.intent.action.BATTERY_LOW
android.intent.action.BATTERY_OKAY
android.intent.action.BOOT_COMPLETED
android.intent.action.CAMERA_BUTTON
android.intent.action.CLOSE_SYSTEM_DIALOGS
android.intent.action.CONFIGURATION_CHANGED
android.intent.action.DATE_CHANGED
android.intent.action.DEVICE_STORAGE_LOW
android.intent.action.DEVICE_STORAGE_OK
android.intent.action.DOCK_EVENT
android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE
android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE
android.intent.action.GTALK_CONNECTED
android.intent.action.GTALK_DISCONNECTED
android.intent.action.HEADSET_PLUG
android.intent.action.INPUT_METHOD_CHANGED
android.intent.action.LOCALE_CHANGED
android.intent.action.MANAGE_PACKAGE_STORAGE
android.intent.action.MEDIA_BAD_REMOVAL
android.intent.action.MEDIA_BUTTON
android.intent.action.MEDIA_CHECKING
android.intent.action.MEDIA_EJECT
android.intent.action.MEDIA_MOUNTED
android.intent.action.MEDIA_NOFS
android.intent.action.MEDIA_REMOVED
android.intent.action.MEDIA_SCANNER_FINISHED
android.intent.action.MEDIA_SCANNER_SCAN_FILE
android.intent.action.MEDIA_SCANNER_STARTED
android.intent.action.MEDIA_SHARED
android.intent.action.MEDIA_UNMOUNTABLE
android.intent.action.MEDIA_UNMOUNTED
android.intent.action.MY_PACKAGE_REPLACED
android.intent.action.NEW_OUTGOING_CALL
android.intent.action.PACKAGE_ADDED
android.intent.action.PACKAGE_CHANGED
android.intent.action.PACKAGE_DATA_CLEARED
android.intent.action.PACKAGE_FIRST_LAUNCH
android.intent.action.PACKAGE_FULLY_REMOVED
android.intent.action.PACKAGE_INSTALL
android.intent.action.PACKAGE_NEEDS_VERIFICATION
android.intent.action.PACKAGE_REMOVED
android.intent.action.PACKAGE_REPLACED
android.intent.action.PACKAGE_RESTARTED
android.intent.action.ACTION_POWER_CONNECTED
android.intent.action.ACTION_POWER_DISCONNECTED
android.intent.action.PROVIDER_CHANGED
android.intent.action.REBOOT
android.intent.action.SCREEN_OFF
android.intent.action.SCREEN_ON
android.intent.action.ACTION_SHUTDOWN
android.intent.action.TIMEZONE_CHANGED
android.intent.action.TIME_SET
android.intent.action.TIME_TICK
android.intent.action.UID_REMOVED
android.intent.action.UMS_CONNECTED
android.intent.action.UMS_DISCONNECTED
android.intent.action.USER_PRESENT
android.intent.action.WALLPAPER_CHANGED


2012年6月6日水曜日

AndroidでMD5ハッシュを使う

参照元: http://www.androidsnippets.com/create-a-md5-hash-and-dump-as-a-hex-string

public String md5(String s) {
    try {
        // Create MD5 Hash
        MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
        digest.update(s.getBytes());
        byte messageDigest[] = digest.digest();
        
        // Create Hex String
        StringBuffer hexString = new StringBuffer();
        for (int i=0; i<messageDigest.length; i++)
            hexString.append(Integer.toHexString(0xFF &amp; messageDigest[i]));
        return hexString.toString();
        
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return "";
}
// see http://androidsnippets.com/create-a-md5-hash-and-dump-as-a-hex-string


AndroidのzXing(QRコードスキャナー)と連携してQRコードを読み込む

Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");

try {
  
  // onActivityResultをoverrideして結果を取得
  startActivityForResult(intent, 10000);
  
} catch(ActivityNotFoundException e) {
  
  // zXingがインストールされていないので、インストールを促す動作
  
}


zXingから制御が戻ってきた時に以下が呼ばれる。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
  if(requestCode == 10000) {
    
    if(resultCode == RESULT_OK) {
      
      // QRコードをデコードした結果の文字列を取得
      String qr_code = intent.getStringExtra("SCAN_RESULT");
      
    }
  
  }

}


参照元: http://code.google.com/p/zxing/wiki/ScanningViaIntent

AndroidのMapViewで画面の四隅の緯度経度を取得する

GeoPoint point = mapview.getMapCenter();
int lat_span = mapview.getLatitudeSpan();
int lng_span = mapview.getLongitudeSpan();

double west_lat = (double)(point.getLatitudeE6() - (lat_span / 2)) / 1E6;
double east_lat = (double)(point.getLatitudeE6() + (lat_span / 2)) / 1E6;
double south_lng = (double)(point.getLongitudeE6() - (lng_span / 2)) / 1E6;
double north_lng = (double)(point.getLongitudeE6() + (lng_span / 2)) / 1E6;



  • 画面の左端の経度はwest_lat
  • 画面の右端の経度はeast_lat
  • 画面の上端の緯度はnorth_lng
  • 画面の下端の緯度はsouth_lng


なので、四隅の緯度経度は


  • 上の左端はwest_latとnorth_lng
  • 下の左端はwest_latとsouth_lng
  • 上の右端はeast_latとnorth_lng
  • 下の右端はeast_latとsouth_lng


となる。

2012年6月5日火曜日

Androidでデバイスがインターネットに接続されているかどうかの確認

ConnectivityManager connectivity_manager = (ConnectivityManager)context.getSystemService(CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = connectivity_manager.getActiveNetworkInfo();

if(networkInfo != null) {
  
  if(networkInfo.isConnected()) {
    
    // 接続されている
    
  } else {
    
    // 接続されていない
     
  }
}


Androidで現在の接続がWifiか3Gかを判断する。


ConnectivityManager connectivity_manager = (ConnectivityManager)context.getSystemService(CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = connectivity_manager.getActiveNetworkInfo();

if(networkInfo != null) {
  
  if(networkInfo.isConnected()) {
    
    if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
      
      // Wifiで接続中
      
    } else if(networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
      
      // たぶん3Gで接続中
      
    }
  
  }

}

AndroidでDialogにwebページを表示させる

webのロード完了を待って、Dialogを表示させる。
webのロード中は、ProgressDialogを表示させておく。

final ProgressDialog progress_dialog = new ProgressDialog(this);
progress_dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress_dialog.setMessage(getString(R.string.dialog_loading_data));
progress_dialog.show();
   
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.webview_dialog);
dialog.setTitle(getString(R.string.dialog_title));
dialog.setCancelable(true);
WebView webview = (WebView)dialog.findViewById(R.id.webview);

webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webview.setWebViewClient(new WebViewClient() {

  @Override
  public void onPageStarted(WebView view, String url, Bitmap favicon) {
    
    super.onPageStarted(view, url, favicon);
    
  }
  
  @Override
  public void onPageFinished(WebView view, String url)
  {
    super.onPageFinished(view, url);
    progress_dialog.dismiss();
    dialog.show();
  }
});

webview.loadUrl("Dialogに表示するwebのURL");

DialogにセットするViewのlayoutファイル(R.layout.webview_dialog)は以下の通り








AndroidからHTTPサーバへ画像ファイルをアップロードする

try {
  
  String url = "アップロードする先のURL";
  HttpClient http_client = new DefaultHttpClient();
  HttpPost http_request = new HttpPost(url);
  MultipartEntity multipart_entity = new MultipartEntity();
  
  multipart_entity.addPart("image_file", new FileBody(new File("画像ファイルへのパス")));
  http_request.setEntity(multipart_entity);
  
  HttpResponse http_response = http_client.execute(http_request);
  int status = http_response.getStatusLine().getStatusCode();
  
  if(status != HttpStatus.SC_OK) {
    
    // 送信失敗
    
  } else {
    
    ByteArrayOutputStream byte_array_output_stream = new ByteArrayOutputStream();
    http_response.getEntity().writeTo(byte_array_output_stream);
    String response_message = byte_array_output_stream.toString();
    
    if(response_message.indexOf("ERROR") == -1) {
      
      // 送信成功
      
    } else {
      
      // たぶん送信失敗
      
    }
  
  }

} catch (Exception e) {
  
  // 例外処理
  
}



HTTPサーバ側がPHPで処理をしている場合は以下の変数にアップロードされた画像ファイルのパスが入っていますので、move_uploaded_file関数等で処理します。

$_FILES['image_file']['tmp_name'];

2012年6月2日土曜日

AdnroidでWebViewとメディアプレーヤーの連携

WebView上にあるmp3ファイルへのリンクが選択された際に、デフォルトの音楽プレーヤーを立ち上げて再生する。
WebViewClientのonLoadResourceを以下のようにOverrideする。

this.webview.setWebViewClient(new WebViewClient()
{
  @Override
  public void onLoadResource(WebView webview, String url)
  {
    if(url.endsWith(".mp3"))
    {
      Uri uri = Uri.parse(url);
      Intent intent = new Intent(Intent.ACTION_VIEW);
      intent.setDataAndType(uri, "audio/mp3");
      startActivity(intent);
    }
  }
}

AndroidでFacebookアプリを起動して特定のFacebookページを表示させる

uri = Uri.parse("fb://page/フェイスブックページのID");
intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

上記はcom.facebook.katanaがインストールされていることが前提になる。

またFacebookアプリとの連携で使用可能なuriは以下の通り。


facebook:/chat
facebook:/events
facebook:/friends
facebook:/inbox
facebook:/info
facebook:/newsfeed
facebook:/places
facebook:/requests
facebook:/wall

fb://root
fb://feed
fb://feed/{userID}
fb://profile
fb://profile/{userID}
fb://page/{id}
fb://group/{id}
fb://place/fw?pid={id}
fb://profile/{#user_id}/wall
fb://profile/{#user_id}/info
fb://profile/{#user_id}/photos
fb://profile/{#user_id}/mutualfriends
fb://profile/{#user_id}/friends
fb://profile/{#user_id}/fans
fb://search
fb://friends
fb://pages
fb://messaging
fb://messaging/{#user_id}
fb://online
fb://requests
fb://events
fb://places
fb://birthdays
fb://notes
fb://places
fb://groups
fb://notifications
fb://albums
fb://album/{%s}?owner={#%s}
fb://video/?href={href}
fb://post/{postid}?owner={uid}

参照元: stackoverflow.com

2012年5月30日水曜日

AndroidでWebViewとYouTubeアプリを連携させる

WebView上に埋め込まれたiframeなYouTubeの再生を察知して、YouTubeアプリを起動して再生させる。
WebViewClientのonLoadResourceを以下のようにOverrideする。

webview.setWebViewClient(new WebViewClient() {

  @Override
  public void onLoadResource(WebView webview, String url) {
    
    if(url.startsWith("http://www.youtube.com/get_video_info")) {
      
      Uri uri = Uri.parse(url);
      Intent intent = new Intent(Intent.ACTION_VIEW);
      intent.setData(Uri.parse("vnd.youtube:"+uri.getQueryParameter("video_id")));
      startActivity(intent);
      
      webview.stopLoading();
      
      super.onLoadResource(webview, url);
      
    }
  
  }

}

2012年5月22日火曜日

AndroidでMapView上にボタンを配置

LayoutInflaterでxmlレイアウトファイルからViewを作成し、それをMapViewにaddViewする。

メインActivityのonCreateあたりに以下のように記述。

LinearLayout linear_layout = new LinearLayout(context);
linear_layout.setVisibility(View.VISIBLE);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.button_layout, linear_layout);

MapView.LayoutParams params = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT, 0, 0, MapView.LayoutParams.TOP);
params.mode = MapView.LayoutParams.MODE_VIEW;
params.x = 0;
params.y = 0;

mapview.addView(view, params);


  1. Viewを展開するレイアウトを作成(今回はLinearLayoutを使用)
  2. LayoutInflaterを使って、ボタンの配置を記述したxmlファイルを1で作成したレイアウトに展開してViewを作成。
  3. 作成したViewをMapView上にどのように展開するか、パラメータを設定。
  4. addViewでMapViewに追加。

ボタンのレイアウトを定義したxmlファイル(R.layout.button_layout)の詳細。
MapViewの下方の左側に二つ、右側に一つボタンを配置。



     
  
    
    

      

      
    
 
    

      
 
       
     
  





2012年5月15日火曜日

Debug Certificate expire

久しぶりにandroidアプリをデバッグしようとしたら、「Debug Certificate expired」とのこと。
デバッグ用のkeyの期限切れ。
このkeyはAndroidの開発環境が勝手に生成する。

まず古いkeyを削除後、再度デバッグを行うと勝手に生成される。
keyは
C:\Documents and Settings\ユーザ名\.android

debug.keystore
という名前で生成される。

今回の該当アプリはgoogle maps apiを使用したものだったので、新しいデバッグ用のkeyに対応する新たなmaps api keyも申請する必要がある。

keytool.exe -list -keystore debug.keystore
でMD5 fingerprintを確認して、
https://developers.google.com/android/maps-api-signup
で取得。

自動生成されるkeyの期限は一年みたいだが、毎年これをやるのか。やれやれ。