Partage
  • Partager sur Facebook
  • Partager sur Twitter

android c++ ifstream

    29 septembre 2022 à 21:23:57

    Bonjour, je viens vers vous après quelques jours de recherches par rapport à la création d'un fichier txt et à la lecture de celui-ci.

    Il faut utiliser du code natif si je comprends bien mais je n'ai aucunes connaissances.

    Auriez vous un tuto sous la manche ou un truc du genre svp ?

    (malheureusement les ifstreams ne fonctionnement pas)

    Je code en c++ avec la SFML.

    j'ai trouvé ce code sur internet:

    #include <vector>
    #include <string>
    #include <fstream>
    #include <android/asset_manager.h>
    
    class asset_streambuf: public std::streambuf
    {
        public:
            asset_streambuf(AAssetManager* manager, const std::string& filename) : manager(manager)
            {
                asset = AAssetManager_open(manager, filename.c_str(), AASSET_MODE_STREAMING);
                buffer.resize(1024);
    
                setg(0, 0, 0);
                setp(&buffer.front(), &buffer.front() + buffer.size());
            }
    
            virtual ~asset_streambuf()
            {
                sync();
                AAsset_close(asset);
            }
    
            std::streambuf::int_type underflow() override
            {
                auto bufferPtr = &buffer.front();
                auto counter = AAsset_read(asset, bufferPtr, buffer.size());
    
                if(counter == 0)
                    return traits_type::eof();
                if(counter < 0) //error, what to do now?
                    return traits_type::eof();
    
                setg(bufferPtr, bufferPtr, bufferPtr + counter);
    
                return traits_type::to_int_type(*gptr());
            }
    
            std::streambuf::int_type overflow(std::streambuf::int_type value) override
            {
                return traits_type::eof();
            };
    
            int sync() override
            {
                std::streambuf::int_type result = overflow(traits_type::eof());
    
                return traits_type::eq_int_type(result, traits_type::eof()) ? -1 : 0;
            }
    
        private:
            AAssetManager* manager;
            AAsset* asset;
            std::vector<char> buffer;
    };
    
    
    class assetistream: public std::istream
    {
        public:
            assetistream(AAssetManager* manager, const std::string& file) : std::istream(new asset_streambuf(manager, file))
            {
            }
    
            assetistream(const std::string& file) : std::istream(new asset_streambuf(manager, file))
            {
            }
    
            virtual ~assetistream()
            {
                delete rdbuf();
            }
    
            static void setAssetManager(AAssetManager* m)
            {
                manager = m;
            }
    
        private:
            static AAssetManager* manager;
    };
    class test_asset
    {
    private:
        
    public:
        test_asset();
        ~test_asset();
        std::string getfile();
    };
    
    void foo(AAssetManager* manager)
    {
        assetistream::setAssetManager(manager);
    
        assetistream as("data.txt");
        std::string s;
    
        std::getline(as, s);
    }

    mais je ne sais pas comment l'utiliser.

    Merci pour votre aide.

    -
    Edité par kkabu 30 septembre 2022 à 20:15:13

    • Partager sur Facebook
    • Partager sur Twitter
      4 octobre 2022 à 13:02:12

      le fstream devrait fonctionner à partir où l'application demande les droits d'accès au stockage, et a priori, il semble préférable d'indiquer un chemin absolu pour le fichier

      https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only 

      • Partager sur Facebook
      • Partager sur Twitter
        10 octobre 2022 à 21:37:56

        Merci beaucoup pour ton aide, j'ai tenté de m'inspirer de ton exemple mais je n'y arrive pas, voici mon code

        void write_file(const char* filename)
                {
                    std::vector<int>v{1,2,3};
        
                    ANativeActivity* nativeActivity  = sf::getNativeActivity();
        
                    const char* internalPath = nativeActivity->internalDataPath;
        
                    std::string dataPath(internalPath); 
        
                    std::string filename_s(filename);
        
                    struct stat sb;
                    int32_t res = stat(dataPath.c_str(), &sb);
                    
                    if(FILE* appConfigFile = std::fopen(filename_s.c_str(), "w"))
                    {
                        res = std::fwrite(v.data(), sizeof(int), v.size(), appConfigFile);
                        std::fclose(appConfigFile);
                    }
                }

        Quel est le problème ?

        J'utilise la SFML c'est pour ça que j'ai fais le sf::getNativeActivity

        Encore merci pour le coup de main !

        -
        Edité par kkabu 10 octobre 2022 à 21:38:56

        • Partager sur Facebook
        • Partager sur Twitter
          11 octobre 2022 à 11:11:00

          quel est le message d'erreur?
          • Partager sur Facebook
          • Partager sur Twitter
            11 octobre 2022 à 18:04:40

            Je n'ais pas de message d'erreur, mais ça ne fonctionne pas.

            Par contre ça ne me demande pas d'autorisation malgré le fais que j'ai modifié le fichier AndroidManifest.xml

            <?xml version="1.0" encoding="utf-8"?>
            
            <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                package="org.sfmldev.android"
                android:versionCode="1"
                android:versionName="1.0" >
            
                <uses-feature android:glEsVersion="0x00010001" />
            
                <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
                </uses-permission>
                <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"> 
                </uses-permission>
            
                <application android:label="@string/app_name"
                    android:icon="@drawable/sfml_logo"
                    android:hasCode="false"
                    android:allowBackup="true"
                    android:extractNativeLibs="true">
            
                    <activity android:name="android.app.NativeActivity"
                        android:label="@string/app_name"
                        android:icon="@drawable/sfml_logo"
            			android:requestLegacyExternalStorage="true"
            			android:screenOrientation="landscape" 
                        android:configChanges="keyboardHidden|orientation|screenSize">
            
                        <meta-data android:name="android.app.lib_name" android:value="sfml-activity" />
                        <meta-data android:name="sfml.app.lib_name" android:value="sfml-example" />
            
                        <intent-filter>
                            <action android:name="android.intent.action.MAIN" />
                            <category android:name="android.intent.category.LAUNCHER" />
                        </intent-filter>
                    </activity>
                </application>
            </manifest>
            

            C'est correct ?

            -
            Edité par kkabu 11 octobre 2022 à 18:06:35

            • Partager sur Facebook
            • Partager sur Twitter
              14 octobre 2022 à 17:46:36

              Salut, je reviens ici car j'ai presque trouvé la solution mais il me manque un petit truc, comment faire fonctionner ce code et est-il correct ?

              ANativeActivity *activity = sf::getNativeActivity();
               JNIEnv* env = activity->env; 
              jclass cls_Env = (*env)->FindClass(env, "com/psdk/NativeActivity"); 
              jmethodID mid = (*env)->GetMethodID(env, cls_Env, "tata", "()Ljava/lang/String;"); 
              jobject obj_File = (*env)->CallObjectMethod(env, activity->clazz, mid, NULL);
              j'ai ceci à la compilation:
              error: member reference type 'JNIEnv' (aka '_JNIEnv') is not a pointer; did you mean to use '.'? 
              jclass cls_Env = (*env)->FindClass(env, "com/psdk/NativeActivity"); error: too many arguments to function call, expected single argument 'name', 
              have 2 arguments 
              jclass cls_Env = (*env)->FindClass(env, "com/psdk/NativeActivity"); 
              error: member reference type 'JNIEnv' (aka '_JNIEnv') is not a pointer; did you mean to use '.'? 
              jmethodID mid = (*env)->GetMethodID(env, cls_Env, "tata", "()Ljava/lang/String;");

              -
              Edité par kkabu 19 octobre 2022 à 19:23:31

              • Partager sur Facebook
              • Partager sur Twitter
                19 octobre 2022 à 20:38:27

                Salut, j'ai réédité mon message mais open Classroom ne met pas à jour le sujet.
                • Partager sur Facebook
                • Partager sur Twitter
                  20 octobre 2022 à 11:19:40

                  les messages sont parlant, Ils te suggèrent d'utiliser le point au lieu de la flèche (*env)->FindClass(..) ==> (*env).FindClass(...) et cette fonction n'attend qu'un paramètre "name"
                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 octobre 2022 à 18:24:29

                    J'ai testé ceci mais mon app crash directement, voici mon code complet:

                    Mon fichier s'appelle MainActivity.java

                    package com.psdk;
                    
                    import java.io.FileWriter;
                    import android.os.Bundle;
                    
                    import android.Manifest.permission;
                    import android.content.Intent;
                    
                    import android.Manifest;
                    import android.app.Activity;
                    import android.content.SharedPreferences;
                    import android.content.pm.PackageManager;
                    import android.util.Log;
                    import androidx.core.app.ActivityCompat;
                    import androidx.core.content.ContextCompat;
                    import java.io.File;
                    import java.io.FileOutputStream;
                    import java.io.IOException;
                    import java.io.InputStream;
                    import java.io.OutputStream;
                    import java.util.ArrayList;
                    import java.util.List;
                    
                    public class MainActivity extends android.app.Activity {
                    	static {
                    		System.loadLibrary("jni-lib");
                    	}
                    	
                    	private static final int ACCEPT_PERMISSIONS_REQUESTCODE = 8007;
                    	
                        @Override
                        public void onCreate(Bundle savedInstanceState) {
                    		super.onCreate(savedInstanceState);
                            tata();
                        }
                    	
                    	public String tata(){
                    		String string1 = "Hey you";
                    		
                    		if (requestPermissionsIfNeeded(this, ACCEPT_PERMISSIONS_REQUESTCODE)) {
                    			FileOutputStream fos ;
                    
                    			try {
                    				fos = new FileOutputStream("filename.txt", true);
                    
                    				FileWriter fWriter;
                    
                    				try {
                    					fWriter = new FileWriter(fos.getFD());
                    					fWriter.write("hi");
                    					fWriter.close();
                    				} catch (Exception e) {
                    					e.printStackTrace();
                    				} finally {
                    					fos.getFD().sync();
                    					fos.close();
                    				}
                    			} catch (Exception e) {
                    				e.printStackTrace();
                    			}
                    		}
                    		return "tata";
                    	}
                    	
                    	public static boolean requestPermissionsIfNeeded(Activity activity, int requestCode) {
                    		return requestPermissionsNeeded(activity, new String[] { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, requestCode);
                    	}
                    	
                    	private static boolean requestPermissionsNeeded(Activity activity, String[] permissions, int requestCode) {
                    		final List<String> notGrantedPermissions = new ArrayList<>();
                    		for (final String permission : permissions) {
                    			if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
                    				notGrantedPermissions.add(permission);
                    			}
                    		}
                    		if (!notGrantedPermissions.isEmpty()) {
                    			ActivityCompat.requestPermissions(activity, notGrantedPermissions.toArray(new String[0]), requestCode);
                    			return false;
                    		}
                    		return true;
                    	}
                    }

                    et dans mon main.cpp:

                    ANativeActivity *activity = sf::getNativeActivity();
                    JNIEnv* env = activity->env;            
                    jclass cls_Env = (*env).FindClass("com/psdk/NativeActivity");
                    jmethodID mid = (*env).GetMethodID(cls_Env, "tata", "()Ljava/lang/String;");
                    jobject obj_File = (*env).CallObjectMethod(activity->clazz, mid, NULL);


                    Je n'ai pas de log, pourquoi ça fait ça ? dans mon code java au niveau du 

                    System.loadLibrary("jni-lib");

                    J'ai mis jni-lib mais je ne sais pas si c'est correct, ça correspond à quoi ?

                    Encore merci pour votre aide

                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 octobre 2022 à 18:50:37

                      Je vais encore insister sur le fait que l'emplacement où tu écris ton fichier n'est peut-être pas accessible en écriture.

                      Tu sembles t'être inspiré de ce post https://stackoverflow.com/questions/11386441/filewriter-not-writing-to-file-in-android mais sans prendre en compte l'emplacement du fichier..

                      • Partager sur Facebook
                      • Partager sur Twitter

                      android c++ ifstream

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown