著者アーカイブ asaba

asaba 著者:asaba

【cordova】画像が横向きになる問題を解消する

コルドバでアプリを作っていると、FileReaderを使って画像をアップロードする機能が欲しくなるときがあります。

このライブラリを使う時に少しめんどくさいのが、アップロードの際に画像が90度回転してしまいその修正をしなければいけないという点です。

こんな感じです。↓

対策としてexif-jsを使って向きを調べた後にcanvasで修正する方法があるのですが、コールバックが含まれていて可読性が下がってしまう

点とandroidのバージョンが古いとちゃんと動作しないという問題を抱えています。

reactで開発していることもあって、スタックオーバーフローを見ても事例が少なく途方に暮れていたところ有用なサイトを発見。

どうやらnpmでblueimp-load-imageという画像を独自メソッドを使って直してくれる便利そうなパッケージを発見。

さっそくnpm install blueimp-load-imageでインストール。下でコードの説明をしていきます。

<pre> loadImage.parseMetaData(file, (data) =&gt; {
            const options = {
                maxHeight: 1024,
                maxWidth: 1024,
                canvas: true
            };
            if (data.exif) {
                options.orientation = data.exif.get('Orientation');
            }
            loadImage(file, (canvas) =&gt; {
                const dataUri = canvas.toDataURL('image/jpeg');
                const imgNode = this.refs.image;
                imgNode.src = dataUri;
            },
            options);
        });</pre>

 

parseMetaDataメソッドを使って画像を修正するのですが、まず最初に対象のfileを引数にした後にオプションでキャンバスをtrueで使用

可能にし、その次にdata.exifで画像の向きを調べています。loadImageではtoDataURLでbase64に変換して、最終的にimgNodeとタグ

this.refs.imageを紐付けて画像を表示しています。このコードで全てセットなので、難しかった画像の向きも簡単に修正することができますね。

これで横向きになっていたがぞうが元に戻りました。めでたしめでたし。

 

その他参考にさせていただいたサイトです。->http://dackdive.hateblo.jp/entry/2016/07/19/095000

 

asaba 著者:asaba

【html5】inputタグのtype=”file”のワナ

コルドバでアプリ開発をしていると、プラグインによってandroidとiphoneが必ずしも同じ動きをしない場合があります。

例えば、下のinputタグのtype=””fileもiphoneの場合はカメラ撮影もギャラリーから写真を撮ることもできるのに対し、androidでは

カメラ機能だけがついていない状態で反映されます。


<input type="file" >

 

iphoneだとこんな感じになります。

問題のandroidがこちらです。

 

http://kimizuka.hatenablog.com/entry/2016/12/01/215013

の記事によれば、機種依存のバグだそう。androidには無効な機能がいくつかあるみたいで再現は不可能みたいです。

今自分が開発しているアプリは、カメラ機能で撮った写真をアップロードしてその写真を恒久的に使うのでこのバグはかなり痛かったです。

このような場合は諦めてcordova-plugin-cameraというプラグインとinput fileタグを使い分けるしかないですね。

自分はこれに気づくのが遅く数時間無謀な格闘をしてしまいましたが、どこのサイトを見ても解決策が見当たらない場合はすっぱり諦めて

一度頭の中空っぽにして別の手段を考えるとアレ?これでもいけるんじゃね。と意外とすぐ解決策が見つかるかもしれません。

一つのエラーに執着すると、視野が狭くなってしまい別の糸口が見えなくなってしまうことを痛感させられましたですはい。教訓です。

asaba 著者:asaba

【chrome】実機で起きたエラーをブラウザで確かめる方法

ブラウザと実機(androidStudio)では挙動に若干の違いがあり、コルドバのプラグインはブラウザでは大体使えないので挙動を見たい時は

実機で確かめなければいけません。これだけならめんどくさいだけで開発には支障ないのですが、ブラウザでエラーが起きずに逆に実機で

