NullPointerException:Attempt toget length of null array [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
i need to create playlist from sdcard when i run my application it generate null pointer exception attempt get length of null array. because it could not read file from sdcard. But i have song files in emulator sdcard folder.Here is the code i have tried but it not work please help me to fix the problem.
class Mp3Filter implements FilenameFilter{
public boolean accept(File dir,String name) {
return (name.endsWith(".mp3"));
}
}
public class Audio extends ListActivity{
private MediaPlayer mp=new MediaPlayer();
private final String SD_PATH=new String("/sdcard/");
private List<String> songs=new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.audio);
updatePlaylist();
Button stpbtn =(Button) findViewById(R.id.stpbtn);
stpbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.stop();
mp.release();
}
});
}
private void updatePlaylist()
{
try
{
File home = new File (SD_PATH);
if(home.listFiles(new Mp3Filter()).length > 0)
{
for(File file:home.listFiles(new Mp3Filter()))
{
songs.add(file.getName());
}
ArrayAdapter<String> songList = new ArrayAdapter<String>(Audio.this,R.layout.song_item,songs);
setListAdapter(songList);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
here is my audio.xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/android:list"
android:layout_width="match_parent"
android:layout_height="401dp" >
</ListView>
<Button
android:id="#+id/stpbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/stpbtn" />
</LinearLayout>
here is song_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView android:id="#+id/text1" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

From the JavaDoc for File.listFiles(FileFilter):
The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.
So you need to check this explicitly.
File home = new File (SD_PATH);
File[] listOfFiles = home.listFiles(new Mp3Filter());
if(listOfFiles != null && listOfFiles.length > 0) {
...
}
And/Or work in a check that the file is in fact a directory:
File home = new File (SD_PATH);
if(!home.isDirectory()) {
// Error case, handle it.
}

Related

Issues with ActivityMainBindingImpl.java

I'm writing a celsius-farenheits converter but the program crashes for something that I didn't found
I'm actually trying to use the data binding and the view model but Android Studio founded some issues in ActivityMainBindingImpl.java that I didn't write by myself. Here's the part of code were it founds a problem. It is in line 104 at com.example.convertitorecelsius_farenheit.MainViewModel viewModel = mViewModel; It says "Cannot resolve symbol 'mViewModel'"
There's another problem in line 33 in "super(bindingComponent, root, 0", it says "'ActivityMainBinding()' has private access in 'com.example.convertitorecelsius_farenheit.databinding.ActivityMainBinding'"
The last problem is at line 8 in "public class ActivityMainBindingImpl extends ActivityMainBinding {", the error is in "ActivityMainBinding", it says "Cannot inherit from final 'com.example.convertitorecelsius_farenheit.databinding.ActivityMainBinding'"
Here's the full code where I founded these problems
package com.example.convertitorecelsius_farenheit.databinding;
import com.example.convertitorecelsius_farenheit.R;
import com.example.convertitorecelsius_farenheit.BR;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.View;
#SuppressWarnings("unchecked")
public class ActivityMainBindingImpl extends ActivityMainBinding {
#Nullable
private static final androidx.databinding.ViewDataBinding.IncludedLayouts sIncludes;
#Nullable
private static final android.util.SparseIntArray sViewsWithIds;
static {
sIncludes = null;
sViewsWithIds = new android.util.SparseIntArray();
sViewsWithIds.put(R.id.cambiaTemperatura, 3);
sViewsWithIds.put(R.id.inputTemperatura, 4);
sViewsWithIds.put(R.id.converti, 5);
}
// views
#NonNull
private final androidx.constraintlayout.widget.ConstraintLayout mboundView0;
// variables
// values
// listeners
// Inverse Binding Event Handlers
public ActivityMainBindingImpl(#Nullable androidx.databinding.DataBindingComponent bindingComponent, #NonNull View root) {
this(bindingComponent, root, mapBindings(bindingComponent, root, 6, sIncludes, sViewsWithIds));
}
private ActivityMainBindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
super(bindingComponent, root, 0
, (android.widget.Button) bindings[3]
, (android.widget.Button) bindings[5]
, (android.widget.EditText) bindings[4]
, (android.widget.TextView) bindings[2]
, (android.widget.TextView) bindings[1]
);
this.mboundView0 = (androidx.constraintlayout.widget.ConstraintLayout) bindings[0];
this.mboundView0.setTag(null);
this.textTemperatura.setTag(null);
this.textView.setTag(null);
setRootTag(root);
// listeners
invalidateAll();
}
#Override
public void invalidateAll() {
synchronized(this) {
mDirtyFlags = 0x2L;
}
requestRebind();
}
#Override
public boolean hasPendingBindings() {
synchronized(this) {
if (mDirtyFlags != 0) {
return true;
}
}
return false;
}
#Override
public boolean setVariable(int variableId, #Nullable Object variable) {
boolean variableSet = true;
if (BR.viewModel == variableId) {
setViewModel((com.example.convertitorecelsius_farenheit.MainViewModel) variable);
}
else {
variableSet = false;
}
return variableSet;
}
public void setViewModel(#Nullable com.example.convertitorecelsius_farenheit.MainViewModel ViewModel) {
this.mViewModel = ViewModel;
synchronized(this) {
mDirtyFlags |= 0x1L;
}
notifyPropertyChanged(BR.viewModel);
super.requestRebind();
}
#Override
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
switch (localFieldId) {
}
return false;
}
#Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
java.lang.String viewModelTypeCurrentTemperature = null;
int viewModelConvertiTemperatura = 0;
com.example.convertitorecelsius_farenheit.MainViewModel viewModel = mViewModel;
if ((dirtyFlags & 0x3L) != 0) {
if (viewModel != null) {
// read viewModel.typeCurrentTemperature
viewModelTypeCurrentTemperature = viewModel.getTypeCurrentTemperature();
// read viewModel.convertiTemperatura()
viewModelConvertiTemperatura = viewModel.convertiTemperatura();
}
}
// batch finished
if ((dirtyFlags & 0x3L) != 0) {
// api target 1
this.textTemperatura.setText(viewModelConvertiTemperatura);
androidx.databinding.adapters.TextViewBindingAdapter.setText(this.textView, viewModelTypeCurrentTemperature);
}
}
// Listener Stub Implementations
// callback impls
// dirty flag
private long mDirtyFlags = 0xffffffffffffffffL;
/* flag mapping
flag 0 (0x1L): viewModel
flag 1 (0x2L): null
flag mapping end*/
//end
}
Here's the program I wrote
MainActivity.java
package com.example.convertitorecelsius_farenheit;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.widget.EditText;
import com.example.convertitorecelsius_farenheit.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private MainViewModel viewModel;
public EditText inputTemperature;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inputTemperature = findViewById(R.id.inputTemperatura);
binding = ActivityMainBinding.inflate(getLayoutInflater());
binding.setLifecycleOwner(this);
setContentView(binding.getRoot());
viewModel = new ViewModelProvider(this).get(MainViewModel.class);
binding.setViewModel(viewModel);
}
public int getInputTemperature() {
return Integer.parseInt(inputTemperature.toString());
}}
MainViewModel.java
package com.example.convertitorecelsius_farenheit;
import androidx.lifecycle.ViewModel;
public class MainViewModel extends ViewModel {
public int grades;
public boolean isCelsius = false;
MainActivity temperaturaInserita = new MainActivity();
//private final MutableLiveData<String> _TypeCurrentTemperatura = new MutableLiveData<>();
private String _TypeCurrentTemperatura = ""; //indicates if the temperature is celsius or farenheit
public String getTypeCurrentTemperature() {
return _TypeCurrentTemperatura;
}
public void changeTypeTemperature() {
if (isCelsius) {
isCelsius = false;
_TypeCurrentTemperatura = "F°";
} else {
isCelsius = true;
_TypeCurrentTemperatura = "C°";
}
}
public int convertiTemperatura() { //convertTemperature (that's the italian name)
if (isCelsius) {
grades = (int) ((temperaturaInserita.getInputTemperature() * 1.8) + 32);
} else {
grades = (int) ((int) ((temperaturaInserita.getInputTemperature()) -32) * .5556);
}
return grades;
}}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.example.convertitorecelsius_farenheit.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="348dp"
android:text="#{viewModel.typeCurrentTemperature}"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/cambiaTemperatura"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="80dp"
android:text="c--f"
app:layout_constraintBottom_toTopOf="#+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="#+id/inputTemperatura"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="52dp"
android:ems="10"
android:inputType="number"
app:layout_constraintBottom_toTopOf="#+id/cambiaTemperatura"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/converti"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="273dp"
android:layout_marginBottom="274dp"
android:text="converti"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/inputTemperatura"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="#+id/textTemperatura"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="23dp"
android:text="#{viewModel.convertiTemperatura()}"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="#+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Can somebody help me :)
There are some things wrong in your code:
You're setting the activity view twice, remove the first line: setContentView(R.layout.activity_main);
Since you're using view binding (different thing from data binding), you dont need to call findViewById replace it with inputTemperature = binding.inputTemperatura
If you're already using data binding why bother with view binding? You can do all input/output related tasks in data binding.
You SHOULD NEVER instantiate ANDROID activities or hold a reference to it, this is task of the Android framework, remove the line MainActivity temperaturaInserita = new MainActivity(); of your viewmodel.
Check this answer it may help you: Android : Difference between DataBinding and ViewBinding
EDIT
You don't need to call methods of your activity from your viewmodel, this is a bad practice, because if the system destroys your activity you will end with a NPE in your view model, you have 2 options:
Use two way data binding to set/get the value of the temperature from the viewmodel: https://bignerdranch.com/blog/two-way-data-binding-on-android-observing-your-view-with-xml/
Change the function in the view model to receive as argument the value of the input text.
I recommend to go with first option, this way you will have the updated value always in your view model and also can survive config changes.
And remember don't matter what, your viewmodel SHOULD never have a reference to the Activity.

