重要です。 以下に記載されているものはすべて、専門家にとっての価値を表すものではありませんが、初心者のAndroid開発者にとって有用な例となります。 コードでは、すべてのアクションをコメントしてログに記録しようとしました。
行こう 多くのモバイルアプリケーション(だけでなく)は、クライアントサーバーアーキテクチャを使用しています。 一般的なスキームは理解できると思います。

各要素に注意を払い、次のことに注意してください。
- サーバー-リモートコンピューターで実行される特定のプログラムであり、クライアントアプリケーションとの「通信」機能を実装します(要求を聞き取り、転送されたパラメーターと値を認識し、それらに正しく応答します)。
- クライアント-この場合、サーバーが理解できるリクエストを生成し、受信したレスポンスを読み取ることができるモバイルデバイス上のプログラム。
- インタラクションインターフェイス-両方の当事者による要求/応答の送信/受信の特定の形式と方法。
これらの要素がどのように実装されているかは問題ではなく、それらはすべて存在しています。 プリミティブサーバーとそれを使用するAndroidクライアントを実装しましょう。 例として、人気のあるモバイルインターネットメッセンジャー(Viber、ICQ)を使用し、アプリケーションを「インターネットチャット」と呼びます。
相互作用スキームは次のとおりです。

デバイスAにインストールされたクライアントは、デバイスBにインストールされたクライアントにメッセージを送信します。逆も同様です。 サーバーは、デバイスAとB ... C、D ...などの間のリンクの役割を果たします。 また、クライアントデバイスの1つで削除された場合の回復のために、メッセージの「ドライブ」の役割も果たします。
メッセージを保存するには、サーバーとクライアントデバイスの両方でSQLデータベースを使用します(原則として、インターネットメッセンジャークライアントのすべての作業は、ローカルデータベースとリモートデータベースのメッセージとの継続的な同期になります)。 また、オンラインチャットは、デバイスの起動から開始し、バックグラウンドで作業できます。 相互作用は、HTTP要求とJSON応答を介して発生します。
同期がポート/ソケットを介して発生する場合、一方で論理的には、これによりタスクが簡素化されます(HTTPリクエストを送信して新しいメッセージを周期的に確認する必要はなく、リスニングソケットのステータスを確認するだけです)一方で、アプリケーションのサーバー側の作成が複雑になります。
サーバーを作る
「サーバー」を実装するには、SQLとPHPを使用できるようにするホスティングに登録する必要があります。空のSQLデータベースを作成し、その中にテーブルを作成します。
チャットテーブル。CREATE TABLE `chat` ( `_id` int(11) NOT NULL AUTO_INCREMENT, `author` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `client` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `data` bigint(20) NOT NULL, `text` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`_id`) )
構造は次のとおりです。
- author-メッセージの作成者。
- クライアント-メッセージの受信者。
- データ-サーバーでメッセージを受信した日時。
- テキストはメッセージです。
次の2つのファイルでは、データベースにアクセスするためのデータを含む変数を、「サーバー」の登録時に受け取った独自の変数に変更する必要があります。
$mysql_host = "localhost";
chat.phpファイルは、サーバーフレンドリーなリクエストの構造を実装するAPIです。 APIのリクエストの構造:
- 必須アクション属性-select(サーバーはデータベースのレコードのリストで応答する)、insert(サーバーがデータベースに新しいレコードを追加する)、delete(サーバーがデータベースをクリアする)に等しい
- action = insertの場合、追加のパラメーターを渡す必要があります:author(メッセージの作成者)、client(メッセージの宛先)、text(メッセージ)
- action = selectには追加のパラメータデータが含まれる場合があります。この場合、サーバーの応答にはデータベースからのすべてのメッセージが含まれるのではなく、送信されたものよりも作成時間が遅いメッセージのみが含まれます
例:
- chat.php?action = delete-サーバー上のすべてのエントリを削除します
- chat.php?action = insert&author = Jon&client = Smith&text = Hello-サーバーに新しいエントリを追加します:著者Jon、受信者Smith、コンテンツHello
- chat.php?action = select&data = 151351333-送信された時間の後に受信したすべてのレコードを長い形式で返します
showBD.phpファイルは、ブラウザにデータベースの内容を表示するためのオプションのスクリプトです。 クライアント部
Androidアプリケーションの構造は次のとおりです。