エラーが起きてしまった場合は実機周りや開発環境を見直さないといけなくなる羽目になり、開発が大幅に遅れてしまいます。

androidStudioで一応Logcatでエラー内容を見れるのですが、ブラウザと違い全て表示してくれるわけではないので、あまり頼れるもので

はありません。(ハイブリッドアプリを作る時のみ)

確実にエラーを見るには、chromeを開いてアドレス欄にchrome://inspectと入力してください。

すると、下記のようなページに移動すると思います。

 

 

移動出来たら、一番下に小さくinspectと書いてあるリンクをクリックします。すると、別ウィンドウで下の画像のようなページが表示

されます。今は何も表示されていませんが、実機でコンパイルしてアプリを起動してエラーが起きると通常のデベロップツールと

同じようにエラーの内容が表示されます。

 

androidStudioでは表示できないエラーの中身も、これを使えば全部見ることができます。実機で起きたエラーの詳細を見ることで

開発の効率もぐんと上がるので、ハイブリッドアプリ開発をしている方にとっては心強い味方になってくれると思います。

asaba 著者:asaba

【cordova-react】cordova-barcodescannerプラグインでスキャンしたURLに遷移する方法

 

少し前にcordova-barcodescanner-pluginを導入したのですが、肝心の読み込みー>そのページに移動するという機能を付けられずにいた

のですが、最近になってようやく実装できました。方法としては、以下の一行を加えるだけです。

<pre>window.location.href = result.text;</pre>

読み込んだresult.textをhrefで遷移しているだけなのでとても簡単に実装することができます。

コード全体がこちらです。

 

<pre>        window.cordova.plugins.barcodeScanner.scan(
            function (result) {
                alert("Success!\n" +
                "Result: " + result.text + "\n" +
                "Format: " + result.format + "\n" +
                "Cancelled: " + result.cancelled);
                window.location.href = result.text;
            },
            function (error) {
                alert("Scanning failed: " + error);
            },
            {
                preferFrontCamera : true, // iOS and Android
                showFlipCameraButton : true, // iOS and Android
                showTorchButton : true, // iOS and Android
                torchOn: true, // Android, launch with the torch switched on (if available)
                saveHistory: true, // Android, save scan history (default false)
                prompt : "Place a barcode inside the scan area", // Android
                resultDisplayDuration: 500, // Android, display scanned text for X ms. 0 suppresses it entirely, default 1500
                formats : "QR_CODE,PDF_417", // default: all but PDF_417 and RSS_EXPANDED
                orientation : "landscape", // Android only (portrait|landscape), default unset so it rotates with the device
                disableAnimations : true, // iOS
                disableSuccessBeep: false // iOS and Android
            }
        );</pre>

 

設定は遷移に影響しないのでお好みで変えていただいても大丈夫だと思います。試したところほとんどのQRコードで遷移成功できたので

実際に使ってみる分にも申し分ない性能だと思います。

今回無事に実装ができたきっかけはまたまたスタックオーバーフロー様の記事です。

リンク記事ー>https://github.com/phonegap/phonegap-plugin-barcodescanner/issues/262

 

asaba 著者:asaba

【javaScript】税込み商品の計算アプリ

プログラミングを始めた時に既に作りたいものがたくさんあったのですが、まだ技術も基礎もない自分でも何か作れない

かなと試行錯誤していた時に作ったアプリです。題名は、税込み商品計算アプリです。

消費税が上がることを思い出したことをきっかけに作ったアプリです。使い方は単純で、商品と現在の消費税を入力して計算ボタンを

押すと税込み価格をテキストで表示する、本当にそれだけのアプリです。


<form name="text">
<input type="text1" id="okt1"name="add1"> ×
<input type="text2" id="okt2"name="add2">
</form>
<input type="button" id="cb" value="お会計"onclick="cash()">
<input type="button" id="res" value="リセット"onclick="reset()">
<p id="result"></p>
<script>
var num1 = document.text.okt1.value;

var num2 = document.text.okt2.value;

