たまたま私は一つの議論を失い、私は大胆に剃らなければなりませんでした。 なぜなら 私の頭への新鮮なアイデアの流れを妨げるものは他にありませんでした。外に見えるのは残念でした。それから、最高の開発環境の1つに社会的に役立つプラグインを書き始めました。 機能はペアのトウモロコシの穂軸のようにシンプルですが、非常に必要です(これがデフォルトで組み込まれていない理由は想像できません)。 それで、今日は、接続したAndroidデバイスから作業中のアプリケーションをエレガントに削除できるプラグインの開発での私の経験を共有しようとします。
使用を開始したいだけの人のために、 AltGraph + Uと呼ばれるように見えます:
ここからダウンロード( ver。1.0.1 ): github.com/Ghedeon/ADB-Uninstall/releases
インストール: 設定→プラグイン→ディスクからプラグインをインストール...
重要:プラグインは生なので、インストールする人が問題の購読を中止することを本当に望みます。 できる限り訂正します。 レビュー、コメント、機能を拡張するための提案-すべてが大歓迎です!
Android開発者の日常のシナリオをいくつか示します(特にチームで作業する場合):
ユースケース1:
チームは1つのアプリケーションで作業します。 誰かとデバイスを交換し、インストールが完了するまで辛抱強く待ちます。 結果は何ですか? そう、 失敗[INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]。 デバイスには同僚からのアプリケーションがあり、アプリケーションの署名に使用されるデバッグキーはそれぞれ異なるため、 更新は機能しないため、論理的です。 呪い、コマンドラインに登り、"adb uninstall <package>"
と入力し、プログラムがバイト単位でどのように
"adb uninstall <package>"
されるかをほとんど物理的に感じます。
ユースケース2:
システムに1つではなく2つのデバイスがあり、 adbはどちらを削除するかわからないため、すべてが同じで、"adb uninstall"
何も起こりません。 頭の中で状況の愚かさをすべて受け入れて、
"adb devices"
と入力してイライラした気持ちで、デバイスのリストを取得し、
"adb -s <deviceId> uninstall <package>"
と世界があなたに降伏します。
ユースケース3:
複数の接続されたデバイスがあり、すべてから削除する必要があります。 さて、ここで最も怠ziな人は、キッチン全体を何らかの形で自動化するスクリプトを作成します。ユースケース4:
問題はありませんが、あなたは"adb uninstall <package>"
と書くのが
"adb uninstall <package>"
です。
ソリューション:
- チームのすべてのメンバーが1つのデバッグキーを使用すると、システムの観点から見ると、すべてが1台のコンピューターで作業しているように見えます。
- 自作のスクリプト。できれば、パッケージの名前を尋ねない程度にスマート。
実際、最近までスクリプトを中断しましたが、当局がチーム内でより積極的に連絡を取り合うことを要求するまで、それは完全に私に合っていました。 誰かのオウムの健康に興味を持ち、誠実に夢中になっている外見に耐えるように最善を尽くすという選択肢は、絶望的であるとして拒否されました。
スクリプト自体
#!/bin/bash package=`grep -o 'package=".*"' AndroidManifest.xml | grep -o \".* | sed 's/"//g'` #adb uninstall $package adb devices | tail -n +2 | awk '{print $1}' | xargs -I {} adb -s {} uninstall $package
開発
habr上のIDEAのプラグインについては、すでにLucyferからの7つの部分の記念碑的な翻訳は費用がかかると書かれているため、IDEの一般的な構造とセットアップは省略します。 メニューやツールバーに独自のアイテムを追加するために、 AnActionを継承し、 actionPerformed()メソッドを再定義します 。 まず、 Android SDKへの絶対パスを見つけます 。
ProjectRootManager.getInstance(event.getProject()).getProjectSdk().getHomePath();
これに
/platfrom-tools
を追加すると、作業フォルダーへのパスが得られ、そこからadbを実行できます。
ご注意
最初に、私は他の方法に進むことにしました。ユーザーが環境変数でAndroid SDKへのすべてのパスを正しく構成し、それらをプロセスに渡すことを期待するためです。 そうすれば、絶対パスは必要ありません。インタープリターは、実行したいコマンドについて知っています。 ただし、 LinuxおよびMac OSでは 、ご存じのように、環境変数は1000の比較的まともな場所に詰め込まれている可能性があるため、
にいると明確に言うことはできません。 一般に、さまざまなシステム設定で、この方法は失敗し、私はバックアウトすることにしました。 後に、IDEA用のAndroidプラグインのソースコードを詳しく調べたところ、私と同じように絶対パスを使用していることがわかりました。
System.getenv()
にいると明確に言うことはできません。 一般に、さまざまなシステム設定で、この方法は失敗し、私はバックアウトすることにしました。 後に、IDEA用のAndroidプラグインのソースコードを詳しく調べたところ、私と同じように絶対パスを使用していることがわかりました。
接続されたデバイスのリストを取得します。
Process pr = Runtime.getRuntime().exec(toolPath + File.separator + "adb devices");
Javaの
Runtime.exec()
を使用しましたが、同時に、IDEAはそのようなことに対してより適切な
GeneralCommandLine
を提供します。 実際、私はまだTODOでこの移行を行っており、誰かが経験を共有してくれたら本当に感謝しています。
次に、削除するパッケージの名前を決定する必要があります。 オプションがあるかもしれません。 Androidプロジェクトには、異なるパッケージ名を持つ複数の実行可能モジュールが含まれる場合があります。 まだ図書館プロジェクトがあるかもしれませんが、私たちはそれらについて話していません。 最初に思いついたのは、現在アクティブなモジュールのAndroidManifest.xmlからパッケージ名を取得することでした。 しかし、これはあまり便利ではないことが判明したため、削除するモジュールで作業できない可能性があるため、最初にマウスで目的のモジュールを選択する必要がありました。 その結果、現在の起動構成で指定されているモジュールのマニフェストからパッケージ名を抽出するという、はるかに論理的なソリューションに落ち着きました。 説明します。 ご存知のように、アプリケーションをインストールするには、少なくとも1つの実行構成が必要です。 この実行構成自体を作成するときは、[ 全般 ]タブでModuleを指定します。 指定されたモジュールのマニフェストから、パッケージ名を取得します。 複数の構成がある場合、現在アクティブな構成を使用します。
アクティブな構成を取得します。
RunManager runManager = RunManager.getInstance(event.getProject()); ModuleBasedConfiguration selectedConfiguration = (ModuleBasedConfiguration) runManager.getSelectedConfiguration().getConfiguration();
次のステップは、 AndroidManifest.xmlでフォルダーへの正確なパスを見つけることです。 古い構造のプロジェクトの場合、これはモジュールの単なるルートになります。 gradle ベースのプロジェクトの場合、これは通常currentModulePath / src / mainであり、考慮する必要があります。 モジュール自体のルートは次のように取得されます。
Module module = selectedConfiguration.getConfigurationModule().getModule(); currentModuleFilePath = module.getModuleFilePath(); String currentModulePath = currentModuleFilePath.substring(0, currentModuleFilePath.lastIndexOf(File.separator));
パッケージ属性に対して同じStAXパーサーによって検出されたAndroidManifest.xmlの解析は、すでに簡単なタスクです。
実際、受信したデータ( deviceIdおよびpackage )は、 adb uninstallを直接続行するのに十分です。 しかしその前に、私たちは別の、主に化粧品のことをします。 deviceIdでデバイスを区別するのはあまり便利ではないので、ユーザーにより読みやすい情報を提供するようにします。 このために、各デバイスに対して次のコマンドを実行します。
adb -s <deviceId> shell cat /system/build.prop;
その結果は、デバイスのさまざまな特性の長いリスト(実際には、これは連想配列です)になります。 必要なものだけを選択します。すなわち、
ro.product.manufacturer ro.product.model ro.build.version.release ro.build.version.sdk
その結果、ユーザーは抽象スペルR32CC02G02Zの代わりに、 「Samsung Nexus 10 Android 4.3(API 18)」という誇らしげな言葉を目にします。
事は小さく、ユーザーにこのすべてのものを含むモーダルウィンドウを表示し、選択されたデバイスのリストを取得し、ライブキューの順に、切望されているadb uninstallを実行します。
Process pr = Runtime.getRuntime().exec(toolPath + File.separator + "adb -s " + device.getSerialNumber() + " uninstall " + packageName);
以上です。
GitHubプロジェクトのソースコード: github.com/Ghedeon/ADB-Uninstall 。
追加:
- ユーザー宛のログとさまざまなメッセージには、
Notifications.Bus.notify(<notification>)
ます。 ユーザー設定に応じて、メッセージはユーザーインターフェイスの1つまたは複数の場所に表示されます: イベントログ、バルーン、スティッキーバルーン、ツールウィンドウバルーン 。 またはまったく表示されません。 - アドオンがオーガニックに見えるようにユーザーと対話するには、ベアSwingではなく、 IntelliJ IDEAが提供するコンポーネントを使用することをお勧めします。 特に、このセットのDialog Wrapperを使用しました。
- 私にとって重要な未実現のポイントは、少なくともプラグインの失敗に関する統計を収集することです。 現時点では、プラグインのクラッシュに応じて、IDEAがバグレポートをGoogleに送信することを提案している、ある種の奇妙な状況があります。 誰かがCrashlyticsのようなツールを知っていれば、 Swingアプリケーション専用のヒントに感謝します。
ユーザーLucyferとyoleについて言及したいと思います。 彼らの良いアドバイスに感謝します。