Androidでのプログラミング-なぜそのような困難なのですか?

エントリー


私は長い間プログラマーではなく、管理者です。 ただし、ログ分析ユーティリティを迅速に作成し、自動化することが必要になる場合があります。検索日にインターネット上で類似するものが見つからない場合は、それを行います。



アンドロイドでは、私のdigりはすぐに2つの事実によって引き起こされました-グループ間のメロディーの欠如(まあ、なぜ、ソニア以外に誰もこの明らかに必要な機能を考えなかったのはなぜですか?)そしてコンタクトと一緒にメロディーを蓄積することができないこと。 当時のスマートシステムの標準だったSymbianでは、最後の機能がありました。



この検索で​​は、2番目のポイントでは何も得られず、最初のポイントではほとんど何も得られませんでした。 これらはandroid 1.5からandroid 1.6への厳しい移行時間であり、地平線上のどこかでAndroid 2.0が登場しました。



いや、いや、いや-私は書く、それは鍋を燃やす神ではありません。 Bacupaから、コンタクトにインストールされたメロディーのよりシンプルなものから始めました。



その結果、プログラムは最も簡単な機能で生まれました-連絡先名=設定通信を取得し、このデータを復元します(市場ではRingtone Keeperという名前で見つけることができます)が、その過程でどのようなレーキがあったかを説明します。



Android 1.6


Google自身はわざわ​​ざ1.5をしつこく勧めたので、私は1.6のすぐ下に書くことにしました。 まあ、いや、いや。 ネット上のドキュメントでは、同じコメントの同じ例がサイト間をさまよう。 developer.android.comの Google自体に 、フィールドと機能の例なく、非常に禁欲的な説明があります。 主なリソースはstackoverflow.com/questionsで、質問への回答のロジックを見ることができます。 私はダミーのために数冊の本を読み、走り去った。 プログラムが生まれ、熊手が登っています。



たとえば、サウンドのすべてのデータはMediaStoreのAndroidにあります。 しかし、それらはインデックステーブルの形で存在し、そこからファイル名を引き出します(そして、同じファイルがMediaStoreで他のインデックスを持つ可能性が高いシステムを再インストールした後、ファイル名が必要です)。



連絡先と同じ歌について。 しかし、少なくとも彼らには例があり、私は試行錯誤によって音で戦争全体を模索しなければなりませんでした。



連絡先の通話設定はさらに独創的です。 繰り返しますが、ファイル名の変換(MediaStoreのインデックス)を実行する必要があります。 しかし、これは十分ではありません! このインデックスをメロディーとして連絡先に割り当てると、連絡先のメロディーが削除されます。 それでも、MediaStoreにあるファイルはそこに登録する必要があり(withAppendedIdメソッド)、登録中に受け取ったUriのみを連絡先に押し込むことができます。



それがとても複雑な理由です。 それとも何か見つけられなかったのですか?



Android 2.0


プログラムは機能しましたが、Android 2.0にアップグレードするときが来ました。 そして、Googleではすべてがいつも通りです。 彼は、連絡先を操作するためにSDKを変更し、同時に2回起きないように、古いSDKを保持しましたが、読み取り専用モードにしました。 つまり、連絡先データの読み取りモードは機能し、古いモードは機能します。

2つのコード例:



SDK 1.6

String[] selectCols = { People._ID, People.NAME, People.CUSTOM_RINGTONE }; if ((ContactName == null) || (ContactName.length() < 1)) { return DATA_NOT_FOUND; } //     ContentResolver localContentResolver = this.getContentResolver(); Cursor cur = localContentResolver.query( Uri.withAppendedPath(People.CONTENT_FILTER_URI, Uri.encode(ContactName)), selectCols, null, null, null); if (cur.moveToFirst()) { int cID = cur.getInt(cur.getColumnIndex(People._ID)); return cID; } return DATA_NOT_FOUND;
      
      







SDK 2.0

 tring[] selectCols = { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.CUSTOM_RINGTONE }; if ((ContactName == null) || (ContactName.length() < 1)) { return DATA_NOT_FOUND; } //     ContentResolver localContentResolver = this.getContentResolver(); Cursor cur = localContentResolver.query( Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode(ContactName)), selectCols, null, null, null); if (cur.moveToFirst()) { int indID = cur.getColumnIndex(ContactsContract.Contacts._ID); return cur.getInt(indID); } return DATA_NOT_FOUND; }
      
      







つまり、単にPeopleをContactsContract.Contactsに、.NAMEを.DISPLAY_NAMEに変更できます。 変更する必要さえありません-古い方法で読むのはうまくいきます!



