2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AndroidでOpenAi APIを呼び出す

Last updated at Posted at 2023-10-22

はじめに

近頃のトレンドのChatGpt。Androidの環境でOpenAi APIを叩いてみた。
既に同じような記事は存在するが、AnroidのJavaっていう点では少ないので記載。

準備

まずはAPIを呼び出せるように設定を行います。
https://platform.openai.com/overview
上記URLでアカウントを作成し、ログインしましょう。APIを利用するには、別途料金が必要になってきます。

アプリ概要

テキストに入力した内容をボタンで送信。バックグランドでOpenAPIに要求し、アウトプット用テキストに出力する簡単な仕組み。

実装

依存関係

必要な依存関係をビルドシステム(gradle)に記載

依存関係を確認する際には下記サイトを参照。OpenAi API Javaの一覧が記載されている。
https://mvnrepository.com/artifact/com.theokanning.openai-gpt3-java
初心者のために行っておくが、依存関係でOpenAi APIを取り込まないとクラスなども呼べない。

build.graled
dependencies {

    // https://mvnrepository.com/artifact/com.theokanning.openai-gpt3-java/api
    implementation group: 'com.theokanning.openai-gpt3-java', name: 'api', version: '0.2.0'
    // https://mvnrepository.com/artifact/com.theokanning.openai-gpt3-java/service
    implementation group: 'com.theokanning.openai-gpt3-java', name: 'service', version: '0.14.0'
    // https://mvnrepository.com/artifact/com.theokanning.openai-gpt3-java/client
    implementation group: 'com.theokanning.openai-gpt3-java', name: 'client', version: '0.16.0'
}

ソースコード

MainActivity.java
public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
    private EditText mInputText, mOutputText;
    private Button mRequestBtn;
    private ChatGptService mChatGptService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mInputText = findViewById(R.id.inputText);
        mOutputText = findViewById(R.id.outputText);
        mRequestBtn = findViewById(R.id.requestBtn);

        mChatGptService = new ChatGptService(getApplicationContext());
    }

    @Override
    protected void onResume() {
        super.onResume();

        // 回答内容を要求
        mRequestBtn.setOnClickListener(view -> {
            Log.i(TAG, "onClick()");
            String inputText = mInputText.getText().toString();
            mChatGptService.requestChatGpt(inputText, new ChatGptService.Callback() {
                @Override
                public void onRequest() {
                    mRequestBtn.setEnabled(false);
                }

                @Override
                public void onFinishedRequest(String result) {
                    mOutputText.setText(result);
                    mRequestBtn.setEnabled(true);
                }
            });
        });
    }
}

ChatGpServiceクラス

OpenAi APIをバックランドで叩くクラスです。
バックランドとのやり取りには、handlerThreadを作成して、 Handlerでやり取りを行う。ここに関しては本題から外れるので詳しく話しません。OpenAi AIPを叩くには、ネットワーク通信が必要になってきます。バックグランドでの実行を行うようにしましょう。
それに伴いPermissionの設定も必要になってきます。

AndroidManifest.xml
 <uses-permission android:name="android.permission.INTERNET" />
ChatGptService.java
/**
 * バックグランドでOpenAi APIをコールするクラス
 */
public class ChatGptService {
    private static final String TAG = ChatGptService.class.getSimpleName();
    private final Object mObject = new Object();
    private HandlerThread mHandlerThread;
    private ChatGptHandler mChatGptHandler;
    private Callback mCallback;
    // TODO:key-codeの保存方法は変更する
    private static final String key_token = "自分のtoken";
    private OpenAiService mOpenAiService;
    private SharedPreferences mPhrasingSettingPrefs;
    private static final int DELAY_TIME = 60;
    private static final String DEFAULT_MODE ="通常通り";


    public ChatGptService(Context context) {
        // スレッドはrequestChatGptの時に作成

        mOpenAiService = new OpenAiService(key_token, Duration.ofSeconds(DELAY_TIME));
    }

    /**
     * リクエストを要求する
     * @param inputText
     */
    public void requestChatGpt(String inputText, Callback callback) {
        if (mCallback == null) {
            mCallback = callback;
        }

        mCallback.onRequest();

        if (mHandlerThread == null) {
            mHandlerThread = new HandlerThread("ChatGptService");
            mHandlerThread.start();
        }

        mChatGptHandler = new ChatGptHandler(mHandlerThread.getLooper() ,inputText, mPhrasingSettingPrefs.getString(PHRASING_MODE, DEFAULT_MODE));

        //バックグランドにMessage送信
        Message message = new Message();
        message.what = ChatGptHandler.REQUEST_MSG;
        mChatGptHandler.sendMessage(message);
    }

    class ChatGptHandler extends Handler {
        private static final int REQUEST_MSG = 0;
        private String mInputText;
        private String mContent;
        private ChatMessage mChatMessage;
        private List<ChatMessage> mMessages;
        private ChatMessage mUserMessage;

        ChatGptHandler(Looper looper, String inputText) {
            super(looper);
            mInputText = inputText;
            // TODO
            mContent = "";
            mMessages = new ArrayList<>();

            mChatMessage = new ChatMessage("system", mContent);
            mMessages.add(mChatMessage);

            mUserMessage = new  ChatMessage("user", mInputText);
            mMessages.add(mUserMessage);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case REQUEST_MSG:
                    Log.i(TAG, "handleMessage:" + "REQUEST_MSG");
                    requestChatGpt();
                    break;
                default:
                    Log.w(TAG, "Nothing message");
                    break;
            }
        }

        /**
         * inputされたchat内容を返答する
         */
        private void requestChatGpt() {
            ChatCompletionRequest chatCompletionRequest =
                    ChatCompletionRequest.builder()
                            .model("gpt-3.5-turbo-0613")
                            .messages(mMessages)
                            .maxTokens(2048)
                            .build();
            ChatCompletionResult chatCompletionResult = mOpenAiService.createChatCompletion(chatCompletionRequest);
            String resultText = chatCompletionResult.getChoices().get(0).getMessage().getContent();
            Log.i(TAG, "result:" + resultText);
            notifyFinishedRequest(mCallback, resultText);
        }

        private void notifyFinishedRequest(ChatGptService.Callback callback, String result) {
            final Handler handler = new Handler(Looper.getMainLooper());
            final ChatGptService.Callback callbackImpl = callback;
            if (callbackImpl == null) {
                Log.w(TAG, "Callback is null");
                return;
            }
            synchronized (mObject) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callbackImpl.onFinishedRequest(result);
                    }
                });
            }
        }
    }



    interface Callback {
        /**
         * リクエストが始まった時のコールバック
         */
        void onRequest();

        /**
         * リクエスト結果を返すコールバック
         * @param result 結果内容
         */
        void onFinishedRequest(String result);
    }
}

ActivtiyのLayout

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/phrasingSettingText"
            android:layout_width="0.0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.8"/>

        <Button
            android:id="@+id/phrasingSettingsBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/phrasingChange"/>

    </LinearLayout>

    <EditText
        android:id="@+id/inputText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/requestBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="30dp"
        android:text="@string/request" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <EditText
            android:id="@+id/outputText"
            android:layout_width="match_parent"
            android:layout_height="200dp"/>
    </ScrollView>
</LinearLayout>

まとめ

簡単なOpenAI APIを利用する簡易アプリを作成してみました
最近では、AIと英会話をするようなアプリも作成されており、そのようなアプリもOpenAI APIを利用してるのでしょうかね。次回はそのようなアプリの作成をしてみたいと思います。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?