顯示具有 mobile 標籤的文章。 顯示所有文章
顯示具有 mobile 標籤的文章。 顯示所有文章

2020年12月20日

[Mobile] Android Samsung Note 10 vs. Apple iPhone mini 12 使用心得

我是一個對智慧型手機莫名有興趣的人,曾經在 hTC 打工時寫過幾篇開箱文、去年也寫過 Samsung S10+ 和 Note 10 的簡單比較,從智慧型手機出到現在,曾經用過 Micrsoft Lumia 620、LG G 系列、小米 Mix2S、小米 Mi 9、Google Pixel 3XL、Samsung S 系列,一直到現在用的 Samsung Note 10。
Samsung Note 10
雖然換過許多不同的裝置,手邊用 Mac 和 iPad,耳機使用的是 AirPods Pro,但就是從來都沒有實際用過 iPhone。從去年的 iPhone 11 到今年年初推出的 iPhone SE 2020 都吸引到我一波,然後都忍住了 XD,到了年底的 iPhone 12 mini 是壓倒駱駝的最後一根稻草,是時候來感受看看所謂蘋果生態系的時候了!
這篇文章就來分享一下當前使用 Note 10 和 iPhone 12 mini 的體驗心得。

前言

我覺得現在聊手機品牌,特別是聊到安卓(Android)和蘋果(Apple)的比較並不是一個令人太愉快的經驗,因為和他人討論這東西時,已經變成很像在聊「政治」,大家有自己很明確的立場,只要立場對了什麼都好,很難真的去考量功能本身的好壞,所以漸漸也覺得自己用得開心就好,不太想和別人實際去討論這些「功能」上的優劣,因為很多人常常也不願意理解你在說什麼,他只選擇相信自己想相信的。我想任何事物,只要到了 O 粉的程度,就已經是信仰層次,盲目是必然的現象,不論是政治或手機。

系統使用體驗

日常使用流暢性

以系統體驗來說,iPhone 的流暢性真的是非常優秀,過場動畫非常順暢,操作起來就是很開心。iPhone 總是能把每天需要用到的細節體驗優化到很好,以每天會做上 n 次的解鎖這個動作來說,整個動作一般來說就是行雲流水一般的順暢。用過 iPad 的 Touch ID,和 iPhone 的 Face ID,以我個人來說,即使在經常需要戴口罩的今天,Face ID 還是我認為非常優異的解鎖方式,雖然真的會稍不方便,但如果 Touch ID 和 FaceID 只能選一個的話,我會選 Face ID,對我來說能少一個動作實在是太重要了。
反觀 Samsung Note 10 在這一塊就顯得相當不足,雖然同時提供了指紋解鎖和臉部解鎖,但指紋解鎖的感受沒辦法達到過去實體指紋感測器那種「秒解」的爽度;臉部解鎖雖然還算堪用,但有時會發生已經臉部解鎖完成,我還傻傻在使用指紋解鎖的情形,因為臉部解鎖後,指紋的圖示並沒有消失。另外,一開始買的時候,進到解鎖畫面前,畫面會有稍微的卡頓的情況,這個部分在後續的更新已經好非常多,這些體驗上的細節雖然不影響使用,但總會覺得沒那麼流暢。

大眾運輸通勤最強 - Samsung Pay 悠遊卡

但除了解鎖之外,搭乘大眾運輸對我來說也是每天的例行事務,這時候 Samsung Note 10 的 Samsung Pay 悠遊卡發揮它極大的優勢,手機本身就是悠遊卡這點真的太強大了,甚至手機沒電時仍然可以使用,你不再需要每次到了捷運站去包包裡掏卡片。iPhone 雖然在國外也有整合交通卡的功能,但在台灣還沒辦法使用。這點也絕對不單單是 MegSafe 可以補足的。

App 使用流暢性差不多

以 App 使用流暢性來說,我覺得在 App 使用時,兩者使用的感覺並沒有差異非常大,所以如果擔心使用 App 時會有卡頓的情況,在我使用這兩隻時都不太有這樣的情況,不論是日常的 Facebook、Intagram、Mobile01 等等,兩隻都非常順暢。

單手操作

