Bluetoothイヤフォン:「ELEVENSESのイヤフォン」レビュー

Jabra Elite t65が故障しているため、違うタイプのBluetoothイヤフォンを買ってみました。

Amazonのレビューは少ないながらも高評価です。 Appleのイヤフォンと似ていますがもちろん別物です。

それではレビューします。

梱包

ちょっと微妙そうに見えるのはカタカナのフォントのせいでしょうか。 梱包自体には問題ありません。

付属品

  • USB TypeA - MicroBケーブル(白いケーブル)
  • USB TypeA - MicroB変換コネクタ(白いコネクタ)
  • USB TypeA - 二股プラグ?(黒いケーブル)
  • 説明書

黒いケーブルは何者? とりあえず白いケーブルだけあれば充分です。

説明書の日本語はいたって普通。読めます。

接続

Bluetooth5.0対応です。 iPhoneXとは問題なくペアリング出来ました。

...自動で接続されない?

翌朝ケースから取り出したときは自動で繋がりませんでした。 ケース側に充電していなかった事もありスリープに入っていたのでしょうか。 右左それぞれのスイッチを押すことで認識されました。

ケースに充電した後は取り出すと認識されるようになっています。

...たまに再接続する

アプリを切り替えるときに再接続することがありました。 頻繁には起こりませんし、切れ続けてつながらないということもありません。

音質

下と上はよく聴こえます。解像感については物足りない感じです。 オーケストラ曲の全員が弾くような場面では色々埋もれてしまいます。

でも、値段を考えれば文句ない範囲だと思います。 iPhone付属のイヤフォンに近い音質かもしれません。

マイク機能

試せていません。

防滴防塵

生活防水と書かれています。 小雨の中くらいなら大丈夫ということでしょうか。

電池の持ち

イヤフォンのみで4時間再生可能。さらにケースからの充電が最大10回可能とのことです。 通勤通学で使うなら週一で充電すれば十分。電池の心配なんで不要なレベルですね。 さらにスマフォの充電もできるそうです。(緊急時に少し充電できる程度)

片耳だけ

左耳のみで使用可能です。

総合

完全ワイヤレスのケースで充電モデルの入門として十分のレベルだと思います。 装着感はiPhone付属のイヤフォンと似ていますので、iPhone付属のイヤフォンが合わない人は要注意です。

Bluetoothイヤフォン:「Jabra Elite 65t」の右耳側が聴こえない!【無償交換してもらった!】

愛用しているJabra Elite 65tの右耳側が突然聴こえなくなりました。

schagerl.hatenablog.com

いい機会なので治るor修理までの情報をシェアしたいと思います。

