[GO] Premiers pas avec Android!

introduction

Bonjour, fin d'école cette semaine complète, passer les vacances d'été sans contenu de la semaine prochaine c'est mon. Cette fois, j'aimerais utiliser l'application Android pour la communication HTTP avec l'API Django créée dans Article précédent.

Au fait, la qualité n'est pas si élevée car elle a été mise en œuvre en un jour même si elle a été couverte. (Bien que cela prenne environ 16 heures)

Basiques!

C'est là que j'ai eu le plus de problèmes. Je n'ai pas du tout compris la configuration d'exécution, je ne pouvais pas du tout voir l'image dans son ensemble, comment implémenter le front-end? etc. Tout d'abord, si vous ne pouvez pas saisir le tableau d'ensemble, vous ne savez pas par quoi commencer. Par conséquent, tout d'abord, il est nécessaire de comprendre de quel type de structure il est constitué et ce qu'il peut faire.

De plus, récemment, il y a Kotlin et React Native lors du développement d'applications Android, mais cette fois, nous utiliserons Java qui est Owacon Legacy Language.

Choses importantes

Voici quelques actions importantes à effectuer lors de la création d'une application Android. À tout le moins, je veux que vous compreniez cette configuration, alors pardonnez-moi.

--Activité

Si un amoureux du Web le compare à MVC, cette fois, le modèle est sur le serveur Django, et le code java qui compose Android est le contrôleur, et la partie écrite en XML est la vue.

Configuration d'exécution

Cette fois, la partie que je ne comprenais pas le plus sur la communication HTTP est ici. Quelle classe est exécutée dans Android en premier lieu? J'avais des ennuis parce que c'était comme ça. En tant que prémisse majeure ** Lorsque vous exécutez Android, la classe spécifiée dans le manifeste sera exécutée. ** ** En d'autres termes, même si vous définissez d'autres classes, vous devrez éventuellement les agréger ici. (Je n'ai pas compris ça)

L'image ressemblera à la figure ci-dessous. image.png

C'est un chiffre sale, mais comme la seule classe qui est finalement exécutée est la classe principale, même s'il y a beaucoup d'autres classes, le traitement que vous voulez faire est exécuté uniquement dans la classe principale. Vous pouvez faire un détour, alors passons à la principale! !! !!

Écrivons en fait le code.

Les classes utilisées cette fois sont les suivantes.

classe Utilisation
ExSample.java Classe d'exécution principale
AsyncHttpRequestGet.java Obtenez toutes les données
AsyncHttpRequestPost.java Envoyer une notification de fin de livraison
ListAndView.java Classe pour définir la vue de liste dans une disposition linéaire

Cette fois, je vais créer une application Android en utilisant ces quatre.

créer!

Écrivons.

Points dans l'exemple

--Construisez un programme en héritant de la classe AppCompatActivity. --Exécutez avec la méthode onCreate.

ExSample.java


package es.exsample;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

public class ExSample extends AppCompatActivity {

    //Afficher la classe
    private static final String TAG = "ExSample";
    //Variables pour référencer le contexte dans différentes classes
    private static ExSample context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_item);
        context = this;
        //Courir
        AsyncHttpRequestGet task = new AsyncHttpRequestGet(context);
        task.execute("http://localhost:8000/get_shop");
        Log.d(TAG, "created");
    }

    //Fonctions d'utilisation du contexte dans d'autres classes
    public static ExSample getInstance(){
        return context;
    }
}

Point d'AsyncHttpRequestGet

--ExSample n'exécute que ceci, donc le montant dans cette classe est plutôt grand.

AsyncHttpRequestGet.java



package es.exsample;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;

public class AsyncHttpRequestGet extends AsyncTask<String, Void, String> {
    //Balise enregistreur
    private static final String TAG = "AsyncHttpRequestGet";

    //Vue exploitée depuis le fil de l'interface utilisateur
    private TextView titleView;
    private TextView beforUserContent;
    private TextView doneUserContent;
    private ListView beforUser;
    private ListView doneUser;
    public static Map<String, String> data;
    public static List<Map<String, String>> dataList;
    public static ListView listView;
    public static ListAndView adapter;

    //Constructeur d'ensemble, vue
    public AsyncHttpRequestGet(Context context) {
        super();
        ExSample sample = (ExSample) context;
        titleView = (TextView)sample.findViewById(R.id.title);
        beforUserContent = (TextView)sample.findViewById(R.id.befor);
        doneUserContent = (TextView)sample.findViewById(R.id.done);
        beforUser = (ListView)sample.findViewById(R.id.beforUser);
        doneUser = (ListView)sample.findViewById(R.id.doneUser);

        listView = (ListView)sample.findViewById(R.id.beforUser);
    }

