フラッター:バックグラウンドサービス


それで、私がフラッターを実際に試みる時間です.私は最後のdev会議を見ました、そして、私はフラッターがすることができて、将来のフラッター(ウェブ、Windows、Linux)ができることに驚いています.あなたがその会議を見たいならば、ここで...

背景


私は“Hello World”で何かを試すことはありません.私は、「重い」ものと一緒に行きます.だから、私は試していることの力、短所、長所を見ることができます.だから、私は“ミリオネアアイデア”リストからアイデアをつかむと私の旅を始めた.

アプリ:残り


私は本当に簡単なアプリを私は非常に便利ですビルドします.私は、あなたが睡眠に行くとき、私の電話で若干のバックグラウンドミュージックを聞くのが好きである時のために、私がメニエ病(BTWにもその病気があるならば、BTWによって生産される耳鳴り)を持っています.しかし、私は一晩中音楽を演奏している電話を去りたくありません.

研究


たびに私は素晴らしいアイデアを私はGoogleそれを持っている.私は、車輪を再発明したくありません.今回は仕事をするアプリケーションを見つけました.問題は、それが本当に頻繁にハングアップまたは凍結傾向があることです.時々、アプリはすべてのボタンは本当に悪いレンダリングします.だから私はシンプルで機能的なアプリを作ることによって継続することを決めた.

始めましょう


どんなコードの前にも、私はあなたに警告します.独自の研究をしてください.ポストのこれらのシリーズ


一度にフラッターとダーツの基本的な知識を持って読んでください.

MVP