(購入を検討されている方に重要な情報があります。コチラ

きっかけ

以下のような流れで聴こえなくなりました。

  • 自転車に乗りながら右耳側のみで使用していた
  • 駅に着いたので自転車を預けて左耳も装着した
  • 10分ほど聴いていたら右耳側から「ブツッ」と音がした
  • それ以降右耳側の音が極端に小さい

右耳側のみ使い込んだわけではなく、片耳使いを試し始めてから3回目くらいでの出来事でした。

ブツッと音がしてから聴こえなくなったので鼓膜がどうかしてしまったか!?と焦りました。

以下に治すため行ったことを記述します。

1. リセットを試す

まずは基本中の基本であるリセット(JabraのQA)を実行してみました。

2〜3回やりましたが結果は改善せずでした。

2. ファームウェアアップデートを試す(できませんでした)

ファームウェアアップデートを実行したら治るかと思い試そうとしました。

しかしアプリ中のファームウェアアップデート部分を見るとグレーアウトされています。

残念ながら未適用のファームウェアアップデートがある場合にしか実行できないようです。

3. サポートへ連絡する

Jabraのコンシューマ向けサポートページから症状を連絡しました。 www.jabra.jp

夜に連絡したところ翌日の営業開始すぐにメールが届いていました。 なかなか迅速な対応で好感がもてます。

4. サポートから教えてもらったことを試す

サポートからは下記を試して欲しいとのことでした。

ファームウェアアップデート ②音声ガイダンスの言語の更新 ③リセット

①と③はすでに試していましたが②はやっていないので早速試しました。 (音声ガイダンスの更新もアプリから実行します)

結果は改善せずでした。 ②については2〜3回試すと改善することがあるそうなので何回も試しましたが治らず。

改めて①〜③を数回試しましたが治らずでお手上げ状態です。

4. 結果をサポートへ連絡する

サポートへ全て試したが改善せずと返信したところ翌日の営業開始後すぐに返信がありました。

無償交換してくれるそうです。

まずは無償交換のためにレシートを撮影した画像を送って欲しいとのことです。 帰宅後早々にメール添付で送付しました。 画像を送れない場合は不具合品を送付するときに同梱でも良いそうです。

不具合品の送料についてはユーザー側が負担です。しょうがないですね。

5. 不具合品をJabraへ送る

翌営業日の朝にメールがあり、住所氏名などを書いたものと一緒に送付することになりました。

昼休みにコンビニから送付しました。

6. 新品が帰ってきた!

交換品が帰ってきました。

月曜日の昼休みに送付して木曜日には新品が送り返されて届きました。

素晴らしい対応ですね! 大切に使っていきます。

再確認ですが無償交換はレシートがあり認定販売店で買った場合に限り1年間、さらにアプリからユーザー登録したら2年間に延長との事です。

認定販売店

重要な情報です。 サポートからのメールには

ELITEシリーズは認定販売店からの購入に限りサポート対象

と書かれていました。 認定販売店で買わなかった場合には買ったお店のサポートしか受けられないようですので気をつけてください。

認定販売店は下記との事です。(2019年2月時点)

Amazon以外の場合

Amazonの場合

  • Amazon Japan G.K
  • Jabra Speciality Store
  • eイヤホン

Bluetoothイヤフォン:「Jabra Elite 65t」レビュー

今回のお題はイヤフォンです。

iPhoneからイヤフォンジャックが無くなって以来Bluetoothイヤフォン難民になっていましたが、その時に出会ったのがJabra Elite 65tです。

同様のイヤフォンは色々ありますが、まずは見た目から入ってしまいました。だって北欧デザインですよ。 形がカッコいいし落ち着いた色も魅力的です。

以下説明です。

接続

Bluetooth5.0対応です。 iPhoneXで使用していますが問題なく接続出来ました。

接続が切れる事もほとんどありません。 (何故か京王井ノ頭線渋谷駅のホームだけ切れかけます)

音質

有線の同価格帯と比べるとどうしても解像感は落ちますが不満はありません。 通勤通学で使う場合にはタッチノイズが無い分有利かも知れません。

さらにコンプライのイヤーピースhttps://amzn.to/2IxJSW4を着けてます。 快適です。

マイク機能の部分で書きますがノイズキャンセル機能もついているようです。

マイク機能

このイヤフォンはマイクがついており通話などに使えます。

私は公園などでアプリ英会話をやる事があります。 その時にはこのイヤフォンを使っていますが少しハッキリと話せば問題なく聞こえているようです。

また、マイク機能を使って風切り音などのノイズをキャンセルしているようです。 正直よくわかりませんがマイルド効いているんでしょうか。

ノイズキャンセルとは逆に外の音が聴こえるようになる機能もあります。 こちらはコンビニでお金払うときや電車内で放送を聞きたいときなどに便利です。

防滴防塵

防滴防塵機能についてはIP55です。 雨の中や砂の舞うお天気の中でも問題なく使えるレベルです。

電池の持ち

イヤフォン単体では5時間使用可能、さらにケースで満タン2回分充電可能との事です。

外した時にケースに入れておくだけで充電され電池切れで困ったことはないです。

片耳だけ

右耳片側だけでの使用が可能です。 マイク機能があるので片耳のヘッドセットとしてもつかえますね。

アプリ

公式がアプリを提供しています。 イコライザ設定やファームウェアアップデートが可能です。

ファームウェアアップデート対応ということは長く使えそうですね。

また、アプリからユーザー登録すると保証期間が1年から2年に伸びます。インストール必須です。

トラブル…

いい事ばかり書いていますがこの記事を書いている最中にトラブルが発生しました。 約4ヶ月使用したところですが突然右側の音量だけ凄く小さくなってしまったのです。

現在サポートに連絡して対応中です。

次以降の記事で経過報告しますので興味のある方は確認してください。 (購入を検討している方には重要な情報がありますので是非読んでください)

iOSアプリ開発:「Auto Layout」と「制約」

前回は制約(constraint)についてあまり説明せずに使用していました。

今回は制約関連の説明を行いたいと思います。

Anchor

Anchorとは船のイカリや固定する動作を表す英語です。 UIViewは水平垂直方向の位置や長さについてのAnchorを持っており、Anchorに制約を与えることにより固定することが出来ます。

例えば、あるビューの右端Anchorと左端Anchorを別のビュー基準で制約を与えれば、基準のビューが水平方向に動いたりサイズが変わった場合にもそれに合わせて伸び縮みしてくれるようになります。

また、伸び縮みして欲しくなく、いつでも同じ長さで、左端から決まった位置に配置したいような場合は、左端Anchorと水平方向の長さAnchorに制約を与えることで実現できます。

以下にAnchorの種類を並べます。

Anchorの種類

  • 垂直方向の位置についてのAnchor
メンバ名 タイプ 説明
topAnchor NSLayoutYAxisAnchor Viewの上端を表すAnchorです
centerYAnchor NSLayoutYAxisAnchor Viewの垂直方向中心を表すAnchorです
bottomAnchor NSLayoutYAxisAnchor Viewの下端を表すAnchorです
firstBaselineAnchor NSLayoutYAxisAnchor View内テキストの上端を表すAnchorです
lastBaselineAnchor NSLayoutYAxisAnchor View内テキストの下端を表すAnchorです
  • 水平方向の位置についてのAnchor
メンバ名 タイプ 説明
leadingAnchor NSLayoutXAxisAnchor Viewのリーディング端(左端)を表すAnchorです
centerXAnchor NSLayoutXAxisAnchor Viewの水平方向中心を表すAnchorです
trailingAnchor NSLayoutXAxisAnchor Viewのトレイリング端(右端)を表すAnchorです
leftAnchor NSLayoutXAxisAnchor Viewの左端を表すAnchorです
rightAnchor NSLayoutXAxisAnchor Viewの右端を表すAnchorです
  • 長さについてのAnchor
メンバ名 タイプ 説明
heightAnchor NSLayoutDimension 高さを表すAnchorです
widthAnchor NSLayoutDimension 幅を表すAnchorです

constraint

Anchorは制約を与えるためのメソッドを持っています。 Anchorのタイプ毎に行くつかのメソッドを持っていますので代表的なものを説明します。

constraintの種類

// 他のAnchor(equalTo)を基準にオフセット(constant)を足した位置に固定する制約です。
// NSLayoutXAxisAnchor, NSLayoutYAxisAnchorで使用します。
func constraint(equalTo: NSLayoutAnchor<AnchorType>, constant: CGFloat) -> NSLayoutConstraint

// サイズを固定する制約です。
// NSLayoutDimensionで使用します。
func constraint(equalToConstant: CGFloat) -> NSLayoutConstraint

他にも色々なメソッドがありますので興味のある人は調べてみましょう。 https://developer.apple.com/documentation/uikit/view_layout

iPadとPlaygroundsで学ぶ:「addSubview」でエラー!?

iPad+Playgrounds環境です。

UIButtonを複数表示させようと思い、for文でUIViewController.viewにaddSubviewするプログラムを書きました。

import UIKit

class ViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        for i in 1..<12 {
            self.view.addSubview(UIButton())
        }
    }
}