    //Traitez les demandes et les réponses ici
    @Override
    protected String doInBackground(String... params) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        HttpsURLConnection connection = null;

        try {
            //L'URL est définie, la valeur d'en-tête est gérée ici et le jeton peut être obtenu lors de la connexion.
            URL url = new URL(params[0]);
            connection = (HttpsURLConnection)url.openConnection();
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", "Spécifiez la clé obtenue par JWT Django");
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(3000);

            // GET
            connection.setRequestMethod("GET");
            connection.connect();

            //Vérifiez le code de réponse
            int responseCode = connection.getResponseCode();
            if(responseCode != HttpsURLConnection.HTTP_OK) {
                throw new IOException("HTTP responseCode: " + responseCode);
            }

            //Stringification
            inputStream = connection.getInputStream();
            if(inputStream != null) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(connection != null) {
                connection.disconnect();
            }
        }
        return sb.toString();
    }

    //Créez une vue ici
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onPostExecute(String result) {

        List<String> userListOrderDone = new ArrayList<String>();
        List<String> userListBeforOrder = new ArrayList<String>();
        List<String> idList = new ArrayList<String>();

        //Une fonction qui renvoie simplement ceci dans ExSample (je ne sais pas si cela a du sens)
        Context context = ExSample.getInstance().getApplicationContext();
        ArrayAdapter<String> beforUserList = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, userListBeforOrder);
        ArrayAdapter<String> doneUserList = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, userListOrderDone);


        Log.d(TAG, result);
        titleView.setText("Motodeli");
        beforUserContent.setText("Avant la livraison");
        doneUserContent.setText("Livraison terminée");
        beforUser.setAdapter(beforUserList);
        doneUser.setAdapter(doneUserList);


        try{
            //Obtenez toutes les réponses avec JSONArray
            JSONArray all = new JSONArray(result);
            dataList = new ArrayList<Map<String, String>>();
            for(int i = 0; i < all.length(); i++){
                data = new HashMap<String, String>();
                //Vous pouvez obtenir chaque valeur souhaitée
                JSONObject json = all.getJSONObject(i);
                String email = json.getString("user");
                String total = json.getString("total");
                String status = json.getString("status");
                String id = json.getString("id");
                //Juger s'il a été livré ou livré en fonction de la condition de l'utilisateur (une image que de nombreux débutants sont accros à la comparaison de chaînes de caractères Java)
                if(status.equals("true")){
                    data.put("text1", email);
                    data.put("text2", id);
                    dataList.add(data);
                }
                else{
                    userListOrderDone.add(String.format("%s: %s yen", email, total));
                }
            }
        }
        catch (JSONException e){
            System.out.println(e);
        }

        //Entrez la valeur basée sur les données extraites précédemment
        adapter = new ListAndView(
                context,
                dataList,
                R.layout.row,
                new String[] {
                        "text1",
                        "text2",
                    },
                new int[] {
                        android.R.id.text1,
                        android.R.id.text2,
                });
        //Reflété dans la vue de liste
        listView.setAdapter(adapter);
        listView.setTextFilterEnabled(false);
    }
}

Point d'AsyncHttpRequestPost

AsyncHttpRequestPost.java


package es.exsample;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;

public class AsyncHttpRequestPost extends AsyncTask<String, Void, String> {
    private static final String TAG = "AsyncHttpRequestPost";
    private TextView textView;

    public AsyncHttpRequestPost(Context context) {
        super();
    }

    @Override
    protected String doInBackground(String... params) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        HttpsURLConnection connection = null;

        try {
            //Définissez la chaîne URL.
            URL url = new URL(params[0]);
            connection = (HttpsURLConnection)url.openConnection();
            connection.setConnectTimeout(3000); //Timeout 3 secondes
            connection.setReadTimeout(3000);

            // POST
             connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo2LCJ1c2VybmFtZSI6ImIxODA2NDI5QHBsYW5ldC5rYW5hemF3YS1pdC5hYy5qcCIsImV4cCI6MTU5NTIzMTIzNiwiZW1haWwiOiJiMTgwNjQyOUBwbGFuZXQua2FuYXphd2EtaXQuYWMuanAifQ.18LotiLgemUmSXTqmdcjjD3eKLSL1B13N87msbQswoE");
            OutputStream outputStream = connection.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
            writer.write(params[1]);
            writer.close();
            connection.connect();

            //Code de réponse.
            int responseCode = connection.getResponseCode();
            if(responseCode != HttpsURLConnection.HTTP_OK) {
                throw new IOException("HTTP responseCode: " + responseCode);
            }

            //Stringification
            inputStream = connection.getInputStream();
            if(inputStream != null) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(connection != null) {
                connection.disconnect();
            }
        }
        return sb.toString();
    }

}