單手操作我覺得是 iPhone 的弱勢,用了 iPhone 基本上很難完全單手操作,即使我用的是 iPhone mini,偶爾還是會需要把右手大拇指橫跨過整個螢幕去點擊左上角按鍵鍵的情形。另外,雖然 iPhone 也有單手模式,但基本上就是把最上面的東西往下掉一半,方便你去點擊,點完一次後整個畫面又會彈回到全螢幕。突然理解了,為什麼 iPhone 的使用者似乎沒有很在意是否有單手操作的功能,因為不論是 iPhone 12 mini、iPhone 12、iPhone 12 Pro Max,經常性的都會需要雙手操作。
相對地,Note 10 或 Samsung 的手機雖然螢幕大了一圈,但 6.3" 的螢幕重量僅僅只有 168g,並再搭配 One Hand Operation+ 後,透過手勢就可以達到返回上一頁、鎖定螢幕、螢幕截圖、進入多工畫面等等,如果不夠用的話,和 iPhone 一樣可以透過手勢進入單手模式。Samsung 的單手模式是以等比例的方式縮小螢幕,可以自己調整縮放比例,而且不會點一次就整個彈回全螢幕,再加上 Google 鍵盤本身也有支援單手模式,因此當我在使用 Note 10 時,雖然螢幕很大,卻有更長時間是可以單手操作手機的。
Andorid 單手模式

拍照攝影

我平常蠻在意手機拍照的功能,因為我沒有相機,也不想出去玩時總是要背一台相機跑來跑去,因此對我來說,手機的拍照是重要的。這次雖然買的是 iPhone 12 mini,少了 2 倍鏡頭和 LiDAR,但光就一般拍照來說,應該還是可以簡單比較的。
我認為這兩隻手機在光線充足的情況下都能夠拍出非常優異的照片,但比較明顯的差異會發生在光線不足的情況,這個光線不足並不是指夜拍,而是一般常見的陰天、室內等環境。當光線不足的時候兩隻手機的成像則會有蠻明顯的差異。
在下面的照片中左側放的都是 Note 10(關閉 AI 辨識)、右側放的都是 iPhone 12 mini,並且都使用自動模式,沒去刻意調什麼參數。至於哪張比較「真實」、「自然」,哪張比較好看,每個人心中都有自己的評分標準,就不多說明了。

有一種真實,是 iPhone 覺得的真實

不論是 iPhone 的用戶或 Youtuber 最常自詡的就是 iPhone 的照片接近肉眼所近,最真實也最自然;而 Andorid 的手機就都是美顏、修很大、雖然好看但不自然。但真的是這樣嗎?
在夜間拍攝的時候,iPhone 預設的亮度變得非常高,第一眼會覺得非常亮眼,單若看廣告招牌上的文字就有些過曝。
iphone 12 mini vs Andriod Samsung Note 10
在光線比較不充足時,iPhone 12 mini 拍出來的照片較容易黃黃黑黑,對比度偏強的感覺:
iphone 12 mini vs Andriod Samsung Note 10
iphone 12 mini vs Andriod Samsung Note 10
iphone 12 mini vs Andriod Samsung Note 10
相對地,Samsung Note 10 則會比較偏白粉與柔和(可以留意照片中白色的部分):
iphone 12 mini vs Andriod Samsung Note 10

Samsung Note 10 光線不足時對比度不足、色彩不夠明確

這個情況有好有壞, Samsung Note 10 在光線不足(陰天或室內)則較容易因為對比不夠,而顯得顏色不那麼明確(偏白)。這時當場景本身就是暖色調時,iPhone 的成像就好很多:
iphone 12 mini vs Andriod Samsung Note 10
iphone 12 mini vs Andriod Samsung Note 10
iphone 12 mini vs Andriod Samsung Note 10
iphone 12 mini vs Andriod Samsung Note 10

iPhone 12 場景辨識功能

至於食物的部分,iPhone 12 mini 不知道是不是因為在相機的設定中多了場景辨識的緣故,我個人覺得這食物的顏色很強烈...,相較之下 Samsung Note 10 雖然第一眼看上去沒這麼討喜,但後續如果需要調整色彩應該會也比較容易:
iphone 12 mini vs Andriod Samsung Note 10
iphone 12 mini vs Andriod Samsung Note 10
除了食物之外,自然環境也同樣碰到類似的情況,iPhone 12 mini 的色彩雖然相當鮮豔,第一時間也覺得非常好看,但顏色還是相對較為飽和,對比度也較高,天空的效果也顯得更劇烈:
iphone 12 mini vs Andriod Samsung Note 10