Why is my Android ImageView empty (loading up through Uri, Bitmap or using Picasso)

I have a fragment to display a queue of either videos of images. The video I display in the VideoView works fine, it replays, it's golden. But the images I put in the ImageView just appear invisible. I tried loading them through Uri, by reading a Bitmap, now they're set up with Picasso, and none of it fixed it. The AssetObtainer you'll see in MultimediaPlayer works with both sound files and videos so far, so I highly doubt it has an issue with images. Here's the code:
MultimediaPlayer.java :
public class MultimediaPlayer extends Fragment
{
VideoView mVideoView;
ImageView mImageView;
MultimediaViewModel mMultimediaViewModel;
Play mPlayThread;
Activity mActivity;
AssetObtainer assetObtainer = new AssetObtainer();
public Long mTutorialId;
public List<Multimedia> multimedias = new LinkedList<>();
#Override
public View onCreateView(#NotNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_multimedia_player, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
mActivity = requireActivity();
mMultimediaViewModel = new ViewModelProvider(this).get(MultimediaViewModel.class);
mVideoView = view.findViewById(R.id.video_embed);
mImageView = view.findViewById(R.id.image_embed);
getPlayer(0);
}
private void getPlayer(int position)
{
if(mPlayThread != null) {
mPlayThread.interrupt();
position++;
}
if(!multimedias.isEmpty()) {
mPlayThread = new Play(multimedias.get(position));
mPlayThread.start();
}
}
private class Play extends Thread
{
private final Multimedia currentMedia;
Play(Multimedia media){
currentMedia = media;
}
#Override
public void run()
{
int position = currentMedia.getPosition();
int displayTime = currentMedia.getDisplayTime();
boolean loopBool = currentMedia.getLoop();
if(currentMedia.getType()) {
mActivity.runOnUiThread(() -> {
mImageView.setVisibility(View.VISIBLE);
mVideoView.setVisibility(View.GONE);
try {
Picasso.get().load(assetObtainer.getFileFromAssets(requireContext(), currentMedia.getFullFileName())).into(mImageView);
} catch (IOException ignored) {}
});
if(displayTime>0) {
try {
sleep(displayTime);
if(!loopBool) multimedias.remove(currentMedia);
if(position<multimedias.size()-1) {
getPlayer(position);
} else getPlayer(0);
} catch (InterruptedException e) {
mActivity.runOnUiThread(() -> mImageView.setVisibility(View.GONE));
interrupt();
}
}
} else {
mActivity.runOnUiThread(() -> {
mVideoView.setVisibility(View.VISIBLE);
mImageView.setVisibility(View.GONE);
try {
mVideoView.setVideoURI(Uri.fromFile(assetObtainer.getFileFromAssets(requireContext(), currentMedia.getFullFileName())));
} catch (IOException ignored) {}
if(loopBool && multimedias.size()==1) mVideoView.setOnCompletionListener(v->getPlayer(position-1));
mVideoView.start();
});
}
}
}
#Override
public void onPause()
{
if(mPlayThread!=null){
mPlayThread.interrupt();
}
super.onPause();
}
}
bed for the fragment in the activity .xml file :
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/layout_multimedia"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/active_instructions" />
and the .xml file of the fragment :
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".tutorial.mediaplayer.MultimediaPlayer">
<VideoView
android:id="#+id/video_embed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/image_embed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="#string/image_default_no_description" />
</androidx.constraintlayout.widget.ConstraintLayout>
As mentioned, video works super fine, but images won't show. I'd appreciate even monkey wrench suggestions before I have to rework this entirely.
As mentioned in my other answer, it's not related to the ImageView, it's a problem with SQLite and loading a boolean from the database. The default false which I wanted to correspond with video types is default, so it worked, but since it doesn't default to true the image condition wasn't fulfilled. Anyway the ImageView will work once it is actually ran.