Points ListAndView

ListAndView.java


package es.exsample;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.content.ContentValues.TAG;

public class ListAndView extends SimpleAdapter {

    private LayoutInflater inflater;
    private List<? extends Map<String, ?>> listData;

    //Classe de conservation des données détenue par chaque ligne
    public class ViewHolder {
        TextView text1;
        TextView text2;
    }

    public ListAndView(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
        this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.listData = data;
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;

        //Recevoir une vue
        View view = convertView;

        if (view == null) {
            view = inflater.inflate(R.layout.row, parent, false);

            holder = new ViewHolder();
            holder.text1 = (TextView) view.findViewById(android.R.id.text1);
            holder.text2 = (TextView) view.findViewById(android.R.id.text2);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        //Définir les données dans le support
        String text1 = ((HashMap<?, ?>) listData.get(position)).get("text1").toString();
        String text2 = ((HashMap<?, ?>) listData.get(position)).get("text2").toString();
        holder.text1.setText(text1);
        holder.text2.setText(text2);

        //Exécuter lorsque vous appuyez sur le bouton
        Button btn = (Button) view.findViewById(R.id.rowbutton);
        btn.setTag(position);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                String id = holder.text2.getText().toString();
                Context context = ExSample.getInstance().getApplicationContext();
                AsyncHttpRequestPost task = new AsyncHttpRequestPost(context);
                String url = "http://localhost:8000/post_shop/" + id;
                task.execute(url, "hi");
                Log.d(TAG, "created");
            }
        });

        return view;
    }

}

XML

image.png

list_item.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    card_view:cardBackgroundColor="#ffffff"
    card_view:cardCornerRadius="7dp"
    card_view:cardElevation="5dp">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="1542dp">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textSize="24sp"
            card_view:layout_constraintBottom_toBottomOf="parent"
            card_view:layout_constraintEnd_toEndOf="parent"
            card_view:layout_constraintHorizontal_bias="0.498"
            card_view:layout_constraintStart_toStartOf="parent"
            card_view:layout_constraintTop_toTopOf="parent"
            card_view:layout_constraintVertical_bias="0.01"
            />

        <TextView
            android:id="@+id/befor"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:text="TextView"
            card_view:layout_constraintTop_toBottomOf="@+id/title"
            tools:layout_editor_absoluteX="189dp"
            />

        <ListView
            android:id="@+id/beforUser"
            android:layout_width="402dp"
            android:layout_height="130dp"
            android:background="#7A7A7A"
            card_view:layout_constraintEnd_toEndOf="parent"
            card_view:layout_constraintStart_toStartOf="parent"
            card_view:layout_constraintTop_toBottomOf="@+id/befor" />



        <TextView
            android:id="@+id/done"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="TextView"
            card_view:layout_constraintTop_toBottomOf="@+id/beforUser"
            tools:layout_editor_absoluteX="189dp" />

        <ListView
            android:id="@+id/doneUser"
            android:layout_width="402dp"
            android:layout_height="364dp"
            android:layout_marginTop="12dp"
            android:background="#777777"
            card_view:layout_constraintEnd_toEndOf="parent"
            card_view:layout_constraintStart_toStartOf="parent"
            card_view:layout_constraintTop_toBottomOf="@+id/done" />

        <TextView
            android:id="@+id/tag"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="60dp"
            android:text="TextView"
            card_view:layout_constraintTop_toBottomOf="@+id/doneUser"
            tools:layout_editor_absoluteX="98dp" />

        <TextView
            android:id="@+id/desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="100dp"
            android:layout_marginTop="60dp"
            android:text="TextView"
            card_view:layout_constraintStart_toEndOf="@+id/tag"
            card_view:layout_constraintTop_toBottomOf="@+id/doneUser" />

    </android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>

row.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="80dp"
        tools:ignore="MissingConstraints">

        <TextView
            android:id="@android:id/text1"
            android:layout_width="278dp"
            android:layout_height="80dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:text="Text1"
            android:textSize="18dp" />

        <TextView
            android:id="@android:id/text2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical|right"
            android:text="Text2"
            android:textSize="18dp" />

        <Button
            android:id="@+id/rowbutton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:text="Livré!" />

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

C'est un peu compliqué, mais j'espère que vous pourrez réellement le copier et l'utiliser!

Modifications du backend Django (après exécution)