var res = document.getElementById("result");

function cash(){

num1 = document.text.okt1.value;

num2 = document.text.okt2.value;

res = document.getElementById("result");

sum = Math.round(num1 * num2);

if(num1==="" || num2 ===""){

res.innerHTML = "数値を入力してください。";

}else if(!isNaN(num1) && !isNaN(num2)){

res.innerHTML = "税込みで" + sum + "円になります。";

}else{

res.innerHTML = "数値以外が入力されています";

}
}

//データを削除する処理
function reset(){

document.text.okt1.value="";

document.text.okt2.value="";

res.innerHTML = "";
}
</script>

 

 

 

 

適当にコピーしていただいてchromeで開けばすぐに動きます。

プログラミングを経験しているかたにとってはものすごくチープに感じてしまうくらいしょぼい出来ですが

javaScriptでは必須スキルのフォームを作る方法を詰め込んでいるので、初心者がありがちなこのコードは何をしているか

分からない、何のための関数なのか理解できないといった最初の壁をぶち破ることができます。

reactやvue.jsではこの作法を応用してコンポーネントを作りますが、これら流行りのフレームワークも簡単なアプリを

つくっていく中でめきめきと覚えることができるのではないでしょうか。(筆者は容量が悪いので時間がかかりました)

初心者のかたで何が分からないか分からないという方は、もしjavaScriptでググってこのサイトを見つけたら何かの縁かと

思って試しに動かしてみてくださいね。

asaba 著者:asaba

【cordova-react】ajax通信でerror判定の時のデバッグ方法

今日はajax通信でエラーが吐き出された時の中身を確認する方法を紹介いたします。

ajaxなどのhttp通信では、エラー時にxhr, textStatus, errorThrownをひと固まりで吐き出します。その中身を見るためにはconsole.logで

一項目ずつ引数を指定してあげる必要があります。

コードで書き表すと下記のようになります。

 

 


console.log("xhr : " + JSON.stringify(xhr));
console.log("textStatus : " + textStatus);
console.log("errorThrown : " + errorThrown.message);

上記のxhrは従来のconsole.logに入れると[Object object]で表示されなくなるので、JSON.stringify関数で囲んでください。

この中身を見ることで、クライアント・サーバー間でどのタイミングでエラーになったかを確認することができます。

例としてログで吐かれたxhrの中身を見てみます。


[INFO:CONSOLE(1)] "xhr : {"readyState":0,"status":0,"statusText":"error"}", source: file:///android_asset/www/static/js/main.7a2980e1.js (1)

引数にstatusという項目で0と返ってきていますが、この0とはタイムアウト(接続時間が長すぎて途中で切られた結果の値。サーバー側ではなくブラウザから送られてくるもの)を指します。

このほかにも、404(ファイルが存在しない)や401(許可されていない)など、原因によってさまざまな値を返してくれるので

そこから解決方法を紐付けることが出来れば素早くデバッグ処理をすることができると思います。

 

ajaxで通信したけどエラーが帰ってきたでも何がエラーか分からない!という方は試してみてください、それでは。

 

参考にさせていただいたサイトです。->http://taka.hatenadiary.com/entry/2013/11/10/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6AJAX%E9%80%9A%E4%BF%A1%E3%82%92%E6%95%B4%E7%90%86%E3%81%99%E3%82%8B

 

asaba 著者:asaba

【cordova-react】cordova platform rmでしても消えない時

プラグインを入れるためにコルドバのプラットフォームを削除して新しくプラットフォームを入れ直す作業をしていたのですが、

androidのプラットフォームはrmコマンドで消えてくれない時があり、何度rmしてもダメでした。

上の画像のように空のandroidファイルのみが残ってしまい、このままでは新たにプラットフォームを入れることができません。

力技ですが、ファイルから手動で消してみることにしました。プラットフォームフォルダに移動して、からっぽのandroidファイル

を削除。

改めてcrordova platform add androidでERROR!!が出なければインストール成功になります。(画像は取り忘れてしまいました、すみません)