Recyclerview disappers when EditText not in Focus

I am making an android app, it has an editText on the top and a recyclerview on the buttom.
Every time when a user hit "enter" in the editText field, I will then make an API call with OKHttp and save the info I needed to a Singleton Class so my adapter can use it and update the list.
However, the recyclerview is not showing(updating) if the focus is not in the editText
"V/ViewRootImpl: The specified message queue synchronization barrier token has not been posted or has already been removed"
It's showing this everytime when I click on the editText, I googled it and found out it might be the thread issues. The only place I interact with thread is the API request I made with okHTTP. However, the request returns and interpret the json file correctly.
public Boolean makeCall (String parameter) throws IOException, UnirestException {
// make the api call
String completedLink = BASE_LINK + parameter;
Future<HttpResponse<com.mashape.unirest.http.JsonNode>> response = Unirest.get("https://mashape-community-urban-dictionary.p.rapidapi.com/define?term=wat")
.header("x-rapidapi-host", "mashape-community-urban-dictionary.p.rapidapi.com")
.header("x-rapidapi-key", "xxxxx")
.asJsonAsync(new Callback<com.mashape.unirest.http.JsonNode>() {
#Override
public void completed(HttpResponse<com.mashape.unirest.http.JsonNode> response) {
// decode the response body
ObjectMapper objectMapper = new ObjectMapper();
JsonNode node = null;
try {
node = objectMapper.readTree(String.valueOf(response.getBody()));
} catch (JsonProcessingException ex) {
ex.printStackTrace();
}
JsonNode resultNode = node.get("list");
List<WordItem> resultList = null;
try {
resultList = objectMapper.readValue(resultNode.toString(),
new TypeReference<List<WordItem>>() {});
} catch (JsonProcessingException ex) {
ex.printStackTrace();
}
SavedInfo.getInstance().setResult(resultList);
}
#Override
public void failed(UnirestException e) {
}
#Override
public void cancelled() {
}
});
return true;
}
Every time when I hit enter on the soft keyboard, my code will start making the API call
mResult.setAdapter(adapter);
mResult.setNestedScrollingEnabled(false);
mResult.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
mResult.setLayoutManager(new LinearLayoutManager(getContext()));
mSearchBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if (i == EditorInfo.IME_ACTION_DONE) {
// show progress bar
hideProgressBar(false, mProgress);
mHomeText.setText(textView.getText());
try {
if (new HttpRequest().makeCall(textView.getText().toString())){
adapter.updateList();
}
else {
// showing error message
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
hideProgressBar(true, mProgress);
// hide keyword when enter key is detected
View view = getActivity().getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
return true;
}
});
Also, one thing to point out is the Progress Bar(I set it to "VISIBLE" but not showing still)is not showing at all. I set a few places throughout my code, the Singleton Class and Http Requests are correct and return + save correct info.
Here is my updateList() in my adapter class just in case this helps
public void updateList () {
list.clear();
list.addAll(SavedInfo.getInstance().getResult());
notifyDataSetChanged();
}
Here is the my layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#F3F3F3"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="#+id/title_word_home"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="36dp"
android:fontFamily="sans-serif"
android:text="#string/home_text"
android:textAlignment="center"
android:textSize="28sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp" />
<EditText
android:id="#+id/searchBox"
android:layout_width="254dp"
android:layout_height="50dp"
android:layout_marginStart="239dp"
android:layout_marginEnd="239dp"
android:autofillHints=""
android:drawableStart="#drawable/ic_search"
android:drawablePadding="10dp"
android:ems="10"
android:hint="#string/searchBox_hint"
android:imeOptions="actionDone"
android:inputType="text"
android:pointerIcon="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_word_home" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="#+id/loading_progress"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center|center_vertical"
android:indeterminate="true"
android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/home_resultList"
android:layout_width="409dp"
android:layout_height="wrap_content"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
Thank you for reading!
The problem occurs because the data posts to recycler view before that has downloaded. You are trying to update the recycler view in the method updateList() which called after the request started but before it completed. That's also why the progress bar doesn't show - it's immediately gone.
In order to fix the problem, you have to trigger updateList() after the data has been downloaded. The good way will be to rewrite the makeCall() method, which accepts the second argument as a callback, so you can update the list.
Define the custom callback:
interface MyCallback {
void completed(List<WordItem> result);
void error(UnirestException error);
}
Rewrite making call a bit:
public void makeCall(String parameter, MyCallback callback) {
// make the api call
String completedLink = BASE_LINK + parameter;
Future<HttpResponse<com.mashape.unirest.http.JsonNode>> response = Unirest.get("https://mashape-community-urban-dictionary.p.rapidapi.com/define?term=wat")
.header("x-rapidapi-host", "mashape-community-urban-dictionary.p.rapidapi.com")
.header("x-rapidapi-key", "xxxxx")
.asJsonAsync(new Callback<com.mashape.unirest.http.JsonNode>() {
#Override
public void completed(HttpResponse<com.mashape.unirest.http.JsonNode> response) {
// decode the response body
ObjectMapper objectMapper = new ObjectMapper();
JsonNode node = null;
try {
node = objectMapper.readTree(String.valueOf(response.getBody()));
} catch (JsonProcessingException ex) {
ex.printStackTrace();
}
JsonNode resultNode = node.get("list");
List<WordItem> resultList = null;
try {
resultList = objectMapper.readValue(resultNode.toString(),
new TypeReference<List<WordItem>>() {});
} catch (JsonProcessingException ex) {
ex.printStackTrace();
}
// SavedInfo.getInstance().setResult(resultList);
callback.completed(resultList);
}
#Override
public void failed(UnirestException e) {
callback.failed(e);
}
#Override
public void cancelled() {
}
});
}
And finally pass the callback to makeCall() and refresh the list:
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if (i == EditorInfo.IME_ACTION_DONE) {
// show progress bar
hideProgressBar(false, mProgress);
// clear your list before call if you wish
// updateList(null);
mHomeText.setText(textView.getText());
new HttpRequest().makeCall(textView.getText().toString(), new MyCallback() {
#Override
public void completed(List<WordItem> result) {
updateList(result);
hideProgressBar(true, mProgress);
}
#Override
public void error(UnirestException error) {
hideProgressBar(true, mProgress);
// showing error message
}
});
// hide keyword when enter key is detected
View view = getActivity().getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
return true;
}
This method should be rewrited as well:
public void updateList(List<WordItem> result) {
list.clear();
if (result != null) list.addAll(result);
notifyDataSetChanged();
}
After that problem should go away and also you have no longer need in the singleton class that holding your data.
By the way, there is the Retrofit library which used in order to make api requests in an easier way. The retrofit is the best practice in the android community, so I suggest to try use it.

How can i fetch Whatsapp user's status and display in my android app?

I want to fetch live status from Whatsapp into my android activity. Is it possible to do this? If yes your guidance will be really appreciated.
Please see the image i want to make an activity containing all the statuses. Just like the image
Thanks
WhatsApp store showed status to your device memory or sd card WhatsApp/Media/.Statuses folder. This folder is hidden. You can fetch data from there.
For Kotlin Lover
companion object {
const val WHATSAPP_STATUS_FOLDER_PATH = "/WhatsApp/Media/.Statuses/"
}
fun getImagePath(): ArrayList<String> {
// image path list
val list: ArrayList<String> = ArrayList()
// fetching file path from storage
val file = File(Environment.getExternalStorageDirectory().toString() + WHATSAPP_STATUS_FOLDER_PATH)
val listFile = file.listFiles()
if (listFile != null && listFile.isNullOrEmpty()) {
Arrays.sort(listFile, LastModifiedFileComparator.LASTMODIFIED_REVERSE)
}
if (listFile != null) {
for (imgFile in listFile) {
if (
imgFile.name.endsWith(".jpg")
|| imgFile.name.endsWith(".jpeg")
|| imgFile.name.endsWith(".png")
) {
val model = imgFile.absolutePath
list.add(model)
}
}
}
// return imgPath List
return list
}
There You Go
final String WHATSAPP_STATUSES_LOCATION = "/WhatsApp/Media/.Statuses";
RecyclerView mRecyclerViewMediaList = findViewById(R.id.recyclerViewMedia);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
mRecyclerViewMediaList.setLayoutManager(mLinearLayoutManager);
ListAdapter recyclerViewMediaAdapter = new ListAdapter(MainActivity.this, this.getListFiles(new File(Environment.getExternalStorageDirectory().toString() + WHATSAPP_STATUSES_LOCATION)));
mRecyclerViewMediaList.setAdapter(recyclerViewMediaAdapter);
private ArrayList<File> getListFiles(File parentDir) {
ArrayList<File> inFiles = new ArrayList<>();
File[] files;
files = parentDir.listFiles();
if (files != null) {
for (File file : files) {
Log.e("check", file.getName());
if (file.getName().endsWith(".jpg") ||
file.getName().endsWith(".gif") ||
file.getName().endsWith(".mp4")) {
if (!inFiles.contains(file))
inFiles.add(file);
}
}
}
return inFiles;
}
Adapter
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.MyViewHolder> {
final Context context;
final ArrayList<File> modelFeedArrayList;
private static final String DIRECTORY_TO_SAVE_MEDIA_NOW = "/WhatsappStatus/";
public ListAdapter(Context context, final ArrayList<File> modelFeedArrayList) {
this.context = context;
this.modelFeedArrayList = modelFeedArrayList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_media_row_item, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, int position) {
File currentFile = modelFeedArrayList.get(position);
if (currentFile.getAbsolutePath().endsWith(".mp4")) {
holder.cardViewImageMedia.setVisibility(View.GONE);
holder.cardViewVideoMedia.setVisibility(View.VISIBLE);
Uri video = Uri.parse(currentFile.getAbsolutePath());
holder.videoViewVideoMedia.setVideoURI(video);
holder.videoViewVideoMedia.setOnPreparedListener(mp -> {
mp.setLooping(true);
holder.videoViewVideoMedia.start();
});
} else {
holder.cardViewImageMedia.setVisibility(View.VISIBLE);
holder.cardViewVideoMedia.setVisibility(View.GONE);
Bitmap myBitmap = BitmapFactory.decodeFile(currentFile.getAbsolutePath());
holder.imageViewImageMedia.setImageBitmap(myBitmap);
}
}
#Override
public int getItemCount() {
return modelFeedArrayList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageViewImageMedia;
VideoView videoViewVideoMedia;
CardView cardViewVideoMedia;
CardView cardViewImageMedia;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
imageViewImageMedia = itemView.findViewById(R.id.imageViewImageMedia);
videoViewVideoMedia = itemView.findViewById(R.id.videoViewVideoMedia);
cardViewVideoMedia = itemView.findViewById(R.id.cardViewVideoMedia);
cardViewImageMedia = itemView.findViewById(R.id.cardViewImageMedia);
}
}
}
Row XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_margin="10dp">
<androidx.cardview.widget.CardView
android:id="#+id/cardViewVideoMedia"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:visibility="gone">
<VideoView
android:id="#+id/videoViewVideoMedia"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="#+id/cardViewImageMedia"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true">
<ImageView
android:id="#+id/imageViewImageMedia"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_weight="1"
android:scaleType="fitCenter"
android:contentDescription="#string/todo" />
</androidx.cardview.widget.CardView>
</RelativeLayout>
add to your AndroidManifest.xml.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:requestLegacyExternalStorage="true"
Android 10 File.listFiles() may return null, see File exists and IS directory, but listFiles() returns null
Well all the content of WhatsApp user status are locally stored in /WhatsApp/.Statuses folder except text Statuses. You can simply load all the images and videos that are in the folder in grid view and give options to save and share.
Problem of path and file not found solved with this.
You can try this Path. it may be helpful for you.
For Android-10 and above
File(Environment.getExternalStorageDirectory() + File.separator + "Android/media/com.whatsapp/WhatsApp/Media/.Statuses")
Below Android-10 Version
File(Environment.getExternalStorageDirectory() + File.separator + "WhatsApp/Media/.Statuses")