--Création d'une fonction pour informer l'administrateur lorsque la livraison est terminée. --Lorsque vous appuyez sur le bouton AsyncHttpRequestPost, le processus passe à ce point de terminaison, vidant le panier de l'utilisateur propriétaire du panier sélectionné et sautant le courrier. (La partie courrier est omise)

shop/views.py


######
###réduction###

#Ajoutez ce qui suit

from rest_framework.decorators import api_view

@api_view(['POST'])
def order_done_post_request(request, pk):
    user_info = UserInfomation.objects.get(id=pk)
    user = User.objects.get(email=user_info)
    if request.method == 'POST':
        cart = Cart.objects.get(cart_id=user_info.cart.cart_id)

        order_done(request, str(cart))
    
        user = user_info
        #La gestion du panier est implémentée en entrant une valeur négative au lieu d'une suppression logique (mystère)
        cart.cart_id = -cart.cart_id
        user.status = None
        cart.save()
        user.save()
        return Response(None) #Vous n'avez rien à retourner

###réduction###

Spécifiez l'ID du panier en spécifiant le type int pk

shop/urls.py



urlpatterns = [
    ###réduction###
    path('post_shop/<int:pk>', views.order_done_post_request,),  #ajouter à
]

Ce qui précède est le contenu que j'ai travaillé dur pour mettre en œuvre un jour après la relance d'Android Studio. Lorsque j'ai essayé d'écrire un article de cette manière, le nombre de phrases est devenu très important, même si de nombreuses parties ont été omises.

Résumé

Il faut une journée pour créer une application aussi simple et la construction de l'environnement est délicate, les ingénieurs sont donc impressionnés à chaque fois. Cette fois, c'était Android, mais j'aimerais bientôt commencer à travailler sur iOS. C'est impossible à moins d'acheter un nouvel ordinateur. C'est un article assez compliqué, donc si vous avez des questions, envoyez-les dans les commentaires ou dans le DM sur Twitter et nous vous répondrons! Après cela, veuillez commenter s'il y a des erreurs ou des omissions!

Bonnes vacances d'été pour tous les étudiants! !! !!

Recommended Posts

Premiers pas avec Android!
1.1 Premiers pas avec Python
Premiers pas avec apache2
Premiers pas avec Python
Premiers pas avec Django 1
Introduction à l'optimisation
Premiers pas avec Numpy
Premiers pas avec Spark
Premiers pas avec Python
Premiers pas avec Pydantic
Premiers pas avec Jython
Premiers pas avec Django 2
Traduire Premiers pas avec TensorFlow
Introduction aux fonctions Python
Introduction à Tkinter 2: Button
Premiers pas avec Go Assembly
Premiers pas avec PKI avec Golang ―― 4
Premiers pas avec Python Django (1)
Premiers pas avec Python Django (4)
Premiers pas avec Python Django (3)
Introduction à Python Django (6)
Premiers pas avec Django avec PyCharm
Premiers pas avec Python Django (5)
Premiers pas avec Python responder v2
Introduction à Git (1) Stockage d'historique
Premiers pas avec Sphinx. Générer docstring avec Sphinx
Premiers pas avec les applications Web Python
Premiers pas avec Python pour les classes PHPer
Premiers pas avec Sparse Matrix avec scipy.sparse
Premiers pas avec Julia pour Pythonista
Premiers pas avec Python Bases de Python
Premiers pas avec Cisco Spark REST-API
Commençant par USD sur Windows
Premiers pas avec les algorithmes génétiques Python
Premiers pas avec Python 3.8 sous Windows
Premiers pas avec Python pour les fonctions PHPer
Premiers pas avec CPU Steal Time
Grails pour commencer
Premiers pas avec python3 # 1 Apprenez les connaissances de base
Premiers pas avec Python Web Scraping Practice
Premiers pas avec Python pour PHPer-Super Basics
Premiers pas avec Python Web Scraping Practice
Premiers pas avec Dynamo de Python boto
Premiers pas avec Lisp pour Pythonista: Supplément
Premiers pas avec Heroku, déploiement de l'application Flask
Premiers pas avec TDD avec Cyber-dojo chez MobPro
Démarrer avec Python avec 100 coups sur le traitement du langage
Django 1.11 a démarré avec Python3.6
Principes de base de MongoDB: Premiers pas avec CRUD avec JAVA
Premiers pas avec le dessin avec matplotlib: écrire des fonctions simples
Premiers pas avec la traduction japonaise du modèle séquentiel Keras
[Français] Premiers pas avec Rust pour les programmeurs Python
Django Getting Started Part 2 avec eclipse Plugin (PyDev)
Démarrez avec MicroPython
Premiers pas avec AWS IoT facilement en Python