2021年2月3日 星期三

Flutter 開發文件之 iOS 與 Android 實作筆記 - 使用 Admob 以 Interstitial ads 為例


關於 flutter 使用 Admob 的架構,可參考網路上數篇文章:
此例筆記 iOS & Android 的設定方式,並且記錄碰到的錯誤訊息。

Android app 設定方式:

1. 更新 flutter_app/pubspec.yaml 添加 dependencies (記得要運行 flutter pub get)

firebase: ^8.0.0
firebase_admob: ^0.11.0+1

2. 安置從 Firebase 建立專案時得到的 google-services.json 檔案,擺在 flutter_app/android/app/ 中

3. 更新 flutter_app/android/build.gradle 的 buildscript -> dependencies 設定

//classpath 'com.android.tools.build:gradle:3.5.0'
// 為了修正錯誤訊息:error: unexpected element <queries> found in <manifest>.
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.google.gms:google-services:4.3.3'

4. 更新 flutter_app/android/gradle/wrapper/gradle-wrapper.properties 的 gradle 版本至 6.1.1

#為了修正錯誤訊息:Minimum supported Gradle version is 6.1.1. Current version is 5.6.2. If using the gradle wrapper
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

5. 增加 flutter_app/app/build.gradle 的 apply 項目

apply plugin: 'com.google.gms.google-services'

6. 更新 flutter_app/android/app/src/main/AndroidManifest.xml 添加 meta data (僅範例程式數值)

<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-3940256099942544~3347511713"/>

7. 更新 flutter_app/lib/main.dart (此改自於範例程式,讓 add Button 可以產生一個插頁廣告)

iOS app 設定方式:

1. 更新 flutter_app/pubspec.yaml 添加 dependencies(記得要運行 flutter pub get)

firebase: ^8.0.0
firebase_admob: ^0.11.0+1

2. 安置從 Firebase 建立專案時得到的 GoogleService-Info.plist ,用 Xcode 打開專案,把 GoogleService-Info.plist 拖拉擺入跟 Info.plist 的同階目錄位置。

% open flutter_app/ios/Runner.xcworkspace
% ls flutter_app/ios/Runner/GoogleService-Info.plist

3. 更新 Info.plist 內容,添加資訊 GADApplicationIdentifier 等資訊(僅範例程式數值)

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
<key>SKAdNetworkItems</key>
  <array>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>cstr6suwn9.skadnetwork</string>
    </dict>
  </array>

4. 更新 Podfile ,上方添加 platform :ios, '10.0'