Choose where to save a file in android [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I have an object("jsonized" to a string) and I want to save it in a file.
Also, I want that a dialogbox shows up allowing the user to pick up the folder where the file will be saved.
(I was writing this question when, suddenly, the solution hit me. Just sharing my solution to get feedback of better ways to do this)
When the "Save File" button is clicked, it launches "selectFolder()" function
Activity.java
public void selectFolder(){
// Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// Chain together various setter methods to set the dialog characteristics
builder.setTitle("Choose folder to save profile");
// Get the layout inflater
LayoutInflater inflater = this.getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.dialog_selectfolder, null);
ListView lvDirectories = (ListView) dialogView.findViewById(R.id.lvDirectories);
String path = Environment.getExternalStorageDirectory().toString();
((TextView) dialogView.findViewById(R.id.tvJamesBond)).setText(path);
final ArrayList<String> items = listFolders(path);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
lvDirectories.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String dest = ((ListView) dialogView.findViewById(R.id.lvDirectories)).getItemAtPosition(i).toString().trim();
String path;
if(dest.compareTo("...")==0){
int lastSlash = ((TextView) dialogView.findViewById(R.id.tvJamesBond)).getText().toString().lastIndexOf("/");
path = ((TextView) dialogView.findViewById(R.id.tvJamesBond)).getText().toString().substring(0,lastSlash);
}
else{
path = ((TextView) dialogView.findViewById(R.id.tvJamesBond)).getText().toString() + "/" + dest;
}
items.clear();
items.addAll(listFolders(path));
((TextView) dialogView.findViewById(R.id.tvJamesBond)).setText(path);
adapter.notifyDataSetChanged();
}
});
lvDirectories.setAdapter(adapter);
adapter.notifyDataSetChanged();
builder.setView(dialogView);
// Add the buttons
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
saveProfile(((TextView) dialogView.findViewById(R.id.tvJamesBond)).getText().toString());
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Toast toast = Toast.makeText(getApplicationContext(), "Nothing saved", Toast.LENGTH_SHORT);
toast.show();
}
});
// Get the AlertDialog from create()
AlertDialog dialog = builder.create();
dialog.show();
}
public ArrayList<String> listFolders(String path){
ArrayList<String> result = new ArrayList<String>();
File f = new File(path);
File[] files = f.listFiles();
Log.d("TEST PATH1", path);
Log.d("TEST PATH1", Environment.getExternalStorageDirectory().toString());
if(path.compareTo(Environment.getExternalStorageDirectory().toString())!=0){
result.add("...");
}
for (File inFile : files) {
if (inFile.isDirectory()) {
result.add(inFile.getName());
}
}
return result;
}
public void saveProfile(String folder){
String fileName = "default.txt";
try{
String ob = new Gson().toJson(((MyApplication)getApplication()).getProfile());
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(folder+"/"+fileName));
outputStreamWriter.write(ob);
outputStreamWriter.close();
}
catch(IOException ex){
Log.e("SAVE_FILE", ex.toString());
}
Toast toast = Toast.makeText(getApplicationContext(), "Profile saved to file '"+fileName+"'", Toast.LENGTH_SHORT);
toast.show();
}
dialog_selectfolder.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lvDirectories"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
android:text="New Text"
android:id="#+id/tvJamesBond"
android:layout_gravity="center_horizontal" />
</LinearLayout>

Categories