偶に空っぽのままインストールされるので一応中身をみておいてください。

asaba 著者:asaba

【AndroidStudio】bodyを含めたOkHttp通信

久々にandroidJavaの記事を書きます。今回はOkHttpを使った非同期通信についての記事になります。

androidの非同期通信と言えばURLConnectionが代表的に挙げられ、自分も今までURLConnectionで非同期通信をしていましたがこれが

中々長ったらしくてactivityを分けて書いたりと面倒くさいことづくしでした。

これ毎回書くの嫌だなーって思ってたのですが、最近になってOkHttpという非同期通信の存在を知りました。

リファレンスを見ると、重くなりがちな通信を既存のメソッドを減らすことで速度を向上させるために作られたライブラリみたいです。

メソッドが減るということは当然可読化も改善して作りやすくなったってことですよね。という訳で試しにOkHttpを使った非同期通信を

書いてみました。javaScriptでajaxやfetchで慣れ親しんできた自分としてはすごく楽になったなーと感じるコードになりました。

public class MainActivity extends AppCompatActivity {

    private EditText Text1,Text2;
    private static String TAG = "try";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Text1 = findViewById(R.id.Text1);
        Text2 = findViewById(R.id.Text2);

        Button button = findViewById(R.id.LoginBtn);

        button.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            public void onClick(View view) {


                String url = "http://ここに叩きたいAPI.php";

                String yourname = Text1.getText().toString();

                String yourcountry = Text2.getText().toString();

                RequestBody formBody = new FormBody.Builder()
                        .add("name", "yourname")
                        .add("country", "yourcountry")
                        .build();


                Request request = new Request.Builder()
                        .url(url)
                        .post(formBody)
                        .build();

                OkHttpClient client = new OkHttpClient();

                Call call = client.newCall(request);

                call.enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        System.out.println("fialer!!");
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        System.out.println("response: " + response.body().string());
                    }
                });
            }
        });

        }
    }

 

まず、String urlで叩きたいAPIを宣言します。どの形式にしろ必須です。

次に、postしたいeditTextを変数に格納しています。画像や音声ファイルでも送信は可能ですが、ここではテキストにしています。

次のRequestBody formBody = new FormBody.Builder()ですがここが肝になってきます。

キーに該当するテキストのワードを送って、最後にrequestBodyに送れるようにbuild()しています。これがないとrequestで送る時に

bodyに定義できないので、必ずここでビルディングしておきましょう。

最後にrequestBuilderオブジェクトでurlとpostを定義して送信準備完了です!コールバックのところはそのまま公式からとってきたので省

略します。(すみません)

 

フルコードで載せたので、androidStudioのバージョンが極端に古くなければ動くと思います。

これからOkHttp通信を実装するか考えてるけどどのサイトも書いてあることが断片的で分からない!という方はこれを参考にしていただ

ければ幸いです。それではまた。

 

 

 

asaba 著者:asaba

【react-cordova】即時関数以外でJSXで条件文を定義する

 

少し前にJSX内で即時関数を使ってifを使う記事をかきましたが、良い点と悪い点があるということを書き忘れてしまったので補足します。

良い点はそのままjavascriptを使える点です。初心者のかたはreactの書き方自体まだおぼつかないという方もいると思います。

しかし、即時関数でカッコを複数付けるだけで定義したifの一文を配置したいコンポーネントが命令を読み込んでくれるという初心者のか

たにとっては変更が少なく感覚的に理解しやすい実装方法として使われていました。

次に悪い点の説明ですが、この関数のデメリットはやはりカッコー>{(())}が多くなり可読性に欠けてしまうという点です。

プロジェクトで機能の変更があり即時関数周りの修正が必要になった時とかは特に顕著で、まずカッコの境界線を切り分けた後に修正を

加えないといけなくなり、これにかなり神経を使ってしまうのではと感じました。これが自分ならまだしも他のチームメンバーが見たら