結論

我認為這兩隻手機都是非常棒的手機,多數客觀的使用者也都承認 Apple 絕對有很多優異的功能,而三星的手機在拍照上也能有自然真實而好看的表現;往往令人感到難以理解或不舒服的是那種意識形態般的盲目擁護或盲目貶低。
以使用情境來說,在一般通勤的時候,我會想要使用 Samsung Note 10,不論是搭乘大眾運輸或在大眾運輸上滑手機,我覺得 Note 10 的方便性(悠遊卡、單手模式)和螢幕大小都更適合我。但到了公司若是中午外出去個便利商店、買個飲料等等這種會使用到行動支付的場景,iPhone 系統順暢的體驗會讓我覺得操作起來很舒適。
就我個人來說,iPhone 優異的流暢性適合給想要好好使用手機的使用者,它可能不是什麼地方都最好最強,但多數時候可以讓你在體驗上有 90 分以上的體驗,被照顧的舒舒服服;而三星或高階安卓的使用者則更適合喜歡「玩手機」的人,除了拍照的表現也相當優秀外,單手模式的客製化、主題的調整、Widget 的功能等等,有時還會有雖然兩個人都拿同一型號手機,都卻第一時間不知道怎麼使用對方手機的情況呢!
最後,附上兩隻手機拍的一些比較照片,在 Google 相簿 每張相片右上角有個 i,點擊之後即可檢視不同照片是用哪隻手機進行拍攝:

2020年5月1日

[Mobile] 給開發者用:將 Android 裝置畫面投影到 MAC / PC 上的工具(scrcpy)

keywords: screen sharing, screen mirroring, miracast, android, screen recording
💡 備註:如果你是 iOS 裝置要投放到 Mac 的話則非常簡單,透過內建的 QuickTime 就可以了,只需選擇「File -> New Movie Recording」後,將來源選到 iOS 裝置即可,可參考圖一和圖二的說明。
最近因為有把手機(Android)的操作畫面投影到電腦上的需求,試了幾套不同的工具後,發現許多工具都需要在手機和電腦端同時裝 App,除了會有較明顯的時間差外,大多都是透過 Android 內建的「投放」功能來達到這個效果。
但這裡因為某些理由,我不能使用原生的投放功能來投放螢幕,而是需要直接把手機畫面顯示在電腦上,找這找著找到這套很好用的 Android 投放手機螢幕工具,稱作 scrcpy。
這套工具除了可以投放螢幕外,還可以錄製螢幕、傳輸檔案、並直接由電腦操作手機,最重要的是操作流暢度非常好!
但這套工具比較是給開發者的, 因為需要透過終端機下一些指令,當然你也可以照著打就好了。關於使用的方式在 scrcpy 的 Github 上已經有蠻清楚的說明,可以使用在 Linux, Mac 或 Windows 上,有興趣的可以直接到 scrcpy 的 Github 查看文件。
這裡簡單說明一下步驟,各步驟詳細的作法都可以再額外 Google 或於文件中查看:

手機端操作

  1. 啟用開發人員選項:先進到手機的「設定 -> 關於手機」然後點擊「Build Number(版本號碼)」7 次後即可開啟「開發者」功能(應該會看到提示文字)。
  2. 進入「開發人員選項」:接著回到設定頁面,在設定頁面中應該會多出「開發人員選項(Developer options)」的項目,點擊進去。
  3. 啟用「USB 偵錯」功能:進到開發人員選項後,找到「USB 偵錯(USB Debugging)的項目後開啟它
  4. 將手機透過傳輸線與電腦連接

電腦端操作(Mac)

這裡以 Mac 為例,下面指令都是在終端機輸入:
💡 Windows 的安裝方式可以參考 Github 上的說明。
  1. 安裝 Homebrew(如果還沒裝過)
# 如果還沒安裝過 homebrew 需要先安裝
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
  1. 透過 Homebrew 下載 scrcpy
$ brew install scrcpy                         # 下載 scrcpy
$ brew install --cask android-platform-tools    # 下載 android 工具
  1. 手機連接電腦後,輸入
$ scrcpy
這時候就可以看到手機的畫面出現在電腦上了,而且相當流暢!
scrcpy

使用無限(wireless)方式進行連線

  1. 先將手機和電腦連接到同一個 Wifi 網路
  2. 取得手機的 IP 位置,點選設定 -> Wifi 網路,即可看到如圖的畫面
  3. 將手機與電腦使用傳輸線連結,接著在終端機輸入