しかし、問題は記録にあります。



古いSDK:

  Uri contactUri = ContentUris.withAppendedId(People.CONTENT_URI, cID); ContentValues value = new ContentValues(); value.put(People.Phones.TYPE, People.TYPE_MOBILE); value.put(People.NUMBER, "+7 (777) 777-77-77"); ContentResolver localContentResolver = this.getContentResolver(); int updRow = localContentResolver.update(contactUri, value, null, null); localContentResolver.notifyChange(People.CONTENT_URI, null); return ((updRow > 0));
      
      







このコードは、単一のエラーではなく、収集、起動、動作中です-/ dev / nullまたは誰も読み取っていない古いデータベースにのみ書き込みます。



ここでは、PeopleをContactsContract.Contactsに置き換える必要がありますが、これは一切必要ありません。



思われるかもしれませんが、同義語を作成し、古いルールの古いコードが実際のベースに書き込むようにします。 さて、プラットフォームが1.6よりも高い場合は、Peopleを間違えます。 彼らはどちらもしませんでした。 問題は-なぜそのような困難なのか?



市場と人々


このおよその段階で、私はプログラムを市場に出すことにしました(私の友人の間では、それはバタンと行きました、私はそれをさせようと思いました)。 そして、大量使用に伴い、次のレーキが上昇しました。



連絡先検索は、システムによって指定された形式で名前を返します。 支払い時に連絡先「姓、名」を表示する形式があった場合、連絡先は「Ivan Vasya」として記録されます(DISPLAY_NAMEから返されるため)。 ただし、システムを再インストールした後の形式は「名、姓」です。 ユーザーが[復元]をクリックすると、プログラムは連絡先 "Ivan Vasya"の検索を正直に開始しますが、システムは "Ivan Vasya"と "Vasya Ivanov"が異なる人であると考えているため、検索できません。 システムにこれをどのように説明できますか?私はそれを思い付かず、私のプログラムで連絡先とその検索を解析しました。 速度が大幅に低下し、200の連絡先への通話が20〜30秒間確立されました。 30秒間ハングするプログラムがバグであることは明らかです。 記号「I'm working ...」とアクティビティインジケータを備えた記号が必要です。 Googleの栄光、Androidはそれを提供します! それから、Androidの並列処理について多くのことを学びましたが、このすべてにおいて、少なくともいくつかのロジックをトレースできるため、何も言いません。 これは熊手ではなく、これは肉屋です、彼はそう思います。



さらに、ユーザーはデフォルトの通話とSMSサウンドの保存と復元を要求し始めました。 繰り返しますが、レーキは最も簡単で明白なソリューションです。

Settings.System.DEFAULT_RINGTONE_URIは、外部(SDカード付き)着信音がインストールされている場合、「/システム/オーディオ/着信音」という形式の結果を返します。 同時に、MediaStoreとRingtoneManagerはどちらも、どのようなファイルであるかを推測することをきっぱりと拒否します。 私は習慣的にアンチファサードを登り、RingtoneManager.getActualDefaultRingtoneUri(これ、RingtoneManager.TYPE_RINGTONE)を使用し、その戻り値をファイル名に変換する必要がありました。



また、通話またはSMSをインストールするときの同じボタンアコーディオン-MediaStoreに追加するまで、Android 2および3にはインストールされません。 android 4では、ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI、ringID)なしですべてが機能するため、このバグは最終的に修正されたようです。



別のよくあるユーザーの質問は、降圧型および降圧型ファイル名を配置する場所を選択する機能でした(現在、これはプログラムによってハードコーディングされています)。 それから、Androidには標準のファイル/ディレクトリ選択ダイアログがないことを発見しました(ファンファーレ、Win3.11はnervousでひっくり返ります)。 必要-座って書いてください。 この時点で、私は「十分な倒錯」と言い、可用性が不足しているために、私はそのようなことを書くのが面倒で、ファイルマネージャーを使って好きなところにお金を移すことをみんなに答え始めました。



しかし、なぜ、なぜですか?



ご質問


その結果、プログラムは作成され、動作しますが、質問があります-なぜすべてがそんなに複雑なのですか? Googleでは、Android APIはいくつかの異なる競合チームを作成しますか? 以前のシステムの経験が考慮されないのはなぜですか、なぜ肛門を通して明白な機能が自生するか、まったく存在しないのですか?



誰がこれをすべて発明したのですか?

それともそれほど悪くないのですが、答えが見つかりませんでしたか?



All Articles