バックグラウンドでは、FoneService.javaが機能し、別のスレッドで、15秒ごとにサーバーにリクエストを送信します。 サーバーの応答に新しいメッセージが含まれている場合、FoneService.javaはそれらをローカルデータベースに書き込み、ListViewを更新する必要があることを示すChatActivity.javaメッセージをメッセージとともに送信します。 ChatActivity.java(その時点で開いている場合)はメッセージを受信し、ローカルデータベースからListViewの内容を更新します。
ChatActivity.javaからの新しいメッセージは、FoneService.javaをバイパスしてすぐにサーバーに送信されます。 同時に、メッセージはローカルデータベースに書き込まれません! そこで、サーバー応答として返された後にのみ表示されます。 私は、インターネットチャットの仕事の重要なニュアンスに関連してこの実装を使用しました-時間によるメッセージの必須のグループ化。 タイムグループを使用しない場合、メッセージシーケンスが中断されます。 クライアントアプリケーションは、物理的にはミリ秒単位で正確に同期することはできず、異なるタイムゾーンで動作することもあるため、サーバー時間を使用するのが最も論理的です。 それで
新しいメッセージを作成して、サーバーにリクエストを送信します。メッセージの作成者の名前、メッセージの受信者の名前、メッセージテキスト。 サーバーの応答の形式でこのレコードを取得すると、送信したものと4番目のパラメーターであるサーバーがメッセージを受信した時間を取得します。
MainActivity.javaに、明確にするために、ローカルデータベースからメッセージを削除する機能を追加しました-これは、アプリケーションのクリーンインストールと同等です(この場合、FoneServiceは、選択されたチャットの
すべてのメッセージを受信するためにサーバーにリクエストを送信します)。 サーバーにあるデータベースからすべてのメッセージを削除する要求を送信することもできます。
アクティビティコード:FoneService.java package by.andreidanilevich.temp_chat; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import org.json.JSONArray; import org.json.JSONObject; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.BitmapFactory; import android.os.IBinder; import android.util.Log; public class FoneService extends Service {
ChatActivity.java package by.andreidanilevich.temp_chat; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import android.annotation.SuppressLint; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; public class ChatActivity extends Activity {
MainActivity.java package by.andreidanilevich.temp_chat; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.Toast; public class MainActivity extends Activity {
AutoRun.java package by.andreidanilevich.temp_chat; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class AutoRun extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
AndroidManifest <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="by.andreidanilevich.temp_chat" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="portrait" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ChatActivity" android:label="@string/app_name" android:screenOrientation="portrait" > </activity> <receiver android:name=".AutoRun" android:enabled="true" android:exported="false" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <service android:name=".FoneService" /> </application> </manifest>
:chat.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#999999" > <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="60dp" android:scrollbars="none" android:stackFromBottom="true" android:transcriptMode="alwaysScroll" > </ListView> <LinearLayout android:layout_width="match_parent" android:layout_height="60dp" android:layout_alignParentBottom="true" android:background="#ffffff" > <EditText android:id="@+id/et" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="top" android:layout_weight="1" android:ems="10" > </EditText> <Button android:id="@+id/bt" android:layout_width="50dp" android:layout_height="wrap_content" android:layout_gravity="top" android:onClick="send" android:text=">" /> </LinearLayout> </RelativeLayout>
main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="${relativePackage}.${activityClass}" > <Spinner android:id="@+id/spinner_author" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Spinner android:id="@+id/spinner_client" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/open_chat_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="open_chat" /> <Button android:id="@+id/open_chat_reverce_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="open_chat_reverce" /> <Button android:id="@+id/delete_server_chat" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:onClick="delete_server_chats" android:text=" !" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="delete_local_chats" android:text=" !" /> </LinearLayout>
list.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#999999" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" > <TextView android:id="@+id/author" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:textColor="#c6c6c6" android:textSize="12sp" /> <TextView android:id="@+id/client" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:textColor="#c6c6c6" android:textSize="12sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" > <TextView android:id="@+id/list_author" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:textColor="#0000ff" android:textSize="14sp" android:textStyle="bold" /> <TextView android:id="@+id/list_client" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:textColor="#ffff00" android:textSize="14sp" android:textStyle="bold" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" > <TextView android:id="@+id/list_author_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="right" android:textColor="#c6c6c6" android:textSize="12sp" /> <TextView android:id="@+id/list_client_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="right" android:textColor="#c6c6c6" android:textSize="12sp" /> </LinearLayout> </LinearLayout>
(+ apk):github.com/andreidanilevich/temp_chatPS:1.
apk , «»
l29340eb.bget.ru/showBD.php .
2. , , . . .
3. - — . — , — . .