$ adb tcpip 5555
$ adb connect <DEVICE_IP>:5555  # 填入裝置連上的 WIFI IP
  1. 把手機和電腦的傳輸線拔掉
  2. 執行 scrcpy
$ scrcpy
  1. 由於是透過無線傳輸,若想要得到最好的體驗,建議可以降低解析度和 bit-rate:
$ scrcpy --bit-rate 2M --max-size 800  # scrcpy -b2M -m800 縮寫
⚠️ 若想改回使用 USB 傳輸線連接,可以輸入 adb usb。

更多功能:錄製螢幕、操作手機、檔案傳輸

scrcpy 這個工具除了可以投放螢幕外,也可以錄製螢幕,更可以直接在電腦上操作你的手機,還可以把檔案直接拖到手機內,真的超級方便的,而且流暢度非常高,其他更多的功能或參數設定,都可以到 scrcpy 查看!

參考

2019年11月20日

[WebAPIs] Web Share API 的使用 - navigator.share

keywords: WebAPIs, mobile, navigator.share

TL;DR

// 判斷瀏覽器是否支援 Web Share API
if (navigator.share) {
  // navigator.share 會回傳 Promise
  navigator.share({
    title: 'Web Fundamentals',
    text: 'Check out Web Fundamentals — it rocks!',
    url: 'https://developers.google.com/web',
  })
  .then(() => console.log('Successful share'))
  .catch((error) => console.log('Error sharing', error));
}

Web Share API 的說明

用手機瀏覽網頁的時候,不知道你有沒有注意過,當你按下分享按鈕時它會跳出一個選單,讓你可以選擇要分享到哪個 App 的選單,像是這樣:
Web Share API
這個功能過去需要透過點擊手機瀏覽器上的「分享」後才會出現:
Web Share API
但現在透過 Web Share 這個 API 也可以輕鬆達到這個功能,讓使用者在點擊網頁上的按鈕後就跳出這個「分享選單」,如此就有機會省去使用那種帶有一堆 Facebook、Line、Twitter、Pinterest 按鈕的第三方套件,進一步減少頁面載入時間。
現在就來看看怎麼使用吧!

Web Share API - navigator.share

適用瀏覽器

Web Share API 的使用方式很簡單,但要注意的是這主要是適用在手機上的功能,畢竟電腦上沒有這種分享選單(目前除了 Mac 的 Safari 可用),不過即使電腦不支援此 API 的使用,還是可以很容易做出替代方案(fallback)。
看到下圖瀏覽器支援性的一大片紅字感覺很恐怖,但目前(2019-11-20)其實主要的手機瀏覽器(Chrome, Safari)都適用,Mac 上的 Safari 亦可:
Web Share API
目前實測在三星內建的瀏覽器上可以使用,但分享成功後的回傳訊息不太正確。

使用方式

使用方式很簡單:
// navigator.share 會回傳一個 Promise

// 下面的欄位可以不用全部填寫,可以只分享網址,也可以只分享文字
const sharePromise = navigator.share({
  url: 'https://pjchender.blogspot.com',    // 要分享的 URL
  title: 'PJCHENder 那些沒告訴你的小細節',      // 要分享的標題
  text: '好多眉眉角角啊'             // 要分享的文字內容
});
navigator.share() 會回傳一個 Promise (代表你可以搭配 async...await 使用),這個 Promise 會在使用者完成點擊某個 App 分享後被完成(fulfilled);若使用者取消分享或帶入的參數有錯誤時,則會被拒絕(reject)。
使用時有幾點需留意一下:
  1. Web Share API 只能使用在有 HTTPS 的網站或者是測試時的 localhost,若想玩玩看這個 API 就可以到帶有 HTTPS 的 CodePen 上試試看。
  2. 需要透過使用者主動的行爲(user activation)才能觸發,例如,點擊事件。

範例程式碼

來看一下範例程式碼吧,也可以直接看 CodePen。
See the Pen Web Share API by PJCHEN (@PJCHENder) on CodePen.

HTML

先建立最基本的一個按鈕:
<div class="center-center">
  <button>Share<i class="fas fa-share-alt"></i></button>
  <p class="result"></p>
</div>