為了修正錯誤訊息: 
Automatically assigning platform `iOS` with version `9.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile.

5. 更新 flutter_app/lib/main.dart (此改自於範例程式,讓 add Button 可以產生一個插頁廣告)

如此就收工啦!而 flutter_app/lib/main.dart 內容如下:

import 'package:flutter/material.dart';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_admob/firebase_admob.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  MobileAdTargetingInfo targetingInfo = MobileAdTargetingInfo(
    keywords: <String>['flutterio', 'beautiful apps'],
    contentUrl: 'https://flutter.io',
    childDirected: true,
    nonPersonalizedAds: true,
  );

  InterstitialAd _interstitialAd;

  InterstitialAd createInterstitialAd() {
    return InterstitialAd(
      adUnitId: InterstitialAd.testAdUnitId,
      targetingInfo: targetingInfo,
      listener: (MobileAdEvent event) {
        print("InterstitialAd event $event");
      },
    );
  }

  @override
  void initState() {
    super.initState();
    FirebaseAdMob.instance.initialize(appId: FirebaseAdMob.testAppId);
    //_interstitialAd = createInterstitialAd()..load();
  }

  @override
  void dispose() {
    _interstitialAd?.dispose();
    super.dispose();
  }

  void _incrementCounter() {
    _interstitialAd?.dispose();
    _interstitialAd = createInterstitialAd()..load()..show();
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

 

2021年1月23日 星期六

Chromecast with Google TV - 透過網頁安裝 愛奇藝 TV app 與 愛奇藝手機程式投放到 Chromecast


前陣子不小心買了 Chromecast with Google TV ,想說來試試看,結果裡頭一堆台灣內容提供者 App 不能安裝,如:

  • 動畫瘋
  • 愛奇藝
  • CATCHPLAY+
就明明在 應用程式 -> 娛樂 都有顯示一堆台灣的內容服務,卻說因為國家地區而無法安裝 Orz 推論可能是手上這台是美國貨...有地區限制吧?真是殘念

Updated @ 2021-02-03:

主要是我使用的 Google account 的地區落在美國。可以在 https://play.google.com/store/paymentmethods 的付款方式,查看網頁底部的 地 區資訊 

後來在找了一下,嘿嘿,原來可以靠網頁來安裝程式,立即測試了一下!但不是每一款都能安裝。

在 2021/01/23 成功者:
在 2021/01/23 失敗者:
後續再等看看會不會有什麼變化。

另外,愛奇藝其實有分新加坡(香港)跟北京兩個 App ,其中新加坡(香港)的手機程式可以直接投放到 Chromecast 上,而北京的不行,有興趣可以去找找!

2021年1月22日 星期五

Flutter 開發文件之 iOS 與 Android 實作筆記 - 使用 Firebase 回報 App 使用人數


先說一下,有出類似文件教人怎樣使用 Firebase - Admob 部分,在此僅流水帳紀錄引用 firebase 的用法,體驗一下透過 Flutter 同時開發 ios 和 android app 時,並且使用額外函式庫的過程。

原理:

1. 使用 Android Studio + Flutter plugin 來建立 Flutter 專案
- 在此 package name 使用 org.changyy.study.flutter
- 自動產生 android Package Name = org.changyy.study.flutter_app
- 自動產生 iOS Bundle ID = org.changyy.study.flutterApp
- 假定專案位於 ~/AndroidStudioProjects/flutter_app

2. 建立 Firebase 專案
- 在此使用 org-changyy-study-flutter 作為 firebase project name

3. iOS app
- 使用 Xcode 置入 firebase 的設定檔案 GoogleService-Info.list
- 用指令打開專案 % open ~/AndroidStudioProjects/flutter_app/ios/Runner.xcworkspace/
- 使用 CocoaPods 添加 Firebase 函式庫
- 在 AppDelegate.swift 置入 Firebase 啟動程式碼

4. Android app
- 依照 Firebase 專案建置過程安置 google-service.json 檔案
- 在 <專案>/build.gradle 設置相依套件 com.google.gms:google-service:4.3.4
- 在 <專案>/app/build.gradle 添加 plugin 和引入 com.google.firebase:firebase-analytics

5. 回到 Flutter 專案,分別叫出 iOS simulator 跟 Android emulator 運行


若沒意外,就可以同時在這兩個模擬器上跑出來,並且在 Firebase 專案後臺,看到兩個使用者:



2021年1月14日 星期四

[Javascript] 複寫 XMLHttpRequest 來紀錄 Network Request URL @ Chrome Browser DevTools

最近 podcast 很夯,來研究 <audio> 。之前研究過 <video> 就有發現現在都用很夯 blob 的播放方式,透過 JS 片段下載資料交給 <video> 播放,以至於從 JS 調閱出 <video> 元件時,看不到真實的影片來源,而是一連串 blob (Binary Large Object) 記憶體位置。

原本想說在 Chrome DevTools 下,能不能靠 JS 取得 network request 發送清單來做應用,看著看著突然腦筋一轉,乾脆就用 XMLHttpRequest 好了,多包一層就可以收集了。

用法:

//
// https://stackoverflow.com/questions/7775767/javascript-overriding-xmlhttprequest-open
//
(function() {
var proxied = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function() {
// console.log( arguments );
//
// 只關注 m3u8 來源
//
if (arguments.length >= 2 && arguments[1].indexOf('.m3u8') > 0) {
console.log( arguments );
// return;
}
return proxied.apply(this, [].slice.call(arguments));
};
})();

2021年1月9日 星期六

[開箱] Chromecast with Google TV - 2020/09/30 發表

Chromecast with Google TV

沒想到一進入 2021年,突然又手癢了!立馬買了 Chromecast with Google TV 來把玩。之前沒那麼想入手是因為台灣還買不到,以及自己已經有 Chromecast Ultra,興趣缺缺,但人果真很善變,過了幾個月就突然想起,又快速下手買了一個 XD 這次嘗試粉色系,連內附的電池外裝也粉色!

Chromecast with Google TV

這次體驗的心情,就像 Apple TV 的感受一樣,有個遙控器,並且跟市面上的新電視或電視和一樣支援語音輸入(語音搜尋),我之前對 Apple TV / Android TV 沒這麼愛的主因是輸入難用並認為手機就是本體,凡事都走投影來釋放手機資源,但對 Google TV 可以安裝 App 仍感興趣,這次測試了一下 NETFLIX 後,感覺 NETFLIX 的 UX 體驗在各平台皆非常相近,當下也不會覺得不方便(感興趣都在首頁,滑一滑點一下就可以觀看)

之前有朋友很想要觀看 NETFLIX 4K 內容,查了一下 Chromecast with Google TV 是有支援的,若真的可以用 49.99 美金買到,真的物超所值。這在 NETFLIX 官方文件也有提到:

以下 Chromecast 型號目前支援 Netflix 超高畫質串流功能:

Chromecast Ultra

Chromecast with Google TV

ref: 如何在 Chromecast 上使用 Netflix 

回過頭來,聊聊裝置的啟用,就包括會經過 Google Home app 掃描電視上的 QRCode,而手機過程也可以看到能多訂閱很多項目、音控辨識是否個人化等等,其中有個過程是會配對遙控器紅外線跟電視聲音的控制,十分貼心,因為許多類似設備就算有遙控器也沒規劃用紅外線去控制電視的聲音。

Chromecast with Google TV

感受比較深的是多了很多內容,以前用投影的方式必須自己去尋找有哪些內容,而採用 Google TV 則是大家為主動擠到這個 Android TV Google play 上,像是美國已上線的 Disney+ 等等,有趣的,我反而在 Android TV Google play 上,無法下載 myVideo, LiTV 這類本土程式,不知道是不是 Chromecast with Google TV 內有地區資訊,若是這種綁定關係,在意的就只能再等等吧?不知是不是本土商只在 TW region 上架,還是哪邊可以更改 Chromecast with Google TV 設備的所在地:

Chromecast with Google TV

Updated @ 2021/01/23:使用 Google Play 網頁版安裝愛奇藝

Updated @ 2021/02/03:主要是我使用的 Google account 的地區落在美國。可以在 https://play.google.com/store/paymentmethods 的付款方式,查看網頁底部的 地區 資訊

其餘細節是這款要求外部電源供應,直接插電視 USB 會提醒這是行不通的:

Chromecast with Google TV

最後,Google TV 上面的預設首頁也會隨著使用過的內容 App 節錄出該 App 的熱門內容,效果跟 NETFLIX 首頁很像,這樣一眼可以得知哪些感興趣可以點擊:

Chromecast with Google TV

相關文章: