This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I have 2 modules in my application as follow app and interface. interface was an imported aar file.
I am trying to launch an activity in the interface module but every time the application crashes. Launching activities on the app module works fine
I had tried the other solutions available in this forum but was in vain. Find the codes below
QuestionAnalyser class
package com.example.dell.bubblebot;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import com.example.dell.yandexapilanguagetranslator.Translator;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class QuestionAnalyser extends AppCompatActivity {
public static String question;
public static String[] words;
String entityIdentified;
static boolean identified = false;
DatabaseReference entityRef;
TranslatorServant t = new TranslatorServant();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_interface);
Translator.setKey ("trnsl.1.1.20181013T134643Z.debdb5811d6caba2.3a4daf18b25c9f4b97662d5e9ac45ed81b199c84");
}
public void analyse(String userQues) {
TranslatorServant t = new TranslatorServant();
question = userQues.replaceAll("\\p{Punct}|\\d", "");
// question = t.translateText(userQues).replaceAll("\\p{Punct}|\\d", "");
words = question.split(" ");
getEntity(words);
}
private void getEntity(final String[] words) {
entityRef = FirebaseDatabase.getInstance().getReference().child("IRAdata").child("Entities");
entityRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot entity : dataSnapshot.getChildren()) {
String[] synonyms = entity.child("syn").getValue().toString().split(",");
for (String syn : synonyms) {
for (String word : words) {
if (word.equalsIgnoreCase(syn) || question.equalsIgnoreCase(syn)) {
entityIdentified = entity.getKey();
identified = true;
}
}
}
}
check(words);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public void mimicOtherMessage(String message) {
ChatMessage chatMessage = new ChatMessage(message, false);
Interface.madapter.add(chatMessage);
}
public void mimicOtherMessage() {
ChatMessage chatMessage = new ChatMessage(null, false);
Interface.madapter.add(chatMessage);
}
public void check(String[] words) {
if (identified == true) {
initialiseEntityServant(entityIdentified, question, words);
}
if (identified == false) {
for (String yes : YesNo.yes) {
for (String w : words) {
if (w.equalsIgnoreCase(yes) || question.equalsIgnoreCase(yes)) {
identified = true;
entityIdentified = "basic";
initialiseEntityServant(entityIdentified, question, words);
}
}
for (String no : YesNo.no) {
for (String w : words) {
if (w.equalsIgnoreCase(no) || question.equalsIgnoreCase(no)) {
identified = true;
entityIdentified = "basic";
initialiseEntityServant(entityIdentified, question, words);
}
}
}
}
}
if (identified == false) {
mimicOtherMessage("Sorry, I failed to understand your question.");
}
}
private void initialiseEntityServant(String ent, final String userQues, final String[] words) {
if (ent.equalsIgnoreCase("cuisine")) {
cuisine c=new cuisine();
c.analyse();
}
if(ent.equalsIgnoreCase("basic")){
final List<String> urlsList = new ArrayList<String>();
final List<String> descList = new ArrayList<String>();
urlsList.add("https://media.timeout.com/images/103708802/image.jpg");
urlsList.add("\"https://images.myguide-cdn.com/mauritius/companies/eighty-eight-chinese-restaurant/large/eighty-eight-chinese-restaurant-492783.png");
descList.add("A Chinese dish of small steamed or fried savoury dumplings containing various fillings. Definitely worth a try");
descList.add("Traditionally, this Chinese chicken dish is a dry-stir fry — not a lot of sauce is added into Kung Pao chicken. However, with the amount of flavour explosions happening in this dish, you don’t miss OR want any more sauce.");
Intent i= new Intent(getApplicationContext(),gallery.class);
i.putExtra("urls",urlsList.toArray());
i.putExtra("desc",descList.toArray());
startActivity(i);
}
// will need to initialise other classes
}
//add class to check if question and answer already exists
}
In this code i am calling the gallery activity
gallery class:
package com.example.dell.bubblebot;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class gallery extends AppCompatActivity {
public static String[]desc;
public static TextView descTextbox;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
descTextbox=(TextView)findViewById(R.id.desc);
ViewPager viewPager=findViewById(R.id.view_pager);
String[] imageUrls=getIntent().getStringArrayExtra("urls");
String [] descArr=getIntent().getStringArrayExtra("desc");
desc=descArr;
ViewPagerAdapter adapter= new ViewPagerAdapter(this,imageUrls);
viewPager.setAdapter(adapter);
}
}
Error message:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.samples.chatbotsample1, PID: 14653
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:112)
at com.example.dell.bubblebot.QuestionAnalyser.initialiseEntityServant(QuestionAnalyser.java:126)
at com.example.dell.bubblebot.QuestionAnalyser.check(QuestionAnalyser.java:93)
at com.example.dell.bubblebot.QuestionAnalyser$1.onDataChange(QuestionAnalyser.java:61)
at com.google.firebase.database.obfuscated.zzap.zza(com.google.firebase:firebase-database##16.0.3:75)
at com.google.firebase.database.obfuscated.zzca.zza(com.google.firebase:firebase-database##16.0.3:63)
at com.google.firebase.database.obfuscated.zzcd$1.run(com.google.firebase:firebase-database##16.0.3:55)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7406)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Notice:
Class A { ...
}
getApplicationContext belongs to abstract class Context, if you want to use this method in your custom class, the class should extends Context or any of its sub class, such as Application,Activity, etc.
Related
I'm working on a book-searching app project. The user enters a title, and the app searches Google Books for it.
I initially had one activity and layout. I decided to use two layouts (one for user to enter title, and the other displays results); had to create another activity because the results layout was throwing an exception about 'null' object reference.
After creating the second activity, I used an intent to transfer List data between the two activities; no sooner did I find out that I had to use a Serialize or Parcelable object for the purpose.
Following instructions at Pass list of objects from one activity to other activity in android & https://www.vogella.com/tutorials/AndroidParcelable/article.html, I failed at implementing both, because Serialize sent an empty ArrayList (thus, an empty results page, even though there're book hits) and Parcelable was throwing out different exceptions everytime I used it, probably because I'm using an ArrayAdapter to populate the ListView with books.
I don't think I'm ready to implement the API at https://www.vogella.com/tutorials/AutoValue/article.html and can't use Fragments as well. A better structure would be to use a single activity, View.GONE the background image I so much cherish, and display list of book objects under the search field. But it would be good to make a follow-up on Serialize & Parcelable -- for future projects.
So, fellow developers, what's the solution to this?
FirstActivity screenshot
SecondActivity screeenshot
Here's my code:
MainActivity:
package project.android.gbookslisting;
import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import androidx.appcompat.app.AppCompatActivity;
import static project.android.gbookslisting.ResultsActivity.adapter;
//import android.support.v4.content.AsyncTaskLoader;
//import android.support.v7.app.AppCompatActivity;
public class ParamsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Book>>, Serializable {
private static final int LOADER_ID = 0;
private static String LOG_TAG = ParamsActivity.class.getName();
EditText text;
String query;
private LoaderManager loaderManager = getLoaderManager();
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parameters);
Button query = findViewById(R.id.search_button);
text = findViewById(R.id.deets_field);
query.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View view) {
if (text.getText().toString().length() > 0) { loaderManager.initLoader(LOADER_ID, null, ParamsActivity.this);
} else if (text.getText().length() < 1) {
text.setHint("Please enter book title/details");
text.setHintTextColor(Color.RED);
}
}
});
}
#Override
public Loader<List<Book>> onCreateLoader (int i, Bundle bundle) {
query = text.getText().toString();
return new BookLoader(this, query);
}
#Override
public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) {
// If there is a valid list of {#link Book}s, then add them to the adapter's dataset. This will trigger the ListView to update.
if (data != null && !data.isEmpty()) {
data = new ArrayList<Book>();
Intent i = new Intent(getApplicationContext(), ResultsActivity.class);
i.putExtra("data", (Serializable) data);
startActivity(i);
}
}
#Override
public void onLoaderReset (Loader loader) {
adapter = new Adapt(this, new ArrayList<Book>());
adapter.clear();
}
}
SecondActivity:
package project.android.gbookslisting;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import java.io.Serializable;
import java.util.ArrayList;
import androidx.appcompat.app.AppCompatActivity;
public class ResultsActivity extends AppCompatActivity implements Serializable {
static Adapt adapter;
static TextView emptyResult;
ListView bookEntries;
String LOG_TAG = ResultsActivity.class.getName();
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hits_page);
Intent i = getIntent();
ArrayList<Book> books = (ArrayList<Book>) i.getSerializableExtra("data");
emptyResult = findViewById(R.id.matches_nill);
emptyResult.setText(R.string.matches0);
if (!books.isEmpty()) {
emptyResult.setVisibility(View.GONE);
// Create a new adapter that takes a rich (or otherwise empty) list of books as input
adapter = new Adapt(this, new ArrayList<Book>());
// Get the list of books from {#link Search}
bookEntries = findViewById(R.id.catalog);
bookEntries.setAdapter(adapter);
bookEntries.setEmptyView(emptyResult);
bookEntries.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick (AdapterView<?> adapterView, View view, int position, long l) {
// Find the current book that was clicked on
Book currentBook = adapter.getItem(position);
// Convert the String URL into a URI object (to pass into the Intent constructor)
Uri bookUri = Uri.parse(currentBook.getPage());
// Create a new intent to view the book URI
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, bookUri);
// Send the intent to launch a new activity
startActivity(websiteIntent);
}
});
// adapter.clear();
adapter.addAll(books);
} else {
emptyResult.setVisibility(View.VISIBLE);
emptyResult.setText(R.string.matches0);
}
}
}
Book obj.:
package project.android.gbookslisting;
import java.io.Serializable;
import java.util.Date;
public class Book {
private String book_title;
private String author;
private String publishing_year;
private String page;
public Book (String theTitle, String theAuthor, String theYear, String thePage) {
this.book_title = theTitle;
this.author = theAuthor;
this.publishing_year = theYear;
this.page = thePage;
}
public Book setBook_title (String book_title) {
this.book_title = book_title;
return this;
}
public Book setAuthor (String author) {
this.author = author;
return this;
}
public Book setPublishing_year (String publishing_year) {
this.publishing_year = publishing_year;
return this;
}
public Book setPage (String page) {
this.page = page;
return this;
}
protected String getAuthor () {
return author;
}
protected String getPublishing_year () { return publishing_year; }
protected String getPage () {
return page;
}
protected String getBook_title () {
return book_title;
}
}
You can declare the a variable that will handle your data = new ArrayList<Book>(); as public static.. However it's not recommended for high level codebase but for the structures of yours, you can implement it.
just declare a variable like this above protected void onCreate() in FirstActivity ..
public static List<Book> book_data = new ArrayList<>();
and transfer the data from public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) to book_data
#Override
public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) {
// If there is a valid list of {#link Book}s, then add them to the adapter's dataset. This will trigger the ListView to update.
if (data != null && !data.isEmpty()) {
//data = new ArrayList<Book>();
book_data = data;
Intent i = new Intent(getApplicationContext(), ResultsActivity.class);
startActivity(i);
}
}`
You can also try to debug it if it contains a value
Log.d(TAG, String.valueOf(data.size()));
and in SecondActivity
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hits_page);
List<Book> books = new ArrayList<>();
books = FirstActivity.book_data; //Get the data from the First Activity
....
....
}
All right, so I was able to correct my implementation of the Parcelable interface and the FirstActivity now passes data to SecondActivity. This is it:
package project.android.gbookslisting;
import android.os.Parcel;
import android.os.Parcelable;
public class Book implements Parcelable {
private String book_title;
private String author;
private String publishing_year;
private String page;
public Book (String theTitle, String theAuthor, String theYear, String thePage) {
this.book_title = theTitle;
this.author = theAuthor;
this.publishing_year = theYear;
this.page = thePage;
}
public Book(Parcel in) {
this.book_title = in.readString();
this.author = in.readString();
this.publishing_year = in.readString();
this.page = in.readString();
}
public static final Creator<Book> CREATOR = new Creator<Book>() {
#Override
public Book createFromParcel (Parcel in) {
return new Book(in);
}
#Override
public Book[] newArray (int size) {
return new Book[size];
}
};
protected String getAuthor () { return author; }
protected String getPublishing_year () { return publishing_year; }
protected String getPage () {
return page;
}
protected String getBook_title () {
return book_title;
}
#Override
public int describeContents () {
return 0;
}
#Override
public void writeToParcel (Parcel parcel, int flags) {
parcel.writeString(book_title);
parcel.writeString(author);
parcel.writeString(publishing_year);
parcel.writeString(page);
}
}
I've shared the repository on GitHub #GBooks Listing, pending more features/updates.
ResultsActivity
Sure looks lame, but I'll improve the theming & whatever affects appearance. Thanks.
I am building a audio player i have completed all the Songs browsing (UI) activities and to handle audio playback i am using google sample audio player this and i read all the src from this sample and there is class MusicLibrary in sample code and it contains a sample list of songs like below
public class MusicLibrary {
private static final TreeMap<String, MediaMetadataCompat> music = new TreeMap<>();
private static final HashMap<String, Integer> albumRes = new HashMap<>();
private static final HashMap<String, String> musicFileName = new HashMap<>();
static {
createMediaMetadataCompat(
"Jazz_In_Paris",
"Jazz in Paris",
"Media Right Productions",
"Jazz & Blues",
"Jazz",
103,
TimeUnit.SECONDS,
"http://www.noiseaddicts.com/samples_1w72b820/2537.mp3",
R.drawable.album_jazz_blues,
"https://upload.wikimedia.org/wikipedia/en/a/ac/Audioslave_-_Audioslave.jpg");
createMediaMetadataCompat(
"The_Coldest_Shoulder",
"The Coldest Shoulder",
"The 126ers",
"Youtube Audio Library Rock 2",
"Rock",
160,
TimeUnit.SECONDS,
"http://www.noiseaddicts.com/samples_1w72b820/4201.mp3",
R.drawable.album_youtube_audio_library_rock_2,
"https://theflagcompany.in/wp-content/uploads/2018/10/Indian-National-Flag-300x300.jpeg");
}
but i am unable to find a method which shows how to add a song in current playlist from other activities for example in my current app there is search activity where user can search any song from internet and i want to add track from this search activity by two different ways 1. add and play song 2. only add song in the end of playlist.
Sample code track object use album art image from drawable folder but in my app i need to show album art from internet (Last FM API) not from local folder i tried to edit MusicLibrary class and created a bitmap from URI unable to make it work so this is alos i need to modify in sample code.
Sample code contains only on simple activity where when you open it opens a audio player interface but in my app in HomeActivity there are some fragments and a mini player at bottom now like below
Please help me with these two things
add songs to player from my code
use internet image for METADATA_KEY_ALBUM_ART
i just want to merge these two things and i am new to android so no luck please guide me so that i can complete my project. Thanks in advance :)
My Main Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//add song in sample player service from this method
public void addSongQue(Song song) {
title = song.getTile;
artist = song.getArtist;
mp3Url = song.getSrc;
albumArtImage = song.getAlbumArt;
.......
...
}
}
Sample Code Player Activity full sample src is here
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.android.mediasession.R;
import com.example.android.mediasession.client.MediaBrowserHelper;
import com.example.android.mediasession.service.MusicService;
import com.example.android.mediasession.service.contentcatalogs.MusicLibrary;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ImageView mAlbumArt;
private TextView mTitleTextView;
private TextView mArtistTextView;
private ImageView mMediaControlsImage;
private MediaSeekBar mSeekBarAudio;
private MediaBrowserHelper mMediaBrowserHelper;
private boolean mIsPlaying;
//https://github.com/googlesamples/android-MediaBrowserService
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitleTextView = findViewById(R.id.song_title);
mArtistTextView = findViewById(R.id.song_artist);
mAlbumArt = findViewById(R.id.album_art);
mMediaControlsImage = findViewById(R.id.media_controls);
mSeekBarAudio = findViewById(R.id.seekbar_audio);
final ClickListener clickListener = new ClickListener();
findViewById(R.id.button_previous).setOnClickListener(clickListener);
findViewById(R.id.button_play).setOnClickListener(clickListener);
findViewById(R.id.button_next).setOnClickListener(clickListener);
mMediaBrowserHelper = new MediaBrowserConnection(this);
mMediaBrowserHelper.registerCallback(new MediaBrowserListener());
}
#Override
public void onStart() {
super.onStart();
mMediaBrowserHelper.onStart();
}
#Override
public void onStop() {
super.onStop();
mSeekBarAudio.disconnectController();
mMediaBrowserHelper.onStop();
}
/**
* Convenience class to collect the click listeners together.
* <p>
* In a larger app it's better to split the listeners out or to use your favorite
* library.
*/
private class ClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_previous:
mMediaBrowserHelper.getTransportControls().skipToPrevious();
break;
case R.id.button_play:
if (mIsPlaying) {
mMediaBrowserHelper.getTransportControls().pause();
} else {
mMediaBrowserHelper.getTransportControls().play();
}
break;
case R.id.button_next:
mMediaBrowserHelper.getTransportControls().skipToNext();
break;
}
}
}
/**
* Customize the connection to our {#link android.support.v4.media.MediaBrowserServiceCompat}
* and implement our app specific desires.
*/
private class MediaBrowserConnection extends MediaBrowserHelper {
private MediaBrowserConnection(Context context) {
super(context, MusicService.class);
}
#Override
protected void onConnected(#NonNull MediaControllerCompat mediaController) {
mSeekBarAudio.setMediaController(mediaController);
}
#Override
protected void onChildrenLoaded(#NonNull String parentId,
#NonNull List<MediaBrowserCompat.MediaItem> children) {
super.onChildrenLoaded(parentId, children);
final MediaControllerCompat mediaController = getMediaController();
// Queue up all media items for this simple sample.
for (final MediaBrowserCompat.MediaItem mediaItem : children) {
mediaController.addQueueItem(mediaItem.getDescription());
}
// Call prepare now so pressing play just works.
mediaController.getTransportControls().prepare();
}
}
/**
* Implementation of the {#link MediaControllerCompat.Callback} methods we're interested in.
* <p>
* Here would also be where one could override
* {#code onQueueChanged(List<MediaSessionCompat.QueueItem> queue)} to get informed when items
* are added or removed from the queue. We don't do this here in order to keep the UI
* simple.
*/
private class MediaBrowserListener extends MediaControllerCompat.Callback {
#Override
public void onPlaybackStateChanged(PlaybackStateCompat playbackState) {
mIsPlaying = playbackState != null &&
playbackState.getState() == PlaybackStateCompat.STATE_PLAYING;
mMediaControlsImage.setPressed(mIsPlaying);
}
#Override
public void onMetadataChanged(MediaMetadataCompat mediaMetadata) {
if (mediaMetadata == null) {
return;
}
mTitleTextView.setText(
mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
mArtistTextView.setText(
mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
mAlbumArt.setImageBitmap(MusicLibrary.getAlbumBitmap(
MainActivity.this,
mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID)));
}
#Override
public void onSessionDestroyed() {
super.onSessionDestroyed();
}
#Override
public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) {
super.onQueueChanged(queue);
}
}
}
MusicLibrary Class where two sample songs
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaMetadataCompat;
import com.example.android.mediasession.BuildConfig;
import com.example.android.mediasession.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
public class MusicLibrary {
private static final TreeMap<String, MediaMetadataCompat> music = new TreeMap<>();
private static final HashMap<String, Integer> albumRes = new HashMap<>();
private static final HashMap<String, String> musicFileName = new HashMap<>();
static {
createMediaMetadataCompat(
"Jazz_In_Paris",
"Jazz in Paris",
"Media Right Productions",
"Jazz & Blues",
"Jazz",
103,
TimeUnit.SECONDS,
"http://www.noiseaddicts.com/samples_1w72b820/2537.mp3",
R.drawable.album_jazz_blues,
"https://upload.wikimedia.org/wikipedia/en/a/ac/Audioslave_-_Audioslave.jpg");
createMediaMetadataCompat(
"The_Coldest_Shoulder",
"The Coldest Shoulder",
"The 126ers",
"Youtube Audio Library Rock 2",
"Rock",
160,
TimeUnit.SECONDS,
"http://www.noiseaddicts.com/samples_1w72b820/4201.mp3",
R.drawable.album_youtube_audio_library_rock_2,
"https://theflagcompany.in/wp-content/uploads/2018/10/Indian-National-Flag-300x300.jpeg");
}
public static String getRoot() {
return "root";
}
private static String getAlbumArtUri(String albumArtResName) {
return ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
BuildConfig.APPLICATION_ID + "/drawable/" + albumArtResName;
}
public static String getMusicFilename(String mediaId) {
return musicFileName.containsKey(mediaId) ? musicFileName.get(mediaId) : null;
}
private static int getAlbumRes(String mediaId) {
return albumRes.containsKey(mediaId) ? albumRes.get(mediaId) : 0;
}
public static Bitmap getAlbumBitmap(Context context, String mediaId) {
return BitmapFactory.decodeResource(context.getResources(),
MusicLibrary.getAlbumRes(mediaId));
}
public static List<MediaBrowserCompat.MediaItem> getMediaItems() {
List<MediaBrowserCompat.MediaItem> result = new ArrayList<>();
for (MediaMetadataCompat metadata : music.values()) {
result.add(
new MediaBrowserCompat.MediaItem(
metadata.getDescription(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE));
}
return result;
}
public static MediaMetadataCompat getMetadata(Context context, String mediaId) {
MediaMetadataCompat metadataWithoutBitmap = music.get(mediaId);
Bitmap albumArt = getAlbumBitmap(context, mediaId);
// Since MediaMetadataCompat is immutable, we need to create a copy to set the album art.
// We don't set it initially on all items so that they don't take unnecessary memory.
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
for (String key :
new String[]{
MediaMetadataCompat.METADATA_KEY_MEDIA_ID,
MediaMetadataCompat.METADATA_KEY_ALBUM,
MediaMetadataCompat.METADATA_KEY_ARTIST,
MediaMetadataCompat.METADATA_KEY_GENRE,
MediaMetadataCompat.METADATA_KEY_TITLE
}) {
builder.putString(key, metadataWithoutBitmap.getString(key));
}
builder.putLong(
MediaMetadataCompat.METADATA_KEY_DURATION,
metadataWithoutBitmap.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt);
return builder.build();
}
private static void createMediaMetadataCompat(
String mediaId,
String title,
String artist,
String album,
String genre,
long duration,
TimeUnit durationUnit,
String musicFilename,
int albumArtResId,
String albumArtResName) {
music.put(
mediaId,
new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, mediaId)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION,
TimeUnit.MILLISECONDS.convert(duration, durationUnit))
.putString(MediaMetadataCompat.METADATA_KEY_GENRE, genre)
.putString(
MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
getAlbumArtUri(albumArtResName))
.putString(
MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI,
getAlbumArtUri(albumArtResName))
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
.build());
albumRes.put(mediaId, albumArtResId);
musicFileName.put(mediaId, musicFilename);
}
}
I am in the process of completing an android application project I have been working on. The application is a "distributed Marathon" meaning individuals can race against each other while in different locations. However, I am having an issue with some of my code where I will receive the error:
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to double
I have been trying to resolve this issue since last night, but without success, unfortunately.
I will display all the code I think is relevant below, Please let me know if additional code is needed.
Logcat:
2019-04-04 16:41:15.230 29421-29421/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.aladdin.FitHub2019Project, PID: 29421
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to double
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertDouble(com.google.firebase:firebase-database##16.1.0:395)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToPrimitive(com.google.firebase:firebase-database##16.1.0:276)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database##16.1.0:197)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(com.google.firebase:firebase-database##16.1.0:178)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(com.google.firebase:firebase-database##16.1.0:47)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-database##16.1.0:591)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-database##16.1.0:550)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:firebase-database##16.1.0:420)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database##16.1.0:214)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database##16.1.0:79)
at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database##16.1.0:212)
at com.aladdin.FitHub2019Project.userRacePage.UserRaceActivity$1.onDataChange(UserRaceActivity.java:116)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##16.1.0:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##16.1.0:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##16.1.0:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7045)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
in the Logcat, I receive this error directing me to an activity:
at com.aladdin.FitHub2019Project.userRacePage.UserRaceActivity$1.onDataChange(UserRaceActivity.java:116)
The class I am directed to is the race activity users will be racing against eachother on. This class has about 600+ lines of code, but the error I recieve is within the OnCreate - therefore I will only post this section of the code. The comment "//ERROR" is the line I am taken to:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_race);
timer = new Stopwatch();
name=findViewById(R.id.nameTV);
timerTV=findViewById(R.id.timerTV);
distanceTV=findViewById(R.id.distanceTV);
hourET=findViewById(R.id.hourET);
minET=findViewById(R.id.minET);
startBtn=findViewById(R.id.startBtn);
pauseBtn =findViewById(R.id.pauseBtn);
resetBtn=findViewById(R.id.resetBtn);
logoutBtn=findViewById(R.id.logoutBtn);
setTimeBtn=findViewById(R.id.setTimeBtn);
databaseReference= FirebaseDatabase.getInstance().getReference("RunningUsers");
startBtn.setOnClickListener(this);
pauseBtn.setOnClickListener(this);
logoutBtn.setOnClickListener(this);
resetBtn.setOnClickListener(this);
setTimeBtn.setOnClickListener(this);
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
listView=findViewById(R.id.RunningListView);
Query dr=FirebaseDatabase.getInstance().getReference("RunningUsers").orderByChild("totalSec");
dr.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userNameArrayList.clear();userStatusArrayList.clear();userTimerArrayList.clear();userDistanceArrayList.clear();
for (DataSnapshot s:dataSnapshot.getChildren())
{
RunningUserModel rUM=s.getValue(RunningUserModel.class); //ERROR
userNameArrayList.add(rUM.getUserName());
userStatusArrayList.add(rUM.getUserStatus());
userTimerArrayList.add(rUM.getUserTimer());
userDistanceArrayList.add(rUM.getUserDistance());
}
Collections.reverse(userNameArrayList);Collections.reverse(userStatusArrayList);Collections.reverse(userTimerArrayList);
Collections.reverse(userDistanceArrayList);
customAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(),"error while reading",Toast.LENGTH_SHORT).show();
}
});
The code for the RunningUserModel is below:
public class RunningUserModel {
String userName,userStatus,userTimer;
double totalSec;
double userDistance;
public RunningUserModel()
{
}
public RunningUserModel(String userName, String userStatus, String userTimer, double userDistance, double totalSec) {
this.userName = userName;
this.userStatus = userStatus;
this.userTimer = userTimer;
this.userDistance = userDistance;
this.totalSec=totalSec;
}
public String getUserName() {
return userName;
}
public String getUserStatus() {
return userStatus;
}
public String getUserTimer() {
return userTimer;
}
public double getUserDistance() {
return userDistance;
}
public double getTotalSec() {return totalSec; }
}
And here is the CustomAdapter:
import android.app.Activity;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.aladdin.FitHub2019Project.R;
import java.util.ArrayList;
public class CustomAdapterUserRace extends ArrayAdapter{
LayoutInflater layoutInflater;
TextView userNameTV, userStatusTV, userTimerTV, userDistanceTV;
Activity activity;
ArrayList<String> userName =new ArrayList<String>();
ArrayList<String> userStatus =new ArrayList<String>();
ArrayList<String> userTimer =new ArrayList<String>();;
ArrayList<Double> userDistance =new ArrayList<Double>();
public CustomAdapterUserRace(#NonNull Activity activity, ArrayList<String> userName, ArrayList<String>userStatus, ArrayList<String> userTimer, ArrayList<Double> userDistance)
{
super(activity, R.layout.runninglistener, userName);
this.activity=activity;
this.userName =userName;
this.userStatus =userStatus;
this.userTimer =userTimer;
this.userDistance =userDistance;
layoutInflater=activity.getLayoutInflater();
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
convertView=layoutInflater.inflate(R.layout.runninglistener,null);
userNameTV =convertView.findViewById(R.id.userName);
userStatusTV =convertView.findViewById(R.id.userStatus);
userTimerTV =convertView.findViewById(R.id.usertimer);
userDistanceTV =convertView.findViewById(R.id.userDistance);
userNameTV.setText(userName.get(position));
userStatusTV.setText(userStatus.get(position));
userTimerTV.setText(userTimer.get(position));
userDistanceTV.setText(String.valueOf(userDistance.get(position)));
return convertView;
}
}
Firebase Database Structure:
To solve the error, use the following:
Query dr=FirebaseDatabase.getInstance().getReference("RunningUsers").orderByChild("totalSec");
dr.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userNameArrayList.clear();userStatusArrayList.clear();userTimerArrayList.clear();userDistanceArrayList.clear();
RunningUserModel rUM = dataSnapshot.getValue(RunningUserModel.class); //ERROR
userNameArrayList.add(rUM.getUserName());
userStatusArrayList.add(rUM.getUserStatus());
userTimerArrayList.add(rUM.getUserTimer());
userDistanceArrayList.add(rUM.getUserDistance());
Collections.reverse(userNameArrayList);Collections.reverse(userStatusArrayList);Collections.reverse(userTimerArrayList);
Collections.reverse(userDistanceArrayList);
customAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(),"error while reading",Toast.LENGTH_SHORT).show();
}
});
Remove the for loop, since when you are iterating, you are retrieving the fields as type String and not as type RunningUserModel.
I use Android Studio to make an app. I have a file named 'GlobalVariables.java' and this code in it:
public class GlobalVariables extends Application {
public String CallingActivity;
public String getCallVariable() {
return CallingActivity;
}
public void setCallVariable(String Value) {
CallingActivity = Value;
}
}
In the manifest file I have:
<application android:name=".GlobalVariables" .....
I also have a LanguageActivity.java file which has this code:
package com.testApp;
//import android.content.Intent;
//import android.support.v7.app.ActionBarActivity;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class LanguageActivity extends ListActivity {
// public class CountrycodeActivity extends ListActivity {
public static final String TAG = "MyActivity";
// public static String RESULT_CONTRYCODE = "countrycode";
public String[] countrynames;
private TypedArray imgs;
private List<Country> countryList;
Locale myLocale;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
populateCountryList();
ArrayAdapter<Country> adapter = new CountryListArrayAdapter(this, countryList);
setListAdapter(adapter);
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ReadWriteFile RWFile = new ReadWriteFile();
if (position == 0) {
ChangeLanguage("el", getBaseContext());
try {
RWFile.LangWrite("en",getBaseContext());
Log.e(TAG, "LANG === en");
} catch (IOException e) {
e.printStackTrace();
}
}else{
ChangeLanguage("en", getBaseContext());
try {
RWFile.LangWrite("en",getBaseContext());
Log.e(TAG, "LANG === en");
} catch (IOException e) {
e.printStackTrace();
}
}
imgs.recycle(); //recycle images
finish();
}
});
}
private void populateCountryList() {
countryList = new ArrayList<Country>();
countrynames = getResources().getStringArray(R.array.country_names);
//countrycodes = getResources().getStringArray(R.array.country_codes);
imgs = getResources().obtainTypedArray(R.array.country_flags);
for(int i = 0; i < countrynames.length; i++){
countryList.add(new Country(countrynames[i], imgs.getDrawable(i)));
}
}
public class Country {
private String name;
// private String code;
private Drawable flag;
public Country(String name, Drawable flag){
this.name = name;
// this.code = code;
this.flag = flag;
}
public String getName() {
return name;
}
public Drawable getFlag() {
return flag;
}
// public String getCode() {
// return code;
// }
}
public void ChangeLanguage(String value, Context context){
Resources res = context.getResources();
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale(value.toLowerCase());
res.updateConfiguration(conf, dm);
GlobalVariables mApp = ((GlobalVariables)getApplicationContext());
String Activity = mApp.getCallVariable();
if (Activity.equals("Login")){
final Intent intent = new Intent(LanguageActivity.this, LoginActivity.class);
startActivity(intent);
}else if (Activity.equals("Signup")){
final Intent intent = new Intent(LanguageActivity.this, SignupActivity.class);
startActivity(intent);
}
}
}
When I run the code, the app craches with this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
If I change
GlobalVariables mApp = ((GlobalVariables)getApplicationContext());
String Activity = mApp.getCallVariable();
to
String Activity = ((GlobalVariables) this.getApplication()).getCallVariable();
then I get error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.testApp.GlobalVariables.getCallVariable()' on a null object reference
I did many tries but nothing helped. What will solve my problem anyway?
Why do I do this? I want to know which Activity called ChangeLanguage() to restart it to show the selected language.
Dependency injection will solve your problem. If you use dagger2, solve this kind of problem will be better, because will be easier create singletons. If you want i can post here how you can do this. Comment below this answer if you want me to edit this with dagger2 basics.
Add this to the AndroidManifest.xml:
<application
android:name=".GlobalVariables"/>
Try:
public class GlobalVariables extends Application {
public String CallingActivity;
public staric GlobalVariables instance;
#Override
public void onCreate()
{super.onCreate();
this.instance = this;
}
public String getCallVariable() {
return CallingActivity;
}
public void setCallVariable(String Value) {
CallingActivity = Value;
}
public static GlobalVariables getInstance()
{
return instance;
}
}
String Activity = GlobalVariables.getInstance().getCallVariable();
Try replacing the line
GlobalVariables mApp = ((GlobalVariables)getApplicationContext());
with:
GlobalVariables mApp = new GlobalVariables();
And in line :
String Activity = mApp.getCallVariable();
Replace 'Activity' with 'activity' because Activity is a pre-defined word.
Edit 1: IS this is how you tried:
GlobalVariables mApp = GlobalVariables.getInstance();
mApp.setCallVariable(value);
mApp.getCallVariable();
So I have this text on the java-side that arrives from an Intent, which I'd like to save to AsyncStorage to being able to access it through React afterwards.
Any chance I can achieve this?
I have:
package com.myapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.content.Intent;
import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "BrowseItLater", null);
setContentView(mReactRootView);
// This code is from http://developer.android.com/training/sharing/receive.html
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
handleSendText(intent);
}
}
void handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// How can I handle this ????
}
}
// ...
}
Or is there any other solution to make MainActivity.java communicate with JS?
After quite some fight I finally found a solution. It doesn't use AsyncStorage as I read in the source code AsyncStorage could actually be located differently (SQLite, or something else) depending on the phone. Would be dirty to duplicate this logic.
Instead, I created a module like the doc suggests and passed the inputText as an argument to the .addPackage(new EphemeralStoragePackage(inputText)) call in MainActivity.java.
The module exposes a method readOnceAsync to the JS world, which I can later call with:
NativeModules.EphemeralStorage.readOnceAsync((text :string) => {
if (text.length) {
this._addValue(text); // this method is in charge of storing in AsyncStorage
}
})
Here's the detail:
// android/app/src/main/java/com/appname/modules/ephemeralstorage/EphemeralStorageModule.java
package com.browseitlater.modules.ephemeralstorage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import java.util.Map;
public class EphemeralStorageModule extends ReactContextBaseJavaModule {
private String inputText;
public EphemeralStorageModule(ReactApplicationContext reactContext, String _inputText) {
super(reactContext);
this.inputText = _inputText;
}
#Override
public String getName() {
return "EphemeralStorage";
}
public String getInputText() {
return inputText;
}
#ReactMethod
public void readOnceAsync(Callback successCallback) {
successCallback.invoke(getInputText());
this.inputText = null;
}
}
And
// android/app/src/main/java/com/appname/modules/ephemeralstorage/EphemeralStoragePackage.java
package com.browseitlater.modules.ephemeralstorage;
import android.app.Activity;
import java.util.*;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
public class EphemeralStoragePackage implements ReactPackage {
private String inputText;
public EphemeralStoragePackage(String _inputText) {
super();
this.inputText = _inputText;
}
#Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new EphemeralStorageModule(reactContext, getInputText()));
return modules;
}
#Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
#Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
public String getInputText() {
return inputText;
}
}
Finally in MainActivity.java, my onCreate method looks like:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
String inputText = intent.getStringExtra(Intent.EXTRA_TEXT);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new EphemeralStoragePackage(inputText))
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "BrowseItLater", null);
setContentView(mReactRootView);
}
If you don't want to write a native module, you can do this in MainActivity.java
Declare a global variable inside MainActivity class (don't forget to import com.facebook.react.modules.storage.ReactDatabaseSupplier):
private ReactDatabaseSupplier mReactDatabaseSupplier;
Inside onCreatemethod initialize the global variable:
mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(getApplicationContext());
Declare a private method to save the key/value pair inside AsyncStorage
private void saveKeyValuePair(String key, String value) {
String sql = "INSERT OR REPLACE INTO catalystLocalStorage VALUES (?, ?);";
SQLiteStatement statement = mReactDatabaseSupplier.get().compileStatement(sql);
try {
mReactDatabaseSupplier.get().beginTransaction();
statement.clearBindings();
statement.bindString(1, key);
statement.bindString(2, value);
statement.execute();
mReactDatabaseSupplier.get().setTransactionSuccessful();
} catch (Exception e) {
Log.w("YOUR_TAG", e.getMessage(), e);
} finally {
try {
mReactDatabaseSupplier.get().endTransaction();
} catch (Exception e) {
Log.w("YOUR_TAG", e.getMessage(), e);
}
}
}
Then you can save key/value pairs like this (inside onCreate, for example):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(getApplicationContext());
saveKeyValuePair("myAsyncStorageKey", "myValueInAsyncStorageKey");
}
This is a simple way to save in AsyncStorage of a React Native application. Consider writing a native module.