多量の音楽 mp3ファイル群を Googleドライブ上に保存する.
オンラインなパソコン上では アプリをいれておけば,
通常のディレクトリのようにGUI上でドラッグ&ドロップで
Googleドライブ上に保存できる.
アプリ設定で「自動起動」にしておけば何も考えることはない.
で,これら複数音楽ファイルを
どうやって Android 端末上で聞いたらいいのか.
いまさらだけども.
多量の音楽 mp3ファイル群を Googleドライブ上に保存する.
オンラインなパソコン上では アプリをいれておけば,
通常のディレクトリのようにGUI上でドラッグ&ドロップで
Googleドライブ上に保存できる.
アプリ設定で「自動起動」にしておけば何も考えることはない.
で,これら複数音楽ファイルを
どうやって Android 端末上で聞いたらいいのか.
いまさらだけども.
adb コマンドがめんどくさい場合は
コマンドを補完(completion)してもらいましょう.
何が補完できるか.
・オプション
・サブコマンド
・デバイスにインストールしているパッケージ名
・ローカル/リモートファイル名
・パソコンに接続しているデバイスシリアル名
...
# /* vim: set ai ts=4 ft=sh: */ |
# |
# Copyright 2011, The Android Open Source Project |
# |
# Licensed under the Apache License, Version 2.0 (the "License"); |
# you may not use this file except in compliance with the License. |
# You may obtain a copy of the License at |
# |
# http://www.apache.org/licenses/LICENSE-2.0 |
# |
# Unless required by applicable law or agreed to in writing, software |
# distributed under the License is distributed on an "AS IS" BASIS, |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
# See the License for the specific language governing permissions and |
# limitations under the License. |
# |
_adb() { |
unset - v have |
type $1 &> /dev/null && have= "yes" |
if [ "$have" != "yes" ]; then |
return |
fi |
local where i cur serial |
COMPREPLY=() |
serial= "${ANDROID_SERIAL:-none}" |
where=OPTIONS |
for ((i=1; i <= COMP_CWORD; i++)); do |
cur= "${COMP_WORDS[i]}" |
case "${cur}" in |
-s) |
where=OPT_SERIAL |
;; |
-p) |
where=OPT_PATH |
;; |
-*) |
where=OPTIONS |
;; |
*) |
if [[ $where == OPT_SERIAL ]]; then |
where=OPT_SERIAL_ARG |
elif [[ $where == OPT_SERIAL_ARG ]]; then |
serial=${cur} |
where=OPTIONS |
else |
where=COMMAND |
break |
fi |
;; |
esac |
done |
if [[ $where == COMMAND && $i - ge $COMP_CWORD ]]; then |
where=OPTIONS |
fi |
OPTIONS= "-d -e -s -p" |
COMMAND= "devices connect disconnect push pull sync shell emu logcat lolcat forward jdwp install uninstall bugreport help version start-server kill-server get-state get-serialno status-window remount reboot reboot-bootloader root usb tcpip" |
case $where in |
OPTIONS|OPT_SERIAL|OPT_PATH) |
COMPREPLY=( $(compgen -W "$OPTIONS $COMMAND" -- "$cur" ) ) |
;; |
OPT_SERIAL_ARG) |
local devices=$( command adb devices 2> /dev/null | grep - v "List of devices" | awk '{ print $1 }' ) |
COMPREPLY=( $(compgen -W "${devices}" -- ${cur}) ) |
;; |
COMMAND) |
if [[ $i - eq $COMP_CWORD ]]; then |
COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur" ) ) |
else |
i=$((i+1)) |
case "${cur}" in |
install ) |
_adb_cmd_install "$serial" $i |
;; |
pull) |
_adb_cmd_pull "$serial" $i |
;; |
push) |
_adb_cmd_push "$serial" $i |
;; |
reboot) |
if [[ $COMP_CWORD == $i ]]; then |
args= "bootloader recovery" |
COMPREPLY=( $(compgen -W "${args}" -- "${COMP_WORDS[i]}" ) ) |
fi |
;; |
shell) |
_adb_cmd_shell "$serial" $i |
;; |
uninstall) |
_adb_cmd_uninstall "$serial" $i |
;; |
esac |
fi |
;; |
esac |
return 0 |
} |
_adb_cmd_install() { |
local serial i cur where |
serial=$1 |
i=$2 |
where=OPTIONS |
for ((; i <= COMP_CWORD; i++)); do |
cur= "${COMP_WORDS[i]}" |
case "${cur}" in |
-*) |
where=OPTIONS |
;; |
*) |
where=FILE |
break |
;; |
esac |
done |
cur= "${COMP_WORDS[COMP_CWORD]}" |
if [[ $where == OPTIONS ]]; then |
COMPREPLY=( $(compgen -W "-l -r -s" -- "${cur}" ) ) |
return |
fi |
_adb_util_complete_local_file "${cur}" '!*.apk' |
} |
_adb_cmd_push() { |
local serial IFS=$ '\n' i cur |
serial=$1 |
i=$2 |
cur= "${COMP_WORDS[COMP_CWORD]}" |
if [[ $COMP_CWORD == $i ]]; then |
_adb_util_complete_local_file "${cur}" |
elif [[ $COMP_CWORD == $(($i+1)) ]]; then |
if [ "${cur}" == "" ]; then |
cur= "/" |
fi |
_adb_util_list_files $serial "${cur}" |
fi |
} |
_adb_cmd_pull() { |
local serial IFS=$ '\n' i cur |
serial=$1 |
i=$2 |
cur= "${COMP_WORDS[COMP_CWORD]}" |
if [[ $COMP_CWORD == $i ]]; then |
if [ "${cur}" == "" ]; then |
cur= "/" |
fi |
_adb_util_list_files $serial "${cur}" |
elif [[ $COMP_CWORD == $(($i+1)) ]]; then |
_adb_util_complete_local_file "${cur}" |
fi |
} |
_adb_cmd_shell() { |
local serial IFS=$ '\n' i cur |
local -a args |
serial=$1 |
i=$2 |
cur= "${COMP_WORDS[i]}" |
if [ "$serial" != "none" ]; then |
args=(-s $serial) |
fi |
if [[ $i - eq $COMP_CWORD && ${cur:0:1} != "/" ]]; then |
paths=$( command adb ${args[@]} shell echo '$' PATH 2> /dev/null | tr -d '\r' | tr : '\n' ) |
COMMAND=$( command adb ${args[@]} shell ls $paths '2>' /dev/null | tr -d '\r' | { |
while read -r tmp; do |
command =${tmp ##*/} |
printf '%s\n' "$command" |
done |
}) |
COMPREPLY=( $(compgen -W "$COMMAND" -- "$cur" ) ) |
return 0 |
fi |
i=$((i+1)) |
case "$cur" in |
ls ) |
_adb_shell_ls $serial $i |
;; |
/*) |
_adb_util_list_files $serial "$cur" |
;; |
*) |
COMPREPLY=( ) |
;; |
esac |
return 0 |
} |
_adb_cmd_uninstall() { |
local serial i where cur packages |
serial=$1 |
i=$2 |
if [ "$serial" != "none" ]; then |
args=(-s $serial) |
fi |
where=OPTIONS |
for ((; i <= COMP_CWORD; i++)); do |
cur= "${COMP_WORDS[i]}" |
case "${cur}" in |
-*) |
where=OPTIONS |
;; |
*) |
where=FILE |
break |
;; |
esac |
done |
cur= "${COMP_WORDS[COMP_CWORD]}" |
if [[ $where == OPTIONS ]]; then |
COMPREPLY=( $(compgen -W "-k" -- "${cur}" ) ) |
fi |
packages="$( |
command adb ${args[@]} shell pm list packages '2>' /dev/null 2> /dev/null | tr -d '\r' | { |
while read -r tmp; do |
local package=${tmp #package:} |
echo -n "${package} " |
done |
} |
)" |
COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "${packages}" -- "${cur}" ) ) |
} |
_adb_shell_ls() { |
local serial i cur file |
local -a args |
serial=$1 |
i=$2 |
if [ "$serial" != "none" ]; then |
args=(-s $serial) |
fi |
where=OPTIONS |
for ((; i <= COMP_CWORD; i++)); do |
cur= "${COMP_WORDS[i]}" |
case "${cur}" in |
-*) |
where=OPTIONS |
;; |
*) |
where=FILE |
break |
;; |
esac |
done |
file = "${COMP_WORDS[COMP_CWORD]}" |
if [[ ${ file } == "" ]]; then |
file = "/" |
fi |
case $where in |
OPTIONS) |
COMPREPLY=( $(compgen -W "$OPTIONS" -- "$cur" ) ) |
_adb_util_list_files $serial "$file" |
;; |
FILE) |
_adb_util_list_files $serial "$file" |
;; |
esac |
return 0 |
} |
_adb_util_list_files() { |
local serial dir IFS=$ '\n' |
local -a toks |
local -a args |
serial= "$1" |
file = "$2" |
if [ "$serial" != "none" ]; then |
args=(-s $serial) |
fi |
toks=( ${toks[@]-} $( |
command adb ${args[@]} shell ls -dF ${ file } "*" '2>' /dev/null 2> /dev/null | tr -d '\r' | { |
while read -r tmp; do |
filetype=${tmp%% *} |
filename=${tmp:${ #filetype}+1} |
if [[ ${filetype:${ #filetype}-1:1} == d ]]; then |
printf '%s/\n' "$filename" |
else |
printf '%s\n' "$filename" |
fi |
done |
} |
)) |
# Since we're probably doing file completion here, don't add a space after. |
if [[ $( type -t compopt) = "builtin" ]]; then |
compopt -o nospace |
fi |
COMPREPLY=( ${COMPREPLY[@]:-} "${toks[@]}" ) |
} |
_adb_util_complete_local_file() |
{ |
local file xspec i j |
local -a dirs files |
file =$1 |
xspec=$2 |
# Since we're probably doing file completion here, don't add a space after. |
if [[ $( type -t compopt) = "builtin" ]]; then |
compopt -o plusdirs |
if [[ "${xspec}" == "" ]]; then |
COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}" ) ) |
else |
compopt +o filenames |
COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}" ) ) |
fi |
else |
# Work-around for shells with no compopt |
dirs =( $(compgen -d -- "${cur}" ) ) |
if [[ "${xspec}" == "" ]]; then |
files=( ${COMPREPLY[@]:-} $(compgen -f -- "${cur}" ) ) |
else |
files=( ${COMPREPLY[@]:-} $(compgen -f -X "${xspec}" -- "${cur}" ) ) |
fi |
COMPREPLY=( $( |
for i in "${files[@]}" ; do |
local skip= |
for j in "${dirs[@]}" ; do |
if [[ $i == $j ]]; then |
skip=1 |
break |
fi |
done |
[[ -n $skip ]] || printf "%s\n" "$i" |
done |
)) |
COMPREPLY=( ${COMPREPLY[@]:-} $( |
for i in "${dirs[@]}" ; do |
printf "%s/\n" "$i" |
done |
)) |
fi |
} |
if [[ $( type -t compopt) = "builtin" ]]; then |
complete -F _adb adb |
else |
complete -o nospace -F _adb adb |
fi |
Cross Reference: /sdk/bash_completion/adb.bash
以下のようなコンソール出力になります.
「adb」と文字を入力したあとのひとつスペースに注意しながらの
~ $ adb <TAB> |
-d devices help pull shell usb |
-e disconnect install push start-server version |
-p emu jdwp reboot status-window |
-s forward kill-server reboot-bootloader sync |
bugreport get-serialno logcat remount tcpip |
connect get-state lolcat root uninstall |
~ $ adb -<TAB> |
-d -e -p -s |
~ $ adb -s |
01f9739f4fd1471c 192.168.10.101:5555 |
~ $ adb push a.apk /<TAB> |
/acct/ /dev/ /init.environ.rc /mnt/ /sdcard/ /ueventd.rc |
/cache/ /etc/ /init.mako.rc /persist/ /seapp_contexts /vendor/ |
/charger /file_contexts /init.mako.usb.rc /proc/ /sepolicy |
/config/ /firmware/ /init.rc /property_contexts /storage/ |
/d/ /fstab.mako /init.superuser.rc /res/ /sys/ |
/data/ /init /init.trace.rc /root/ /system/ |
/default.prop /init.cm.rc /init.usb.rc /sbin/ /ueventd.mako.rc |
~ $ adb uninstall <TAB> |
Display all 217 possibilities? (y or n) |
android com.facebook.orca |
com.adamrocker.android.input.simeji com.facebook.pages.app |
com.adobe.flashplayer com.farproc.wifi.analyzer |
com.adobe.reader com.gmail.jp.raziko.radiko |
com.alensw.PicFolder com.google.android.apps.adm |
com.amazon.mp3 com.google.android.apps.ads.publisher |
com.americanexpress.android.acctsvcs.japan com.google.android.apps.authenticator2 |
com.andrew.apollo com.google.android.apps.books |
com.android.apps.tag com.google.android.apps.chromecast.app |
特に, ローカル/リモートディレクトリの補完が快適です.
そんな bash の 補完(completion)なスクリプトは他にもいろいろ見つかります.
android-completion/android at master · mbrubeck/android-completion · GitHub
metasystem/modules/android/shell/bash-completion.sh at master · garethstockwell/metasystem · GitHub
adb - romannurik-code - Roman's miscellaneous sample code - Google Project Hosting
お試しあれ.
脳みそに刻む意味で手間をかけてキャプる.
SDKを最新にして, そのフレームを使って作るとほとんどクリアーできると思う.
非Androidな人が紙で画面構成を作るとこうなっちゃうのだろうけど, 実際, 一般アプリユーザーはどう思うのだろうかー.
以下, Google発ソース動画.