混乱してしまいますよね・・・。

デバッグ前に事前に説明するかコードをもっと簡潔に書いてあげるかしてできればストレスフリーで作業したいですしね。

自分も後からコードを読み返してなんとか気を使えないか悩んだ結果後者を選びました。下のコードを見てください。

 

render() {
const num = this.state.num;
return (
{ num=="1" && <select onChange={ e => this.setState({ward: e.target.value}) }  defaultValue="">

{ this.ward.map( d => <option  value={d.value}>{d.label}</option>)} </select>
 }
);
}

[/java script]

ひいき目でみても綺麗とは言えないですが、カッコの数を減らしてシェイプアップさせました。&&を付けて変数numが1ならばselectタグ

を生成するように定義しています。カッコを消したことで格段に見やすくなりましたね。

 

1人でアプリを作るのにはなんてことはないのですが、大規模なプロジェクトではこのように細かいコードを修正する時でさえ

気を使わないと他のメンバーからなにこれ!みたいに突っ込まれかねないので、reactに慣れてきたなというかたは一度自分のコードを

見てみてください。小さいですが自分のプログラミングの技術向上にもなるので、気づいたらこれはおいしいと思って楽な気持ちで

取り組むといいかもですね。

 

asaba 著者:asaba

【cordova-react】react.jsでCSSっぽいものを書いてみる

 

最近になってやっとreactの書き方が分かってきました。が、コンポーネントの操作は分かったけどCSSってreactだとどう書くの?

と思いreactで使えるライブラリを漁っていました。material-uiやbootstrapでもかけるのですが、自分にとってはstyled-componentが

使いやすいかなと感じ、チュートリアルでいじってみました。

styled-componentは、render外で定義したstyleの設定とrender内で定義したコンポーネントを紐付けて使うのが主な特徴で

おなじみのボタンやテキストを整えてスタイリッシュなアプリを簡単に作ることができます。

広い範囲でlibraryが提供されているので、最初は書き方に戸惑うことがあるかもしれませんが、慣れてくれば上にあげたライブラリと

同じくらいの働きをしてくれます。

サンプルコードで味気ないですがコードを載せておきます。

import React, { Component } from 'react';
import {BrowserRouter as Router, Switch, Route, Redirect,  Link, NavLink, withRouter} from 'react-router-dom'
import ReactDOM from 'react-dom'
import styled from 'styled-components';


const Input = styled.input`
  padding: 0.5em;
  margin: 0.5em;
margin-top:6px;  
margin-left: 250px;  
  color: ${props => props.inputColor || "palevioletred"};
  background: papayawhip;
  border: none;
  border-radius: 3px;
`;


class Sample extends Component {
  constructor(props) {
    super(props);
	  this.state = {
		}
  }

  render() {
    return (
	   
</div> ); } } export default Sample;

[/java script]

 

公式リファレンスからとってきただけですが、断片的で見にくかったのでフルコードで載せてしまいます。

説明することはあまりないですが、tips程度に解説します。まず、class Sampleの上にclass Inputと定義しています。

これは、render内に書いたinputタグのことを指しています。さきほど言ったようにここでコンポーネントのデザインを変更したりできます。

styled.inputの後に何やら見慣れない「`」という記号があります。(グレイブアクセントと読む)その後ろに通常のcssで使うような

設定がありますが、このグレイブアクセントは関数でいう()のようなもので、後ろの設定は引数と考えてください。

 

この定義をいくつか使うことで、ユーザーの目に優しいデザインをつくることが可能になります。自分もこのライブラリに触れたのが

数日前だったので、動かし方を完全に覚えた訳ではありませんが、cssを触ったことのあるまたは他のライブラリを使ったことがあるとい

う方は感覚的に触っていけばその内馴染んで自在にコンポーネントを作れそうですね。

未経験の方は絵を描く感覚で筆者と一緒にじっくり覚えていきましょう。

 

※es6で書いているので、es5でコードを書いているは適所合わせてください。