import PlaygroundSupport
PlaygroundPage.current.liveView = ViewController()

実行してみるとaddSubview7回目で

このプレイグラウンドの実行中に問題が起きしました。コードに誤りがないか確認してください。

という表示が出て止まってしまいます。

色々調べるも情報が見つかりませんでした。

試しにUIViewを1つ作成し、そのUIViewへUIButtonをaddSubviewしたのち、UIViewController.viewにUIViewを設定するように変えてみました。

import UIKit

class ViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let mainView = UIView()
        for i in 1..<12 {
            mainView.addSubview(UIButton())
        }
        self.view = mainView
    }
}

import PlaygroundSupport
PlaygroundPage.current.liveView = ViewController()

今度は問題なく実行できました。 Playgroundsの制限かな?それともUIVewController.viewをそのまま使うのは良くないのかな?

いずれにしても、今後はUIViewを1つ作成してそこにaddSubviewするようにします。

iPadとPlaygroundsで学ぶ:「Auto Layout」と「制約」でビューをレイアウトする

今回はAuto Layoutの機能を使ってビューのレイアウトを行います。

Auto Layout

UIKitにはAuto Layoutという機能があり、制約(constraint)を指定することでメインビューやサブビュー同士の相対位置を指定することができます。

相対位置を指定できて何が良いかというと、メインビューのサイズが変わった場合にもうまく伸び縮みしてくれるということでしょうか。

前回のコードを変更して制約を試してみます。

仕様

  • メインビューの全体にマップビューを表示する(ただし上下左右10ptだけ隙間を開ける)
  • メインビューの右下に50pt x 50ptで赤色のボタンを表示する
  • ボタンの右下は右端から100pt、下端から100ptとする

コード

import UIKit
import MapKit

class ViewController : UIViewController {
    lazy var map = MKMapView()
    lazy var button = UIButton()
    
