Загрузить JSON из php в строки во фрагменте? ⇐ Android
-
Anonymous
Загрузить JSON из php в строки во фрагменте?
Я занимаюсь этим в свободное время уже довольно давно, и каждый раз, когда мне кажется, что я чего-то достиг, я возвращаюсь к исходной точке и расстраиваюсь, потому что знаю, что это не так уж и сложно. Я просто где-то что-то упускаю и не знаю что.
[*]У меня есть php-файл, выдающий результаты в формате JSON.
[{"id":"1","longitude":"-82.831853","lattitude":"39.918837"}]
Я пробовал использовать отдельный класс, пробовал использовать прямой встроенный класс в файле и получаю те же результаты.
Результат таков: он загружается во фрагмент при первой загрузке. Если вы нажмете любую кнопку навигации, чтобы перейти к другому фрагменту, а затем щелкните кнопку навигации, чтобы вернуться к фрагменту, или даже просто щелкните кнопку навигации, чтобы (перезагрузить) фрагмент, значение не будет иметь значения. Первая загрузка загружает правильные значения, вторая загрузка — значения равны нулю. Мне приходится закрыть приложение, снова открыть его, нажать кнопку навигации и угадать, какие там правильные значения, пока вы не нажмете, чтобы открыть его снова. Ниже приведен базовый код, который я использую.
public TruckFragment() { // Требуемый пустой публичный конструктор } @Override public void onAttach (Контекстный контекст) { super.onAttach(контекст); mactivity = getActivity(); } @Override public void onCreate (Bundle saveInstanceState) { super.onCreate(saveInstanceState); } @Override public View onCreateView(@NonNull LayoutInflater инфлятор, контейнер ViewGroup, Пакет saveInstanceState) { mView = inflater.inflate(R.layout.fragment_truck, контейнер, false); если (this.getArguments() != null) { Log.d("эй", "эй"); } вернуть mView; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle saveInstanceState) { super.onViewCreated(просмотр, saveInstanceState); getJSON("get.php"); } частная пустота getJSON (окончательная строка urlWebService) { класс GetJSON расширяет AsyncTask { защищенный недействительный onPreExecute () { супер.onPreExecute(); } protected void onPostExecute (String s) { супер.onPostExecute(s); } protected String doInBackground(Void... Voids) { пытаться { URL URL = новый URL (urlWebService); HttpURLConnection con = (HttpURLConnection) url.openConnection(); StringBuilder sb = новый StringBuilder(); BufferedReader bufferedReader = новый BufferedReader (новый InputStreamReader (con.getInputStream ())); Строка JSON; while ((json =ufferedReader.readLine()) != null) { sb.append((json + "\n")); mySB = String.valueOf(sb); } вернуть sb.toString().trim(); } catch (Исключение е) { вернуть ноль; } } } GetJSON getJSON = новый GetJSON(); getJSON.execute(); } Поэтому в целях тестирования я создал глобальную переменную под названием mySB, чтобы присвоить ей значение строки json.
Опять же, когда я запускаю его в первый раз, это правильно, когда вы загружаете его снова, он равен нулю. Я не знаю, чего мне не хватает.
Единственная цель — получить два фрагмента данных из json и сохранить их в строках, чтобы я мог ссылаться на них в другом месте кода.
Навигация вызывается из основного действия Я пробовал прикрепить, отсоединить, остановить, возобновить работу, но это, похоже, не решило никаких проблем. Итак, вот моя Main_Activity.
пакет com.app.restaurant.bowzers; импортировать android.os.Bundle; импортировать android.view.MenuItem; импортировать androidx.annotation.DrawableRes; импортировать androidx.annotation.StringRes; импортировать androidx.appcompat.app.AppCompatActivity; импортировать androidx.appcompat.widget.Toolbar; импортировать androidx.fragment.app.Fragment; импортировать com.app.restaurant.bowzers.fragments.FoodMenuFragment; импортировать com.app.restaurant.bowzers.fragments.HomeFragment; импортировать com.app.restaurant.bowzers.fragments.MapFragment; импортировать com.app.restaurant.bowzers.fragments.PageFragment; импортировать com.app.restaurant.bowzers.fragments.TruckFragment; импортировать com.google.android.material.bottomnavigation.BottomNavigationView; импортировать android.Manifest; импортировать androidx.core.content.ContextCompat; импортировать android.content.pm.PackageManager; импортировать androidx.core.app.ActivityCompat; импортировать android.widget.Toast; импортировать android.content.Intent; импортировать android.net.Uri; публичный класс MainActivity расширяет AppCompatActivity { статический окончательный Integer CALL = 0x2; частная статическая окончательная строка SELECTION = «SELECTION»; частный BottomNavigationView @Override protected void onCreate (Bundle saveInstanceState) { super.onCreate(saveInstanceState); setContentView(R.layout.activity_main); панель инструментов настройки(); setupBottomMenu (saveInstanceState); //настройкаНавигация(); } /*private void setupNavigation() { BottomNavigationView BottomNavigationView = findViewById(R.id.bottom_navigation); NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); NavigationUI.setupWithNavController(bottomNavigationView, навконтроллер); AppBarConfiguration appBarConfiguration = новый AppBarConfiguration.Builder(R.id.page_home, R.id.page_fav, R.id.page_list, R.id.page_settings, R.id.page_search) .строить(); NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); }*/ @Override protected void onSaveInstanceState (Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(SELECTION, BottomNavigationView.getSelectedItemId()); } частная пустота setupToolbar() { Панель инструментов Toolbar = findViewById(R.id.toolbar); setSupportActionBar (панель инструментов); } частный недействительный setupBottomMenu (Bundle saveInstanceState) { BottomNavigationView = findViewById(R.id.bottom_navigation); BottomNavigationView.setOnItemSelectedListener(this::onItemSelectedListener); если (savedInstanceState == ноль) { //отображает начальный фрагмент при запуске приложения BottomNavigationView.setSelectedItemId(R.id.page_home); } еще { //восстанавливает элемент, выбранный перед поворотом BottomNavigationView.setSelectedItemId(saveInstanceState.getInt(SELECTION)); } BottomNavigationView.getOrCreateBadge(R.id.page_fav).setNumber(1000); BottomNavigationView.getOrCreateBadge(R.id.page_callus).setVisible(true); } частное логическое значение onItemSelectedListener (пункт MenuItem) { переключатель (item.getItemId()) { случай R.id.page_home -> { //showPageFragment(R.drawable.baseline_home_black_48, R.string.bottom_nav_home); showFragment(new HomeFragment(), R.string.hello_home_test); вернуть истину; } случай R.id.page_foodmenu -> { //showFragment(новый MenuFragment(), R.string.bottom_nav_menu); //showPageFragment(R.drawable.icon_menu, R.string.bottom_nav_menu); showFragment(new FoodMenuFragment(), R.string.hello_menu_test); вернуть истину; } случай R.id.location -> { // showPageFragment(R.drawable.baseline_favorite_black_48, R.string.bottom_nav_location); showFragment(new MapFragment(), R.string.hello_menu_test); вернуть истину; } случай R.id.truck -> { //showFragment(new TruckFragment(), R.string.bottom_nav_truck); showmytruckFragment(new TruckFragment(), R.string.bottom_nav_truck); вернуть истину; } случай R.id.callus -> { AskForPermission(Manifest.permission.CALL_PHONE, CALL); } по умолчанию -> выдать новое IllegalArgumentException("элемент не реализован: " + item.getItemId()); } вернуть ложь; } частный недействительный Clear_backstack () { Намерение я = новое намерение (MainActivity.this, MainActivity.class); заканчивать(); overridePendingTransition(0, 0); //startActivity(R.id.fra); overridePendingTransition(0, 0); } Private void AskForPermission (Разрешение String, Integer requestCode) { if (ContextCompat.checkSelfPermission(MainActivity.this, разрешение) != PackageManager.PERMISSION_GRANTED) { // Должны ли мы показать объяснение? if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, разрешение)) { //Это вызывается, если пользователь ранее отклонил разрешение //В этом случае я просто снова спрашиваю разрешения ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode); } еще { ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode); } } еще { // Toast.makeText(this, "" + разрешение + " уже предоставлено.", Toast.LENGTH_SHORT).show(); позвонить(); } } @Override public void onRequestPermissionsResult(int requestCode, разрешения String[], int[]grantResults) { super.onRequestPermissionsResult(requestCode, разрешения, GrantResults); if (ActivityCompat.checkSelfPermission(this, Permissions[0]) == PackageManager.PERMISSION_GRANTED) { переключатель (код запроса) { //Вызов случай 2: if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { позвонить(); BottomNavigationView.setSelectedItemId(R.id.page_foodmenu); } перерыв; } Toast.makeText(this, «Разрешение предоставлено», Toast.LENGTH_SHORT).show(); } еще { Toast.makeText(this, «В доступе отказано», Toast.LENGTH_SHORT).show(); } } защищенный недействительный makeCall() { Строка номер = "6143980364"; Строка d = "тел:" + число; Намерение phoneIntent = новое намерение (Intent.ACTION_CALL); phoneIntent.setData(Uri.parse(d)); пытаться { startActivity (phoneIntent); заканчивать(); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(this, «Не удалось выполнить вызов, повторите попытку позже.», Toast.LENGTH_SHORT).show(); } } Private void showPageFragment(@DrawableRes int iconId, @StringRes int title) { showFragment(PageFragment.newInstance(iconId), title); } Private void showmytruckFragment(Fragment frg, @StringRes int title) { getSupportFragmentManager() .beginTransaction() .setCustomAnimations(R.anim.bottom_nav_enter, R.anim.bottom_nav_exit) .replace(R.id.container, frg) .совершить(); setTitle (название); } // Фрагмент фрагмента = getSupportFragmentManager().findFragmentById(R.id.main_frag) // И это в методе прослушивателя OnClick // если(фрагмент!= ноль) // getSupportFragmentManager().beginTransaction().remove(fragment).commit(); Private void showFragment(Fragment frg, @StringRes int title) { getSupportFragmentManager() .beginTransaction() .setCustomAnimations(R.anim.bottom_nav_enter, R.anim.bottom_nav_exit) .replace(R.id.container, frg) .совершить(); setTitle (название); } } Фрагмент, с которым я работаю, — TruckFragment.
Я занимаюсь этим в свободное время уже довольно давно, и каждый раз, когда мне кажется, что я чего-то достиг, я возвращаюсь к исходной точке и расстраиваюсь, потому что знаю, что это не так уж и сложно. Я просто где-то что-то упускаю и не знаю что.
[*]У меня есть php-файл, выдающий результаты в формате JSON.
[{"id":"1","longitude":"-82.831853","lattitude":"39.918837"}]
Я пробовал использовать отдельный класс, пробовал использовать прямой встроенный класс в файле и получаю те же результаты.
Результат таков: он загружается во фрагмент при первой загрузке. Если вы нажмете любую кнопку навигации, чтобы перейти к другому фрагменту, а затем щелкните кнопку навигации, чтобы вернуться к фрагменту, или даже просто щелкните кнопку навигации, чтобы (перезагрузить) фрагмент, значение не будет иметь значения. Первая загрузка загружает правильные значения, вторая загрузка — значения равны нулю. Мне приходится закрыть приложение, снова открыть его, нажать кнопку навигации и угадать, какие там правильные значения, пока вы не нажмете, чтобы открыть его снова. Ниже приведен базовый код, который я использую.
public TruckFragment() { // Требуемый пустой публичный конструктор } @Override public void onAttach (Контекстный контекст) { super.onAttach(контекст); mactivity = getActivity(); } @Override public void onCreate (Bundle saveInstanceState) { super.onCreate(saveInstanceState); } @Override public View onCreateView(@NonNull LayoutInflater инфлятор, контейнер ViewGroup, Пакет saveInstanceState) { mView = inflater.inflate(R.layout.fragment_truck, контейнер, false); если (this.getArguments() != null) { Log.d("эй", "эй"); } вернуть mView; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle saveInstanceState) { super.onViewCreated(просмотр, saveInstanceState); getJSON("get.php"); } частная пустота getJSON (окончательная строка urlWebService) { класс GetJSON расширяет AsyncTask { защищенный недействительный onPreExecute () { супер.onPreExecute(); } protected void onPostExecute (String s) { супер.onPostExecute(s); } protected String doInBackground(Void... Voids) { пытаться { URL URL = новый URL (urlWebService); HttpURLConnection con = (HttpURLConnection) url.openConnection(); StringBuilder sb = новый StringBuilder(); BufferedReader bufferedReader = новый BufferedReader (новый InputStreamReader (con.getInputStream ())); Строка JSON; while ((json =ufferedReader.readLine()) != null) { sb.append((json + "\n")); mySB = String.valueOf(sb); } вернуть sb.toString().trim(); } catch (Исключение е) { вернуть ноль; } } } GetJSON getJSON = новый GetJSON(); getJSON.execute(); } Поэтому в целях тестирования я создал глобальную переменную под названием mySB, чтобы присвоить ей значение строки json.
Опять же, когда я запускаю его в первый раз, это правильно, когда вы загружаете его снова, он равен нулю. Я не знаю, чего мне не хватает.
Единственная цель — получить два фрагмента данных из json и сохранить их в строках, чтобы я мог ссылаться на них в другом месте кода.
Навигация вызывается из основного действия Я пробовал прикрепить, отсоединить, остановить, возобновить работу, но это, похоже, не решило никаких проблем. Итак, вот моя Main_Activity.
пакет com.app.restaurant.bowzers; импортировать android.os.Bundle; импортировать android.view.MenuItem; импортировать androidx.annotation.DrawableRes; импортировать androidx.annotation.StringRes; импортировать androidx.appcompat.app.AppCompatActivity; импортировать androidx.appcompat.widget.Toolbar; импортировать androidx.fragment.app.Fragment; импортировать com.app.restaurant.bowzers.fragments.FoodMenuFragment; импортировать com.app.restaurant.bowzers.fragments.HomeFragment; импортировать com.app.restaurant.bowzers.fragments.MapFragment; импортировать com.app.restaurant.bowzers.fragments.PageFragment; импортировать com.app.restaurant.bowzers.fragments.TruckFragment; импортировать com.google.android.material.bottomnavigation.BottomNavigationView; импортировать android.Manifest; импортировать androidx.core.content.ContextCompat; импортировать android.content.pm.PackageManager; импортировать androidx.core.app.ActivityCompat; импортировать android.widget.Toast; импортировать android.content.Intent; импортировать android.net.Uri; публичный класс MainActivity расширяет AppCompatActivity { статический окончательный Integer CALL = 0x2; частная статическая окончательная строка SELECTION = «SELECTION»; частный BottomNavigationView @Override protected void onCreate (Bundle saveInstanceState) { super.onCreate(saveInstanceState); setContentView(R.layout.activity_main); панель инструментов настройки(); setupBottomMenu (saveInstanceState); //настройкаНавигация(); } /*private void setupNavigation() { BottomNavigationView BottomNavigationView = findViewById(R.id.bottom_navigation); NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); NavigationUI.setupWithNavController(bottomNavigationView, навконтроллер); AppBarConfiguration appBarConfiguration = новый AppBarConfiguration.Builder(R.id.page_home, R.id.page_fav, R.id.page_list, R.id.page_settings, R.id.page_search) .строить(); NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); }*/ @Override protected void onSaveInstanceState (Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(SELECTION, BottomNavigationView.getSelectedItemId()); } частная пустота setupToolbar() { Панель инструментов Toolbar = findViewById(R.id.toolbar); setSupportActionBar (панель инструментов); } частный недействительный setupBottomMenu (Bundle saveInstanceState) { BottomNavigationView = findViewById(R.id.bottom_navigation); BottomNavigationView.setOnItemSelectedListener(this::onItemSelectedListener); если (savedInstanceState == ноль) { //отображает начальный фрагмент при запуске приложения BottomNavigationView.setSelectedItemId(R.id.page_home); } еще { //восстанавливает элемент, выбранный перед поворотом BottomNavigationView.setSelectedItemId(saveInstanceState.getInt(SELECTION)); } BottomNavigationView.getOrCreateBadge(R.id.page_fav).setNumber(1000); BottomNavigationView.getOrCreateBadge(R.id.page_callus).setVisible(true); } частное логическое значение onItemSelectedListener (пункт MenuItem) { переключатель (item.getItemId()) { случай R.id.page_home -> { //showPageFragment(R.drawable.baseline_home_black_48, R.string.bottom_nav_home); showFragment(new HomeFragment(), R.string.hello_home_test); вернуть истину; } случай R.id.page_foodmenu -> { //showFragment(новый MenuFragment(), R.string.bottom_nav_menu); //showPageFragment(R.drawable.icon_menu, R.string.bottom_nav_menu); showFragment(new FoodMenuFragment(), R.string.hello_menu_test); вернуть истину; } случай R.id.location -> { // showPageFragment(R.drawable.baseline_favorite_black_48, R.string.bottom_nav_location); showFragment(new MapFragment(), R.string.hello_menu_test); вернуть истину; } случай R.id.truck -> { //showFragment(new TruckFragment(), R.string.bottom_nav_truck); showmytruckFragment(new TruckFragment(), R.string.bottom_nav_truck); вернуть истину; } случай R.id.callus -> { AskForPermission(Manifest.permission.CALL_PHONE, CALL); } по умолчанию -> выдать новое IllegalArgumentException("элемент не реализован: " + item.getItemId()); } вернуть ложь; } частный недействительный Clear_backstack () { Намерение я = новое намерение (MainActivity.this, MainActivity.class); заканчивать(); overridePendingTransition(0, 0); //startActivity(R.id.fra); overridePendingTransition(0, 0); } Private void AskForPermission (Разрешение String, Integer requestCode) { if (ContextCompat.checkSelfPermission(MainActivity.this, разрешение) != PackageManager.PERMISSION_GRANTED) { // Должны ли мы показать объяснение? if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, разрешение)) { //Это вызывается, если пользователь ранее отклонил разрешение //В этом случае я просто снова спрашиваю разрешения ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode); } еще { ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode); } } еще { // Toast.makeText(this, "" + разрешение + " уже предоставлено.", Toast.LENGTH_SHORT).show(); позвонить(); } } @Override public void onRequestPermissionsResult(int requestCode, разрешения String[], int[]grantResults) { super.onRequestPermissionsResult(requestCode, разрешения, GrantResults); if (ActivityCompat.checkSelfPermission(this, Permissions[0]) == PackageManager.PERMISSION_GRANTED) { переключатель (код запроса) { //Вызов случай 2: if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { позвонить(); BottomNavigationView.setSelectedItemId(R.id.page_foodmenu); } перерыв; } Toast.makeText(this, «Разрешение предоставлено», Toast.LENGTH_SHORT).show(); } еще { Toast.makeText(this, «В доступе отказано», Toast.LENGTH_SHORT).show(); } } защищенный недействительный makeCall() { Строка номер = "6143980364"; Строка d = "тел:" + число; Намерение phoneIntent = новое намерение (Intent.ACTION_CALL); phoneIntent.setData(Uri.parse(d)); пытаться { startActivity (phoneIntent); заканчивать(); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(this, «Не удалось выполнить вызов, повторите попытку позже.», Toast.LENGTH_SHORT).show(); } } Private void showPageFragment(@DrawableRes int iconId, @StringRes int title) { showFragment(PageFragment.newInstance(iconId), title); } Private void showmytruckFragment(Fragment frg, @StringRes int title) { getSupportFragmentManager() .beginTransaction() .setCustomAnimations(R.anim.bottom_nav_enter, R.anim.bottom_nav_exit) .replace(R.id.container, frg) .совершить(); setTitle (название); } // Фрагмент фрагмента = getSupportFragmentManager().findFragmentById(R.id.main_frag) // И это в методе прослушивателя OnClick // если(фрагмент!= ноль) // getSupportFragmentManager().beginTransaction().remove(fragment).commit(); Private void showFragment(Fragment frg, @StringRes int title) { getSupportFragmentManager() .beginTransaction() .setCustomAnimations(R.anim.bottom_nav_enter, R.anim.bottom_nav_exit) .replace(R.id.container, frg) .совершить(); setTitle (название); } } Фрагмент, с которым я работаю, — TruckFragment.
Мобильная версия