JavaScript

  1. 透過 document.querySelector() 選擇和 DOM 有關的元素
  2. 建立使用者點擊分享時要帶入的資訊,不用每一項都填寫,也可以只分享文字或網址
  3. Web Share API 需要使用者主動的行為才能觸發, 所以透過 addEventListener 監聽使用者點擊 click 事件
  4. 透過 navigator.share 來使用 Web Share API
  5. 當使用者拒絕分享或發生錯誤時要顯示的訊息
// STEP 1:選擇和 DOM 有關的元素
const btn = document.querySelector('button');
const result = document.querySelector('.result');

// STEP 2:建立使用者點擊分享時要帶入的資訊
const shareData = {
  url: 'https://pjchender.blogspot.com', // 要分享的 URL
  title: 'PJCHENder 那些沒告訴你的小細節', // 要分享的標題
  text: '好多眉眉角角啊', // 要分享的文字內容
};

// STEP 3:當使用者點擊按鈕時
btn.addEventListener('click', async () => {
  try {
    // STEP 4:使用 Web Share API
    await navigator.share(shareData);
    result.textContent = '感謝你的的分享';
  } catch (err) {
    // STEP 5:使用者拒絕分享或發生錯誤
    const { name, message } = err;
    if (name === 'AbortError') {
      result.textContent = '您已取消分享此訊息';
    } else {
      result.textContent = err;
      console.log('發生錯誤', err);
    }
  }
});
如此就完成這個簡單的範例了。
這個範例的按鈕樣式是修改自 Ayooluwa 的 CodePen。
來看一下實作的結果:
Web Share API
以 Line 為例,傳送出去的訊息內容如下:
Web Share API
See the Pen Web Share API by PJCHEN (@PJCHENder) on CodePen.

替代處理與其他(fallback)

對於不支援 Web Share API 的瀏覽器則可以透過判斷 navigator.share 是否存在來進行替代方案:
if (navigator.share) {
  // 使用 Web Share API
} else {
  // 替代方案寫在這...
}
舉例來說,在 CSS Tricks 的 How to Use the Web Share API 文章中提供了非常精緻的替代處理畫面:
Imgur
可以參考這個作者的 CodePen 範例。
如果不想這麼複雜的話,替代方案也可以是點擊按鈕後複製網址(Copy Link)給使用者自行分享即可。複製到剪貼簿的方式同樣有對應的 WebAPIs 可以支援,有需要可以參考先前整理的筆記 [WebAPIs] Copy to clipboard 複製到剪貼簿。

範例程式碼:當瀏覽器不支援時讓按鈕變成複製功能

這裡提供實際的範例可以作為參考:
// 選擇和 DOM 有關的元素
const btn = document.querySelector('button');
const result = document.querySelector('.result');

// 當使用者點擊分享時要帶入的資訊
const shareData = {
  url: 'https://pjchender.blogspot.com', // 要分享的 URL
  title: 'PJCHENder 那些沒告訴你的小細節', // 要分享的標題
  text: '好多眉眉角角啊', // 要分享的文字內容
};

btn.addEventListener('click', () => {
  // 判斷瀏覽器是否支援 Web Share API
  if (navigator.share) {
    handleNavigatorShare();
  } else {
    handleNotSupportNavigatorShare();
  }
});

// 當瀏覽器支援 Web Share API 時
async function handleNavigatorShare() {
  try {
    await navigator.share(shareData);
    result.textContent = '感謝你的的分享';
  } catch (err) {
    // 使用者拒絕分享或發生錯誤
    const { name } = err;
    if (name === 'AbortError') {
      result.textContent = '您已取消分享此訊息';
    } else {
      result.textContent = err;
      console.log('發生錯誤', err);
    }
  }
}

// 當瀏覽器不支援 Web Share API 時,點下去變成複製
function handleNotSupportNavigatorShare() {
  const contentToCopy = document.querySelector('#content-to-copy');
  contentToCopy.value = shareData.url;
  contentToCopy.setAttribute('type', 'text'); // 不是 hidden 才能複製
  contentToCopy.select();

  try {
    const successful = document.execCommand('copy');
    const msg = successful ? '成功' : '失敗';
    alert(`${shareData.url} - 複製${msg}`);
  } catch (err) {
    alert('Oops, unable to copy');
  }

  /* unselect the range */
  contentToCopy.setAttribute('type', 'hidden');
  window.getSelection().removeAllRanges();
}

參考文章