    override func loadView() {
        super.loadView()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.button.backgroundColor = UIColor.red
        self.button.addTarget(self, action:#selector(buttonEvent(_:)), for: UIButton.Event.touchUpInside)
        self.view.addSubview(self.map)
        self.view.addSubview(self.button)
        
        self.map.translatesAutoresizingMaskIntoConstraints = false
        self.map.leadingAnchor.constraint(equalTo:self.view.leadingAnchor, constant:10.0).isActive = true
        self.map.trailingAnchor.constraint(equalTo:self.view.trailingAnchor, constant:-10.0).isActive = true
        self.map.topAnchor.constraint(equalTo:self.view.topAnchor, constant:10.0).isActive = true
        self.map.bottomAnchor.constraint(equalTo:self.view.bottomAnchor, constant:-10.0).isActive = true
        
        self.button.translatesAutoresizingMaskIntoConstraints = false
        self.button.widthAnchor.constraint(equalToConstant: 50.0).isActive = true
        self.button.trailingAnchor.constraint(equalTo:self.view.trailingAnchor, constant:-100.0).isActive = true
        self.button.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
        self.button.bottomAnchor.constraint(equalTo:self.view.bottomAnchor, constant:-100.0).isActive = true
    }
 
    @objc func buttonEvent(_ sender: UIButton) {
        self.map.centerCoordinate = CLLocationCoordinate2D(latitude: 35.0, longitude:135.0)
    }
}

import PlaygroundSupport
PlaygroundPage.current.liveView = ViewController()

viewDidLoadself.view.addSubviewより後に記述しているのが制約です。

(始めはaddSubviewより前に制約を書いていたためか実行時に途中で止まってしまい、しばらくハマりました)

また、viewDidLayoutSubviewsの記述がなくなっています。これは制約によりAuto Layoutが制約によりうまく配置といリサイズをしてくれるためです。

以下説明です。

Auto Layoutに位置とサイズを変更させる

ビューのtranslatesAutoresizingMaskIntoConstraintsfalseの場合は、Auto Layoutがビューのサイズと位置を変更するようになります。falseにしましょう。

制約

下記が制約とその制約を有効化する部分です。

self.map.leadingAnchor.constraint(equalTo:self.view.leadingAnchor, constant:10.0).isActive = true 

leadingAnchorは水平方向左側のアンカーで、constraintをコールしてself.viewの左側(leadingAnchor)から10.0ptの位置を指定しています。

さらに上記指定した後にisActive = trueで制約を有効にしています。

iPadとPlaygroundsで学ぶ:メンバーの初期化を「lazy」で+配置を修正

前回はUIButtonとMKMapViewを使いました。 schagerl.hatenablog.com

ビューの初期化と配置についてもう少し整理します。

仕様

前回と同じです。

コード

全体

import UIKit
import MapKit

class ViewController : UIViewController {
    lazy var map = MKMapView()
    lazy var button = UIButton()
    
    override func loadView() {
        super.loadView()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.button.backgroundColor = UIColor.red
        self.button.addTarget(self, action:#selector(buttonEvent(_:)), for: UIButton.Event.touchUpInside)
        self.view.addSubview(self.map)
        self.view.addSubview(self.button)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.map.frame.size = self.view.frame.size
        self.map.frame.origin.x = 0
        self.map.frame.origin.y = 0
        self.button.frame.size = CGSize(width:50, height:50)
        self.button.frame.origin.x = 100
        self.button.frame.origin.y = 100
    }

    @objc func buttonEvent(_ sender: UIButton) {
        self.map.centerCoordinate = CLLocationCoordinate2D(latitude: 35.0, longitude:135.0)
    }
}

import PlaygroundSupport
PlaygroundPage.current.liveView = ViewController()

以下で各処理について説明します。

サブビュー初期化

サブビューはViewControllerの先頭で下記のように生成しています。

    lazy var map = MKMapView()
    lazy var button = UIButton()

lazyは初期化に関するキーワードで、初めて使われるときに一度だけ初期化処理が実行されます。

サブビュー登録

サブビューの基本的な設定と登録はviewDidLoadで行います。

viewDidLoadはメインビューがロードされたタイミングで呼ばれるので、サブビューを登録するにはちょうど良さそうです。

サブビューのサイズ設定と配置

サブビューのサイズ設定と配置はviewDidLayoutSubviewsで行います。

viewDidLayoutSubviewsはメインビューのboundsが変更され、サブビューの配置が変更されたときに呼ばれます。

メインビューのサイズや位置が変わった時にサブビューの位置とサイズを合わせるという処理になっています。

前回のコードではloadViewでサブビューのサイズ設定を行なっていたため、サイズが確定する前のメインビューにサイズを合わせていたことになります。 また、メインビューのサイズが変わった場合に何もしていないのも良くないですね。画面の向きが変わったり、何かの要因で表示領域が小さくなる場合には対応できていませんでした。

色々スッキリしました。