私のアプリは、その最初のリリースでは、私はかなりミニマリストUIとシンプルな機能が欲しい.私はこれらの仕様で行くことにした.
  • タイマーの持続時間は5
  • ユーザーは5分で時間を追加または減算することができます
  • スタート/ストップボタン
  • これが結果だ

    フラッタメソッドコール


    アプリは、カウントダウンタイマーがあります.私はそのタイマーを実行し続けると最終的に音楽をオフにするときに終了するサービスが必要です.
    しかし、ここでは、他のアプリが失敗したときに、アプリケーションを閉じて、再度開いている場合は、タイマーのサービスで実行されている経過時間を知る必要があるので、状態を更新することができますし、そこから現在の時刻を示し始める.
    私はすでにAndroidサービスをコード化しなければならないことを知っていたので、私は少しの研究をして、私が必要としたものを得ました.Flutter Method Call Docs

    Androidサービスの構築


    まず、Androidマニフェスト( Android/app/src/main/androidmanifest . xml )でサービスを宣言する必要があります.
    <service android:enabled="true" android:exported="true" android:name="dev.protium.rest.AppService" />
    
    今、サービスを書く必要があります.サービスはこれらの仕様を満たす必要があります.

    1 )主な活動との接続をバインドできるはずです。


    そのためにバインダーを使用する
    private final IBinder binder = new AppServiceBinder();
    public class AppServiceBinder extends Binder {
            AppService getService() {
                return  AppService.this;
            }
        }
    
    @Override
    public IBinder onBind(Intent intent) {
         return binder;
    }
    

    2 )起動時に停止し、現在の秒数を要求します。


    このコードはこの記事には関係ありませんが、記事の最後にrepoを見ることができます.

    3 )演奏されている場合は音楽を一時停止する必要があります


    あなたが音楽やAndroidデバイスを一時停止する方法について興味がある場合は、これはトリックです
    AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
    if (am.isMusicActive()) {
      long eventtime = SystemClock.uptimeMillis();
      KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PAUSE, 0);
      am.dispatchMediaKeyEvent(downEvent);
      KeyEvent upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PAUSE, 0);
      am.dispatchMediaKeyEvent(upEvent);
    }
    
    魔法、右?

    サービスへの接続


    この時点で、あなたは、コミュニケーションがこのようになるのに気がつきました
    Android Service <-> Android Activity <-> Flutter App
    

    活動からの接続


    これはかなり簡単です
    private void connectToService() {
            if (!serviceConnected) {
                Intent service = new Intent(this, AppService.class);
                startService(service);
                bindService(service, connection, Context.BIND_AUTO_CREATE);
            } else {
                Log.i(TAG, "Service already connected");
                if (keepResult != null) {
                    keepResult.success(null);
                    keepResult = null;
                }
            }
        }
    
    private ServiceConnection connection = new ServiceConnection() {
    
            @Override
            public void onServiceConnected(ComponentName className,
                                           IBinder service) {
                AppService.AppServiceBinder binder = (AppService.AppServiceBinder) service;
                appService = binder.getService();
                serviceConnected = true;
                Log.i(TAG, "Service connected");
                if (keepResult != null) {
                    keepResult.success(null);
                    keepResult = null;
                }
            }
    
            @Override
            public void onServiceDisconnected(ComponentName arg0) {
                serviceConnected = false;
                Log.i(TAG, "Service disconnected");
            }
        };
    
    あなたは気づいたkeepResult 変数後でそれ以上.

    フラッターへの活動の接続


    static final String CHANNEL = "dev.protium.rest/service";
    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            GeneratedPluginRegistrant.registerWith(this);
    
            new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(this::onMethodCall);
        }
    
    クラスの宣言を変更しなければならないので、インターフェイス自体にインタフェースを実装することを決めました
    public class MainActivity extends FlutterActivity implements MethodChannel.MethodCallHandler {
    
    そして今実装
    @Override
    public void onMethodCall(MethodCall call, MethodChannel.Result result) {
            try {
                if (call.method.equals("connect")) {
                    connectToService();
                    keepResult = result;
                } else if (serviceConnected) {
                    if (call.method.equals("start")) {
                        appService.startTimer(call.argument("duration"));
                        result.success(null);
                    } else if (call.method.equals("stop")) {
                        appService.stopTimer();
                        result.success(null);
                    } else if (call.method.equals("getCurrentSeconds")) {
                        int sec = appService.getCurrentSeconds();
                        result.success(sec);
                    }
                } else {
                    result.error(null, "App not connected to service", null);
                }
            } catch (Exception e) {
                result.error(null, e.getMessage(), null);
            }
        }
    
    私たちはMethodChannel.Result 変数にkeepResult . なぜ?サービス接続でサービスをバインドすると、onServiceConnected リスナー.そこに我々はサービスに接続されて知っている.フラッターアプリケーションは、成功または失敗にこのコールバックを待ちます.それを忘れるな.

    フラッターのアクティビティへの接続


    まず、パッケージをlib/mainにインポートする必要があります.ダート
    import 'dart:async'
    import 'package:flutter/services.dart';
    
    我々の状態装置の中で、我々はこれを必要とします
    static const MethodChannel platform = 
    MethodChannel('dev.protium.rest/service');
    
    Future<void> connectToService() async {
        try {
          await platform.invokeMethod<void>('connect');
          print('Connected to service');
        } on Exception catch (e) {
          print(e.toString());
        }
    }
    
    
    注意:チャネルは、メインアクティビティと同様に、メソッド名と同じです.よく聞こえる?いくつかのApache Cordovaプラグインを開発したなら、これは本当にあなたによく知らなければなりません.
    今、私たちはこの3つのコンポーネント-接続のことで行われます.一度フラッタアプリは、開始/停止方法を呼び出すことができるか、またはサービスタイマから現在の秒を取得接続することができます.
    final int serviceCurrentSeconds = await getServiceCurrentSeconds();
    setState(() {
        _currentSeconds = serviceCurrentSeconds;
    });
    
    任務達成

    フラッターから学んだこと


    私が早く言及したように、私は「こんにちはWold」アプリが好きでありません.このアプリはかなり簡単ですが、それが行われるいくつかのトリックがあります.私はフラッタとDARTのタイプ推論に恋をしていると思います.この全体のプロセスは私を正確に2日かかった、私は自慢ではない.私は昨日ラップトップに座った.私は夜にアプリを終えた.今日私はそれを公開しましたGoogle Play Store そして、この記事を書きました.(BTWは初めてアプリを出版する)
    私は多くのトリックを学びました.
  • サービスを呼び出すことなくウィジェットテストを実行する方法
  • どのように最初のアプリケーションのアクセス許可を設定してテストドライブを実行する
  • どのように重要で有用ですflutter analyzeあなたはすべてのレポで見ることができます

    原生生物 / 残り


    音楽をオフにオフの期間と残り時間後


    残り


    注意:このレポは維持されていません.
    時間の期間後に音楽を一時停止するシンプルなアプリ.
    このアプリはフラッターで開発されました

    Googleプレイからインストール



    開発


    依存:
  • アンドロイドSDK
  • アンドロイド
  • フラッターSDK
  • 依存関係をチェックするflutter doctor

    テスト

    flutter test
    flutter drive --target=test_driver/home_page.dart 
    

    走る

    flutter run

    スクリーンショット




    トドス

  • 付箋通知
  • 音楽が一時停止したときにトーストメッセージを表示する
  • 寄付する


    あなたがこのアプリが好きなら、私にコーヒーを買って自由に感じる

    シュールブライアンメイヨー
    View on GitHub
    私はこの小さなプロジェクトで学んだ他のトリックについての記事を投稿します.私はあなたの個人的な“ミリオネアアイデア”リストからいくつかのアイデアをつかむことを奨励し、フラッターで1つを確認します.

    結論


    私は、それが痛みの多くなしで素敵なUIを得るために私に数分かかったことを嬉しく思います.そして、私は本当にフラッターウェブとデスクトップで遊ぶのを熱望しています.私はこれに多くの可能性を参照してください私は私は仕事の会社のCTOは、我々はいくつかの製品を移行する必要がありますフラッターに語った.我々はマルチプラットフォームアプリ(テレビ、スマートフォン、デスクトップ、WebViewで何か)以来、利点が高いです.
    アプリを試してみて、より多くの機能に貢献すること自由に感じなさい.私はより多くの機能を追加する予定ですが、今のところ私は基本的な機能を持って大丈夫です.
    そして、あなたがIOSのためにそれをコンパイルして、出版したいならば、知らせてください.