I want to display a Google Map on half screen of my profile view. In my onCreate method I created a new instance of an AsyncTask to retrieve latitude and longitude from Google servers via JSON. After receiving the result, I call:
GoogMapHandler gmh = new GoogMapHandler(fragmentManager, applicationContext);
gmh.initilizeMap(coord, "Username", "addressInfo");
Here is my GoogMapHandler class:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.content.Context;
import android.widget.Toast;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import com.google.android.gms.internal.fm;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class GoogMapHandler {
// Google Map
private GoogleMap googleMap;
private android.support.v4.app.FragmentManager fragmentManager;
private Context applicationContext;
public GoogMapHandler(FragmentManager fmanager, Context applicationContext) {
this.fragmentManager = fmanager;
this.applicationContext = applicationContext;
}
public void initilizeMap(LatLng coord, String username, String addrInfo) {
if (googleMap == null) {
Fragment fragment = this.fragmentManager.findFragmentById(R.id.map);
FragmentTransaction fragTransaction = this.fragmentManager
.beginTransaction();
fragTransaction.detach(fragment);
SupportMapFragment supportmapfragment = (SupportMapFragment) fragment;
googleMap = supportmapfragment.getMap();
if (googleMap == null) {
Toast.makeText(applicationContext,
"Sorry! Unable to create map.", Toast.LENGTH_SHORT)
.show();
} else {
Marker loc = googleMap.addMarker(new MarkerOptions()
.position(coord).title("User: " + username)
.snippet(addrInfo));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(coord,
15));
fragTransaction.attach(fragment);
fragTransaction.commit();
}
}
}
}
Now the problem is, that I can't see the map, although I get no errors. As the View is already created, I tried to to "redraw" the fragment to display the map, but it's not working.
How can I achieve this?
Any help would be greatly appreciated.
EDIT:
Here is my ProfileActivity. As suggested, I used onResume to create the AsyncTask.
public class ProfileActivity extends BaseActivity {
private String username, address, postalCode, country;
#Override
protected void onResume() {
Log.i("URL",
"http://maps.googleapis.com/maps/api/geocode/json?address="
+ address.replaceAll("\\s+", "+") + ",+" + postalCode
+ ",+" + country + "&sensor=false");
new LocationTask(getSupportFragmentManager(),
getApplicationContext())
.execute("http://maps.googleapis.com/maps/api/geocode/json?address="
+ address.replaceAll("\\s+", "+")
+ ",+"
+ postalCode
+ ",+" + country + "&sensor=false");
super.onResume();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
Intent intent = getIntent();
username = intent.getStringExtra(SearchResultsActivity.USERNAME);
if (username != null) {
setTitle("User: " + username);
}
address = intent.getStringExtra(SearchResultsActivity.ADDRESS);
postalCode = intent
.getStringExtra(SearchResultsActivity.POSTALCODE);
country = intent.getStringExtra(SearchResultsActivity.COUNTRY);
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(username);
setContentView(textView);
}
}
Profile Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/map_frame"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.2" >
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="fill_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</FrameLayout>
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="TextView" />
</LinearLayout>
Location Task:
public class LocationTask extends
AsyncTask<String, String, StringBuilder> {
private EditText address = null;
private EditText postalCode = null;
private EditText country = null;
private Context applicationContext;
private FragmentManager fragmentManager;
private LatLng coord;
public LocationTask(FragmentManager fmanager,
Context applicationContext) {
this.fragmentManager = fmanager;
this.applicationContext = applicationContext;
}
#Override
protected StringBuilder doInBackground(String... params) {
HttpGet httpGet = new HttpGet(params[0]);
HttpClient client = new DefaultHttpClient();
HttpResponse response;
try {
response = client.execute(httpGet);
StringBuilder stringBuilder = new StringBuilder();
try {
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return stringBuilder;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(StringBuilder result) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject = new JSONObject(result.toString());
} catch (JSONException e) {
e.printStackTrace();
}
String postal_code = null;
String street_address = null;
String country = null;
try {
String status = jsonObject.getString("status").toString();
if (status.equalsIgnoreCase("OK")) {
JSONArray results = jsonObject.getJSONArray("results");
JSONObject r = results.getJSONObject(0);
JSONArray addressComponentsArray = r
.getJSONArray("address_components");
JSONObject geometry = r.getJSONObject("geometry");
JSONObject locationObj = geometry.getJSONObject("location");
coord = new LatLng(locationObj.getDouble("lat"), locationObj.getDouble("lng"));
}
} catch (JSONException e) {
e.printStackTrace();
}
GoogMapHandler gmh = new GoogMapHandler(fragmentManager, applicationContext);
gmh.initilizeMap(coord, "Username", "addressInfo");
}
}
I forgot to remove this in my ProfileActivity:
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(username);
setContentView(textView);
Removing it, solved my problem.
I cannot comment
Are you sure your code is going inside the IF block:
public void initilizeMap(LatLng coord, String username, String addrInfo) {
if (googleMap == null) {
//are you getting upto here?
....
}
}
If SupportMapFragment is declared in your layout, I don't think detach will do anything meaningful here. The following should work:
public void initilizeMap(LatLng coord, String username, String addrInfo) {
if (googleMap == null) {
Fragment fragment = this.fragmentManager.findFragmentById(R.id.map);
SupportMapFragment supportmapfragment = (SupportMapFragment) fragment;
googleMap = supportmapfragment.getMap();
if (googleMap == null) {
Toast.makeText(applicationContext,
"Sorry! Unable to create map.", Toast.LENGTH_SHORT)
.show();
} else {
Marker loc = googleMap.addMarker(new MarkerOptions()
.position(coord).title("User: " + username)
.snippet(addrInfo));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(coord, 15));
}
} else {
Marker loc = googleMap.addMarker(new MarkerOptions()
.position(coord).title("User: " + username)
.snippet(addrInfo));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(coord, 15));
}
If the above is not working, the problem is unlikely to be in the block of code, rather, it's probably getting called before map is ready.
Please give us more info; tell us whether the AsyncTask may be returning the results before onResume() is being called.
Related
I'm making a simple program where I can get a content from JSON in this url
https://www.haliminfo.com/feeds/posts/summary/?max-results=10&start-index=1&alt=json
and make it a list Using RecyclerView on Android.
I have made several necessary components such as Model, Adapter, Post Row Item and HttpHandler
when I try RecyclerView with a method like this it works.
private void addData () {
postsArrayList = new ArrayList <> ();
postsArrayList.add (new Posts ("TITLE", "SUMMARY"));
}
but when I apply the method below nothing appears in the activity
private class getContent extends AsyncTask <Void, Void, Void> {
# Override
protected Void doInBackground (Void ... voids) {
HttpHandler sh = new HttpHandler ();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall (URL_FIX);
if (jsonStr! = null) {
try {
JSONObject jsonObj = new JSONObject (jsonStr);
JSONObject feed = jsonObj.getJSONObject ("feed");
JSONArray entry = feed.getJSONArray ("entry");
Posts postsModel = new Posts ();
for (int i = 0; i <entry.length (); i ++) {
postsModel.setTitle (entry.getJSONObject (i) .getJSONObject ("title"). getString ("$ t"));
postsModel.setSummary (entry.getJSONObject (i) .getJSONObject ("summary"). getString ("$ t"));
postsArrayList.add (postsModel);
}
} catch (final JSONException e) {
Log.e ("RESPONSE", "Json parsing error:" + e.getMessage ());
runOnUiThread (new Runnable () {
# Override
public void run () {
Toast.makeText (getApplicationContext (),
"Json parsing error:" + e.getMessage (),
Toast.LENGTH_LONG)
.show ();
}
});
}
} else {
Log.e ("RESPONSE", "Couldn't get json from server.");
runOnUiThread (new Runnable () {
# Override
public void run () {
Toast.makeText (getApplicationContext (),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show ();
}
});
}
return null;
}
}
this is a full file of some important files in my project
MainActivity.java
package com.badjing.bloggercoba.activities;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.badjing.bloggercoba.R;
import com.badjing.bloggercoba.adapter.PostRecyclerViewAdapter;
import com.badjing.bloggercoba.config.Config;
import com.badjing.bloggercoba.handler.HttpHandler;
import com.badjing.bloggercoba.model.Posts;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private PostRecyclerViewAdapter postAdapter;
private ArrayList<Posts> postsArrayList;
private ProgressDialog pDialog;
private Config config = new Config();
String URL_FIX = Config.BLOG_URL + Config.BLOG_URL_MAX_RESULT + Config.MAX_RESULT + config.BLOG_URL_START_INDEX + config.START_INDEX + config.BLOG_URL_ALT_TYPE;;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
postsArrayList = new ArrayList<>();
new getContent().execute();
recyclerView = (RecyclerView) findViewById(R.id.post_recycle_view);
postAdapter = new PostRecyclerViewAdapter(postsArrayList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(postAdapter);
}
// private void addData() {
//
// postsArrayList = new ArrayList<>();
// postsArrayList.add(new Posts("JUDUL", "SUMMARY"));
//
// }
private class getContent extends AsyncTask<Void, Void, Void> {
// #Override
// protected void onPreExecute() {
// super.onPreExecute();
// // Showing progress dialog
// pDialog = new ProgressDialog(MainActivity.this);
// pDialog.setMessage("Please wait...");
// pDialog.setCancelable(false);
// pDialog.show();
// }
#Override
protected Void doInBackground(Void... voids) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(URL_FIX);
if (jsonStr != null) {
try{
JSONObject jsonObj = new JSONObject(jsonStr);
JSONObject feed = jsonObj.getJSONObject("feed");
JSONArray entry = feed.getJSONArray("entry");
Posts postsModel = new Posts();
for (int i = 0; i < entry.length(); i++) {
postsModel.setTitle(entry.getJSONObject(i).getJSONObject("title").getString("$t"));
postsModel.setSummary(entry.getJSONObject(i).getJSONObject("summary").getString("$t"));
postsArrayList.add(postsModel);
}
} catch (final JSONException e) {
Log.e("RESPONSE", "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e("RESPONSE", "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
}
private void urlBuilder() {
URL_FIX = Config.BLOG_URL + Config.BLOG_URL_MAX_RESULT + 10 + config.BLOG_URL_START_INDEX + 1 + config.BLOG_URL_ALT_TYPE;
}
}
Post.java (post model)
package com.badjing.bloggercoba.model;
public class Posts {
String title;
String summary;
public Posts() {
}
public Posts(String title, String summary) {
this.title = title;
this.summary = summary;
}
public String getTitle() {
return title;
}
public String getSummary() {
return summary;
}
public void setTitle(String title) {
this.title = title;
}
public void setSummary(String summary) {
this.summary = summary;
}
}
PostRecyclerViewAdapter.java
package com.badjing.bloggercoba.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.badjing.bloggercoba.R;
import com.badjing.bloggercoba.model.Posts;
import java.util.ArrayList;
public class PostRecyclerViewAdapter extends RecyclerView.Adapter<PostRecyclerViewAdapter.MyViewHolder> {
private ArrayList<Posts> postsList;
public PostRecyclerViewAdapter(ArrayList<Posts> postsArrayList) {
this.postsList = postsArrayList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.post_row_item, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.blog_post_title.setText(postsList.get(position).getTitle());
holder.blog_post_sumary.setText(postsList.get(position).getSummary());
}
#Override
public int getItemCount() {
return (postsList!= null) ? postsList.size() : 0;
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView blog_post_title, blog_post_sumary, blog_post_author;
ImageView img_thumbnail;
public MyViewHolder(View itemView) {
super(itemView);
blog_post_title = itemView.findViewById(R.id.blog_post_title);
blog_post_sumary = itemView.findViewById(R.id.blog_post_sumary);
// blog_post_author = itemView.findViewById(R.id.blog_post_author);
// img_thumbnail = itemView.findViewById(R.id.post_thumbnail);
}
}
}
post_row_item.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="250dp"
android:layout_marginTop="5dp"
android:padding="8dp"
android:background="#fff">
<ImageView
android:id="#+id/post_thumbnail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/loading_shape"></ImageView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="230dp"
android:orientation="vertical"
android:layout_margin="8dp" >
<TextView
android:id="#+id/blog_post_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blog post title"
android:textSize="20dp"
android:textStyle="bold"/>
<TextView
android:id="#+id/blog_post_sumary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blog post summary"/>
<TextView
android:id="#+id/blog_post_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="~ author"/>
</LinearLayout>
</LinearLayout>
thank you for your attention and help.
I am new to Android development, trying to create my own app. It should display a particular YouTube Channel by using the YouTube Data API. I have started with the standard bottom navigation template in Android Studio and used the following project on Github for some start-up help. https://github.com/stressGC/Remake-YouTube-Android
I had to change a few things like the deprecated http call inside the code to keep it running with the new Android APKs. Everything seems fine from my point of view: I can see that the API content looks good and that each title / description / publishdate is placed in the according variables. There is also no error message in the log. When I start the emulator, the app is running fine. But as soon as I switch to the "Dashboard" fragment (where the code is placed), it is empty.
DashboardFragment.java
public class DashboardFragment extends Fragment {
private static String API_KEY = "hidden"; //normaler API key ohne limits, kein oauth
private static String CHANNEL_ID = "hidden";
private static String CHANNEL_GET_URL = "https://www.googleapis.com/youtube/v3/search?part=snippet&order=date&channelId="+CHANNEL_ID+"&maxResults=20&key="+API_KEY+"";
private RecyclerView mList_videos = null;
private VideoPostAdapter adapter = null;
private ArrayList<YouTubeDataModel> mListData = new ArrayList<>();
public DashboardFragment () {
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
mList_videos = (RecyclerView) view.findViewById(R.id.mList_videos);
initList(mListData);
new RequestYouTubeAPI().execute();
return view;
}
private void initList(ArrayList<YouTubeDataModel> mListData) {
mList_videos.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new VideoPostAdapter(getActivity(), mListData);
mList_videos.setAdapter(adapter);
}
// create asynctask to get data from youtube
private class RequestYouTubeAPI extends AsyncTask<Void, String, String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
URL url = null;
String json = null;
StringBuffer sb = new StringBuffer();
try {
url = new URL(CHANNEL_GET_URL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
//HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
HttpURLConnection urlConnection = NetCipher.getHttpsURLConnection(url);
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String inputLine = "";
while ((inputLine = br.readLine()) != null) {
sb.append(inputLine);
}
json = sb.toString();
return json;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if(response != null){
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
public ArrayList<YouTubeDataModel> parseVideoListFromResponse(JSONObject jsonObject) {
ArrayList<YouTubeDataModel> mList = new ArrayList<>();
if (jsonObject.has("items")) {
try {
JSONArray jsonArray = jsonObject.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
if (json.has("id")) {
JSONObject jsonID = json.getJSONObject("id");
String video_id = "";
if (jsonID.has("videoId")) {
video_id = jsonID.getString("videoId");
}
if (jsonID.has("kind")) {
if (jsonID.getString("kind").equals("youtube#video")) {
YouTubeDataModel youtubeObject = new YouTubeDataModel();
JSONObject jsonSnippet = json.getJSONObject("snippet");
String title = jsonSnippet.getString("title");
String description = jsonSnippet.getString("description");
String publishedAt = jsonSnippet.getString("publishedAt");
String thumbnail = jsonSnippet.getJSONObject("thumbnails").getJSONObject("high").getString("url");
youtubeObject.setTitle(title);
youtubeObject.setDescription(description);
youtubeObject.setPublishedAt(publishedAt);
youtubeObject.setThumbnail(thumbnail);
youtubeObject.setVideo_id(video_id);
mList.add(youtubeObject);
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return mList;
}
}
VideoPostAdapter.java
public class VideoPostAdapter extends RecyclerView.Adapter<VideoPostAdapter.YouTubePostHolder> {
private ArrayList<YouTubeDataModel> dataSet;
private Context mContext = null;
public VideoPostAdapter(Context mContext, ArrayList<YouTubeDataModel> dataSet) {
this.dataSet = dataSet;
this.mContext = mContext;
}
#NonNull
#Override
public YouTubePostHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.youtube_post_layout,parent,false);
YouTubePostHolder postHolder = new YouTubePostHolder(view);
return postHolder;
}
#Override
public void onBindViewHolder(#NonNull YouTubePostHolder holder, int position) {
// set the views here
TextView textViewTitle = holder.textViewTitle;
TextView textViewDes = holder.textViewDes;
TextView textViewDate = holder.textViewDate;
ImageView ImageThumb = holder.ImageThumb;
YouTubeDataModel object = dataSet.get(position);
textViewTitle.setText(object.getTitle());
textViewDes.setText(object.getDescription());
textViewDate.setText(object.getPublishedAt());
// image will be downloaded from url
}
#Override
public int getItemCount() {
return dataSet.size();
}
public static class YouTubePostHolder extends RecyclerView.ViewHolder{
TextView textViewTitle;
TextView textViewDes;
TextView textViewDate;
ImageView ImageThumb;
public YouTubePostHolder(#NonNull View itemView) {
super(itemView);
this.textViewTitle = (TextView) itemView.findViewById(R.id.textViewTitle);
this.textViewDes = (TextView) itemView.findViewById(R.id.textViewDes);
this.textViewDate = (TextView) itemView.findViewById(R.id.textViewDate);
this.ImageThumb = (ImageView) itemView.findViewById(R.id.ImageThumb);
}
}
}
YouTubeDataModel.java
public class YouTubeDataModel {
private String title = "";
private String description = "";
private String publishedAt = "";
private String thumbnail = "";
public String getVideo_id() {
return video_id;
}
public void setVideo_id(String video_id) {
this.video_id = video_id;
}
private String video_id = "";
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getThumbnail() {
return thumbnail;
}
public void setThumbnail(String thumbnail) {
this.thumbnail = thumbnail;
}
}
youtube_post_layout.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="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<ImageView
android:id="#+id/ImageThumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"/>
<TextView
android:id="#+id/textViewDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="published at"
android:singleLine="true"
android:layout_alignParentRight="true"
android:layout_margin="5dp"
android:textColor="#android:color/white"
android:textSize="12dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="10dp"
android:orientation="vertical">
<TextView
android:id="#+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="video Title"
android:singleLine="true"
android:textColor="#android:color/white"
android:textSize="22dp"/>
<TextView
android:id="#+id/textViewDes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="video description"
android:singleLine="true"
android:textColor="#android:color/white"
android:textSize="12dp"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
fragment_dashboard.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mList_videos"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Unfortunately I have no idea why the fragment is still empty. And without any error in Android Studio log I really hope you can help me :/
Inside your RequestYouTubeAPI ASyncTask you have this error code:
} catch (IOException e) {
e.printStackTrace();
return null;
}
Then in onPostExecute you have the following:
#Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if(response != null){
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Therefore if you get an error, you return null and if onPostExecute is given a null response it does nothing.
So this one place you could have an error and therefore a blank fragment.
Before you fix this, you can prove this is happening like so:
#Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if(response == null){
Log.e("TUT", "We did not get a response, not updating the UI.");
} else {
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
You can fix this two ways:
in doInBackground change the catch to this:
} catch (IOException e) {
Log.e("TUT", "error", e);
// Change this JSON to match what the parse expects, so you can show an error on the UI
return "{\"yourJson\":\"error!\"}";
}
or onPostExecute:
if(response == null){
List errorList = new ArrayList();
// Change this data model to show an error case to the UI
errorList.add(new YouTubeDataModel("Error");
mListData = errorList;
initList(mListData);
} else {
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("response", jsonObject.toString());
mListData = parseVideoListFromResponse(jsonObject);
initList(mListData);
//adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
Hope that helps, there may be other errors in the code but this is one case that can happen if there is a problem with the API, the Json, the authorization, the internet etc.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
Hi I am learning Android App Development. For this, I wanted to make myself a simple wallpaper app. Hence, I wrote something roughly which is presented here. I want to get wallpaper urls from json. Unfortunately, I am unable to get data from my server. java.lang.NullPointerException: Attempt to read from null array
How do I get the data correctly from the jsonParse asynctask?
I am stuck on this the whole day. What could have gone wrong here?
Here is my code:
myjson.json:
{
"walls":[
{"ourUrl":"http://www.hdbloggers.net/wp-content/uploads/2016/01/Wallpapers-for-Android.jpg"},
{"ourUrl":"http://androidwallpape.rs/content/02-wallpapers/131-night-sky/wallpaper-2707591.jpg"},
{"ourUrl":"http://androidwallpape.rs/content/02-wallpapers/155-starrynight/starry-night-sky-star-galaxy-space-dark-9-wallpaper.jpg"}
]
}
MainActivity.java:
package regalstreak.me.wallpapers;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
public class MainActivity extends Activity {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
RecyclerView.Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerAdapter(this);
recyclerView.setAdapter(adapter);
}
}
RecyclerAdapter.java:
package regalstreak.me.wallpapers;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
// This is a recycleradapter which will set the correct images to the correct position in the recyclerview.
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private Context myCtx1;
String[] arr;
String[] arrurl;
String jsonURL = "http://dev.regalstreak.me/myjson.json";
public RecyclerAdapter(Context ctx) {
this.myCtx1 = ctx;
}
public ImageView Image;
private String[] mText = {
"Text 1",
"Text 2",
"Text 3"
};
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView Text;
public ViewHolder(View itemView) {
super(itemView);
Image = (ImageView) itemView.findViewById(R.id.image_view);
Text = (TextView) itemView.findViewById(R.id.text_view);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.wallpapers_list, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.Text.setText(mText[i]);
new jsonParse().execute();
new DownloadImageTask(Image).execute(arrurl[i]);
}
#Override
public int getItemCount() {
return mText.length;
}
class jsonParse extends AsyncTask<String, Void, String[]> {
protected String[] doInBackground(String[] urls) {
String myText = null;
String url = urls[0];
String ourUrl;
try {
InputStream in = new java.net.URL(jsonURL).openStream();
myText = IOUtils.toString(in, "utf-8");
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
// Parse the json
List<String> allUrls = new ArrayList<String>();
JSONObject jsonObjectRoot = new JSONObject(myText);
JSONArray jsonArray = jsonObjectRoot.getJSONArray("walls");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
ourUrl = jsonObject.getString("ourUrl");
allUrls.add(ourUrl);
}
arr = allUrls.toArray(new String[allUrls.size()]);
} catch (JSONException e) {
e.printStackTrace();
}
return arr;
}
protected void onPostExecute(String[] result){
arrurl = result;
}
}
}
DownloadImageTask.java:
package regalstreak.me.wallpapers;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
import java.io.InputStream;
// Here, we will download the wallpapers obtained from jsonData with an asynctask.
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap>{
ImageView bmImage;
public DownloadImageTask(ImageView bmImage){
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
in.close();
} catch (Exception e) {
Log.e("Error getting images.", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result){
bmImage.setImageBitmap(result);
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="regalstreak.me.wallpapers.MainActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_view" />
</RelativeLayout>
wallpaper_list.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relative"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp">
<ImageView
android:id="#+id/image_view"
android:layout_width="match_parent"
android:layout_height="150dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/image_view"
android:alpha="0.6"
android:background="#color/colorDivider"
android:padding="9dp">
<TextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textColor="#color/colorPrimaryText" />
</RelativeLayout>
</RelativeLayout>
I have used HttpURLConnection class here for quick response and features like cache. The data received from the URL is being added to an input stream which we then convert to a String builder to get a string object which we can further use with the JSON classes.
PS - Add the AsyncTask code to your MainActivity itself, don't make a separate java file for this.
Tip - Always verify the json using this tool - jsonlint.com
MainActivity
/*
your code
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
new MyAsyncTask().execute("");
}
class MyAsyncTask extends AsyncTask<String, String, Void> {
private ProgressDialog progressDialog = new ProgressDialog(StartScreen.this);
InputStream inputStream = null;
String result = "";
ArrayList<String> list;
protected void onPreExecute() {
progressDialog.setTitle("Downloading JSON Data");
progressDialog.show();
// above code makes a dialog with a progress bar
}
#Override
protected Void doInBackground(String... params) {
ArrayList<String> param = new ArrayList<String>();
URL url, url2;
try{
url = new URL("http://dev.regalstreak.me/myjson.json");
// link to your json file
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setUseCaches(false);
inputStream = new BufferedInputStream(urlConnection.getInputStream());
}catch (MalformedURLException malle){
Log.e("Mal", ""+malle);
malle.printStackTrace();
}catch (IOException ioe){
Log.e("IO", ""+ioe);
ioe.printStackTrace();
}
// Convert response to string using String Builder
try {
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"), 8);
StringBuilder sBuilder = new StringBuilder();
String line = null;
while ((line = bReader.readLine()) != null) {
sBuilder.append(line + "\n");
}
inputStream.close();
result = sBuilder.toString();
} catch (Exception e) {
Log.e("StringBuilding", "Error converting result " + e.toString());
}
return null;
}
protected void onPostExecute(Void v) {
//parse JSON data
try {
JSONObject jobj = new JSONObject(result);
//Taking a JSON Array from the JSONObject created above
String url = jobj.getString("ourUrl");
// We are adding this string to the ArrayList
list.add(url);
progressDialog.dismiss();
Context con = ListLoader.this.getApplication();
adapter = new RecyclerAdapter(list,con);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
Log.e("JSONException", "Error: " + e.toString());
} // catch (JSONException e)
}
}
/*
your code
*/
Now to display the images more effectively in the list, use the repo Universal image loader. It has a lot of features. You can get it here - https://github.com/nostra13/Android-Universal-Image-Loader
And then add this kind of code to display the images. Put it inside the onBindViewHolder
Adapter
#Override
public void onBindViewHolder(DataHolder holder, int position) {
ImageLoaderConfiguration config;
config = new ImageLoaderConfiguration.Builder(mContext).build();
ImageLoader.getInstance().init(config);
imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_error_black_48dp) // displays this image not found
.showImageOnFail(R.drawable.ic_error_black_48dp) // Displays this on failure
.showImageOnLoading(R.drawable.white) // Displays while loading
.cacheInMemory(false)
.cacheOnDisk(true)
.build();
imageLoader.displayImage(list.get(position), holder.imageView, options);
// We are feeding the urls here.
}
I am creating an app. my app is crash when i enter any word after provide space in autocompletetextview and then again when i enter any word then its crash. please help me. using following code.........
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,
LocationListener, AdapterView.OnItemClickListener {
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker,FindMarker;
LocationRequest mLocationRequest;
AutoCompleteTextView atvPlaces;
DownloadTask placesDownloadTask;
DownloadTask placeDetailsDownloadTask;
ParserTask placesParserTask;
ParserTask placeDetailsParserTask;
LatLng latLng;
final int PLACES = 0;
final int PLACES_DETAILS = 1;
ListView lv;
ImageButton remove;
private boolean exit = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// setSupportActionBar(toolbar);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onLocationChanged(mLastLocation);
}
});
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
remove = (ImageButton)findViewById(R.id.place_autocomplete_clear_button);
// Getting a reference to the AutoCompleteTextView
atvPlaces = (AutoCompleteTextView) findViewById(R.id.id_search_EditText);
atvPlaces.setThreshold(1);
// Adding textchange listener
atvPlaces.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Creating a DownloadTask to download Google Places matching "s"
placesDownloadTask = new DownloadTask(PLACES);
// Getting url to the Google Places Autocomplete api
String url = getAutoCompleteUrl(s.toString().trim());
// Start downloading Google Places
// This causes to execute doInBackground() of DownloadTask class
placesDownloadTask.execute(url);
if (!atvPlaces.getText().toString().equals("")){
lv.setVisibility(View.VISIBLE);
remove.setVisibility(View.VISIBLE);
}else {
lv.setVisibility(View.GONE);
remove.setVisibility(View.GONE);
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
// Setting an item click listener for the AutoCompleteTextView dropdown list
/* atvPlaces.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int index,
long id) {
ListView lv = (ListView) arg0;
SimpleAdapter adapter = (SimpleAdapter) arg0.getAdapter();
HashMap<String, String> hm = (HashMap<String, String>) adapter.getItem(index);
// Creating a DownloadTask to download Places details of the selected place
placeDetailsDownloadTask = new DownloadTask(PLACES_DETAILS);
// Getting url to the Google Places details api
String url = getPlaceDetailsUrl(hm.get("reference"));
// Start downloading Google Place Details
// This causes to execute doInBackground() of DownloadTask class
placeDetailsDownloadTask.execute(url);
InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
});*/
lv=(ListView)findViewById(R.id.list);
lv.setOnItemClickListener(this);
setListenerOnWidget();
}
private void setListenerOnWidget() {
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View view) {
atvPlaces.setText("");
}
};
remove.setOnClickListener(listener);
}
#Override
public void onBackPressed() {
if(exit){
finish();
}else {
Toast.makeText(this, "Tap Back again to Exit.",
Toast.LENGTH_SHORT).show();
exit = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
exit = false;
}
}, 3 * 1000);
}
}
#Override
public void onItemClick (AdapterView < ? > adapterView, View view,int i, long l){
//ListView lv = (ListView) adapterView;
SimpleAdapter adapter = (SimpleAdapter) adapterView.getAdapter();
HashMap<String, String> hm = (HashMap<String, String>) adapter.getItem(i);
// Creating a DownloadTask to download Places details of the selected place
placeDetailsDownloadTask = new DownloadTask(PLACES_DETAILS);
// Getting url to the Google Places details api
String url = getPlaceDetailsUrl(hm.get("reference"));
// Start downloading Google Place Details
// This causes to execute doInBackground() of DownloadTask class
placeDetailsDownloadTask.execute(url);
InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
String str = ((TextView) view.findViewById(R.id.place_name)).getText().toString();
Toast.makeText(this,str, Toast.LENGTH_SHORT).show();
atvPlaces.setText(str.replace(' ',','));
lv.setVisibility(view.GONE);
}
private String getPlaceDetailsUrl(String ref) {
// Obtain browser key from https://code.google.com/apis/console
String key = "key=**************************************";
// reference of place
String reference = "reference=" + ref;
// Sensor enabled
String sensor = "sensor=false";
// Building the parameters to the web service
String parameters = reference + "&" + sensor + "&" + key;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/place/details/" + output + "?" + parameters;
return url;
}
private String getAutoCompleteUrl(String place) {
// Obtain browser key from https://code.google.com/apis/console
String key = "key=*********************************";
// place to be be searched
String input = "input=" + place;
// place type to be searched
String types = "types=geocode";
// Sensor enabled
String sensor = "sensor=false";
// Building the parameters to the web service
String parameters = input + "&" + types + "&" + sensor + "&" + key;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/place/autocomplete/" + output + "?" + parameters;
return url;
}
/**
* A method to download json data from url
*/
private String downloadUrl(String strUrl) throws IOException {
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
Log.d("Exception while downloading url", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();
//mLocationRequest.setInterval(1000);
//mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if(mCurrLocationMarker != null){
mCurrLocationMarker.remove();
}
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOption = new MarkerOptions();
markerOption.position(latLng);
markerOption.title("Current Position");
markerOption.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOption);
Toast.makeText(this,"Location changed",Toast.LENGTH_SHORT).show();
CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng).zoom(13).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
if(mGoogleApiClient != null){
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
}
loadNearByPlaces(location.getLatitude(), location.getLongitude());
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResult) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
if (grantResult.length > 0
&& grantResult[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
Toast.makeText(this, "permisison denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}
private void loadNearByPlaces(double latitude, double longitude) {
//YOU Can change this type at your own will, e.g hospital, cafe, restaurant.... and see how it all works
String type = "atm";
StringBuilder googlePlacesUrl =
new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
googlePlacesUrl.append("location=").append(latitude).append(",").append(longitude);
googlePlacesUrl.append("&radius=").append(PROXIMITY_RADIUS);
googlePlacesUrl.append("&types=").append(type);
googlePlacesUrl.append("&sensor=true");
googlePlacesUrl.append("&key=" + GOOGLE_BROWSER_API_KEY);
JsonObjectRequest request = new JsonObjectRequest(googlePlacesUrl.toString(),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject result) {
Log.i(TAG, "onResponse: Result= " + result.toString());
parseLocationResult(result);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "onErrorResponse: Error= " + error);
Log.e(TAG, "onErrorResponse: Error= " + error.getMessage());
}
});
AppController.getInstance().addToRequestQueue(request);
}
private void parseLocationResult(JSONObject result) {
String id, place_id, placeName = null, reference, icon, vicinity = null;
double latitude, longitude;
try {
JSONArray jsonArray = result.getJSONArray("results");
if (result.getString(STATUS).equalsIgnoreCase(OK)) {
//mMap.clear();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject place = jsonArray.getJSONObject(i);
id = place.getString(ATM_ID);
place_id = place.getString(PLACE_ID);
if (!place.isNull(NAME)) {
placeName = place.getString(NAME);
}
if (!place.isNull(VICINITY)) {
vicinity = place.getString(VICINITY);
}
latitude = place.getJSONObject(GEOMETRY).getJSONObject(LOCATION)
.getDouble(LATITUDE);
longitude = place.getJSONObject(GEOMETRY).getJSONObject(LOCATION)
.getDouble(LONGITUDE);
reference = place.getString(REFERENCE);
icon = place.getString(ICON);
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(latitude, longitude);
markerOptions.position(latLng);
markerOptions.title(placeName);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory .HUE_BLUE));
markerOptions.snippet(vicinity);
mMap.addMarker(markerOptions);
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
View myContentsView = getLayoutInflater().inflate(R.layout.marker, null);
TextView tvTitle = ((TextView)myContentsView.findViewById(R.id.title));
tvTitle.setText(marker.getTitle());
TextView tvSnippet = ((TextView)myContentsView.findViewById(R.id.snippet));
tvSnippet.setText(marker.getSnippet());
return myContentsView;
}
});
}
Toast.makeText(getBaseContext(), jsonArray.length() + " ATM_FOUND!",
Toast.LENGTH_SHORT).show();
} else if (result.getString(STATUS).equalsIgnoreCase(ZERO_RESULTS)) {
Toast.makeText(getBaseContext(), "No ATM found in 5KM radius!!!",
Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
Log.e(TAG, "parseLocationResult: Error=" + e.getMessage());
}
}
private class DownloadTask extends AsyncTask<String, Void, String> {
private int downloadType = 0;
// Constructor
public DownloadTask(int type) {
this.downloadType = type;
}
#Override
protected String doInBackground(String... url) {
// For storing data from web service
String data = "";
try {
// Fetching the data from web service
data = downloadUrl(url[0]);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
switch (downloadType) {
case PLACES:
// Creating ParserTask for parsing Google Places
placesParserTask = new ParserTask(PLACES);
// Start parsing google places json data
// This causes to execute doInBackground() of ParserTask class
placesParserTask.execute(result);
break;
case PLACES_DETAILS:
// Creating ParserTask for parsing Google Places
placeDetailsParserTask = new ParserTask(PLACES_DETAILS);
// Starting Parsing the JSON string
// This causes to execute doInBackground() of ParserTask class
placeDetailsParserTask.execute(result);
}
}
}
/**
* A class to parse the Google Places in JSON format
*/
private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {
int parserType = 0;
public ParserTask(int type) {
this.parserType = type;
}
#Override
protected List<HashMap<String, String>> doInBackground(String... jsonData) {
JSONObject jObject;
List<HashMap<String, String>> list = null;
try {
jObject = new JSONObject(jsonData[0]);
switch (parserType) {
case PLACES:
PlaceJSONParser placeJsonParser = new PlaceJSONParser();
// Getting the parsed data as a List construct
list = placeJsonParser.parse(jObject);
break;
case PLACES_DETAILS:
PlaceDetailsJSONParser placeDetailsJsonParser = new PlaceDetailsJSONParser();
// Getting the parsed data as a List construct
list = placeDetailsJsonParser.parse(jObject);
}
} catch (Exception e) {
Log.d("Exception", e.toString());
}
return list;
}
#Override
protected void onPostExecute(List<HashMap<String, String>> result) {
switch (parserType) {
case PLACES:
String[] from = new String[]{"description"};
int[] to = new int[]{R.id.place_name};
// Creating a SimpleAdapter for the AutoCompleteTextView
//SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1, from, to);
// Setting the adapter
//atvPlaces.setAdapter(adapter);
ListAdapter adapter = new SimpleAdapter(MainActivity.this, result,R.layout.row,from,to);
// Adding data into listview
lv.setAdapter(adapter);
break;
case PLACES_DETAILS:
String location = atvPlaces.getText().toString();
if (location != null && !location.equals("")) {
new GeocoderTask().execute(location);
}
break;
}
}
}
private class GeocoderTask extends AsyncTask<String, Void, List<Address>> {
#Override
protected List<Address> doInBackground(String... locationName) {
// TODO Auto-generated method stub
Geocoder geocoder = new Geocoder(getBaseContext());
List<Address> addresses = null;
try {
// Getting a maximum of 3 Address that matches the input text
addresses = geocoder.getFromLocationName(locationName[0], 3);
} catch (IOException e) {
e.printStackTrace();
}
return addresses;
}
protected void onPostExecute(List<Address> addresses) {
if(addresses==null || addresses.size()==0){
Toast.makeText(getBaseContext(), "No Location found", Toast.LENGTH_SHORT).show();
}
for(int i=0;i<addresses.size();i++){
Address address = (Address)addresses.get(i);
latLng = new LatLng(address.getLatitude(), address.getLongitude());
String addressText = String.format("%s, %s",
address.getMaxAddressLineIndex() > 0 ? address.getAddressLine(0) : "",
address.getCountryName());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Find Location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
FindMarker = mMap.addMarker(markerOptions);
CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng).zoom(13).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
loadNearByPlaces(address.getLatitude(), address.getLongitude());
}
}
}
}
my app is crash when i enter any word after provide space in autocompletetextview and then again when i enter any word then its crash....
Your list is initialized to null at
List<HashMap<String, String>> list = null;
And if the parsing fire any exception, the list will be still null since it won't get initialized & setting a null List to an adapter will produce the NullPointerException at getCount(). So just ensure to initialize it.
List<HashMap<String, String>> list = new ArrayList<>();
IMPORTANT
When you use a space & try to call that URL, it will fire a FileNotFoundException if not encoded properly. In your case, URL url = new URL(strUrl); is firing that exception while using space character.
Easiest way is to replace space with %20. In getAutoCompleteUrl() before return, put the following code to replace space with %20.
private String getAutoCompleteUrl(String place) {
-------existing code----
url = url.replaceAll(" ", "%20");
return url;
}
Actually i had faced the same situation. You are adding data to autocomplete textview dynamically , basically just like google for each word you are typing u are getting that data from server , if i am wrong please correct me.
Use this code for populating data into autocomplete textview dynamically from server depending upon your search
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.SyncStateContract.Columns;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.Filter;
import android.widget.FilterQueryProvider;
import android.widget.ListView;
public class TestActivity extends Activity {
public Context mContext;
// views declaration
public AutoCompleteTextView txtAutoComplete;
public ListView lvItems;
// arrayList for Adaptor
ArrayList<String> listItems;
// getting input from AutocompleteTxt
String strItemName;
// making Adaptor for autocompleteTextView
ArrayAdapter<String> adaptorAutoComplete;
private static final int ADDRESS_TRESHOLD = 2;
private Filter filter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// for showing full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_listitem);
mContext = this;
listItems = new ArrayList<String>();
// Declaring and getting all views objects
Button btnShare = (Button) findViewById(R.id.ListItem_btnShare);
Button btnSort = (Button) findViewById(R.id.ListItem_btnSort);
lvItems = (ListView) findViewById(R.id.ListItem_lvItem);
txtAutoComplete = (AutoCompleteTextView) findViewById(R.id.ListItem_autoComplete);
// adding listeners to button
btnShare.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
});
btnSort.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
});
String[] from = { "name" };
int[] to = { android.R.id.text1 };
SimpleCursorAdapter a = new SimpleCursorAdapter(this,
android.R.layout.simple_dropdown_item_1line, null, from, to, 0);
a.setStringConversionColumn(1);
FilterQueryProvider provider = new FilterQueryProvider() {
#Override
public Cursor runQuery(CharSequence constraint) {
// run in the background thread
if (constraint == null) {
return null;
}
String[] columnNames = { Columns._ID, "name" };
MatrixCursor c = new MatrixCursor(columnNames);
try {
// total code for implementing my way of auto complte
String SOAP_ACTION = "your action";
String NAMESPACE = "your name space";
String METHOD_NAME = "your method name";
String URL = "your Url";
SoapObject objSoap = null;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// Use this to add parameters
request.addProperty("KEY", yourkey);
request.addProperty("Key", constraint);
request.addProperty("Key", Id);
// Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
HttpTransportSE androidHttpTransport = new HttpTransportSE(
URL);
// this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION, envelope);
// Get the SoapResult from the envelope body.
objSoap = (SoapObject) envelope.getResponse();
if (objSoap != null) {
String strData = objSoap.toString();
}
if (objSoap != null) {
System.out.println("getPropertyCountinevents//////////"
+ objSoap.getPropertyCount());
for (int i = 0; i < objSoap.getPropertyCount(); i++) {
Object obj = objSoap.getProperty(i);
if (obj instanceof SoapObject) {
SoapObject objNew = (SoapObject) obj;
c.newRow()
.add(i)
.add(objNew.getProperty("Itemname")
.toString());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
};
a.setFilterQueryProvider(provider);
txtAutoComplete.setAdapter(a);
} // on create ends
} // final class ends
replace mine code of getting data from server to yours i.e calling webservices through http calls and it will work like a charm.
I am currently developing an app in android studio.The goal of my app is to have one page(MainActivity.java & activityMain.xml) display a spinner. The items in this spinner are items from a remote database. When the user selects an item in this spinner I want that selected item to be displayed in a separate page(Map.java map.xml).
I used a putExtra method in MainActivity to store the selected item into a string variable:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(
getApplicationContext(),
parent.getItemAtPosition(position).toString() + " Selected" ,
Toast.LENGTH_LONG).show();
Intent intent = new Intent(MainActivity.this, Map.class);
String text = spinnerFood.getSelectedItem().toString();
intent.putExtra("SPINNER_KEY", text);
startActivity(intent);
}
Then in my Map class I am calling that string using getExtras:
String spinnerString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
spinnerString= null;
} else {
spinnerString= extras.getString("STRING_I_NEED");
}
} else {
spinnerString= (String) savedInstanceState.getSerializable("STRING_I_NEED");
}
I can pass this string from MainActivity to Map successfully. My problem is when I try to display this string is does not appear on the XML page or on my phone when I run the app. I used the following code to try and display the string:
TextView e = (TextView)findViewById(R.id.textView);
e.setText(spinnerString);
Could someone please tell me where I am going wrong?
Here is my MainActivity class:
package com.example.cillin.infoandroidhivespinnermysql;
import java.util.ArrayList;
...
public class MainActivity extends Activity implements OnItemSelectedListener {
private Button btnAddNewCategory;
private TextView txtCategory;
public Spinner spinnerFood;
//public String spinnerValue;
// array list for spinner adapter
private ArrayList<Category> categoriesList;
ProgressDialog pDialog;
// API urls
// Url to create new category
private String URL_NEW_CATEGORY = "http://food_api/new_category.php";
// Url to get all categories
private String URL_CATEGORIES = "http://food_api/get_categories.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnAddNewCategory = (Button) findViewById(R.id.btnAddNewCategory);
spinnerFood = (Spinner) findViewById(R.id.spinFood);
txtCategory = (TextView) findViewById(R.id.txtCategory);
categoriesList = new ArrayList<Category>();
// spinner item select listener
spinnerFood.setOnItemSelectedListener(this);
// Add new category click event
btnAddNewCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (txtCategory.getText().toString().trim().length() > 0) {
// new category name
String newCategory = txtCategory.getText().toString();
// Call Async task to create new category
new AddNewCategory().execute(newCategory);
} else {
Toast.makeText(getApplicationContext(),
"Please enter category name", Toast.LENGTH_SHORT)
.show();
}
}
});
new GetCategories().execute();
}
/**
* Adding spinner data
* */
public void populateSpinner() {
List<String> lables = new ArrayList<String>();
txtCategory.setText("");
for (int i = 0; i < categoriesList.size(); i++) {
lables.add(categoriesList.get(i).getName());
}
// Creating adapter for spinner
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, lables);
// Drop down layout style - list view with radio button
spinnerAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinnerFood.setAdapter(spinnerAdapter);
//String text = spinnerFood.getSelectedItem().toString();
}
/**
* Async task to get all food categories
* */
private class GetCategories extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Fetching food categories..");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
ServiceHandler jsonParser = new ServiceHandler();
String json = jsonParser.makeServiceCall(URL_CATEGORIES, ServiceHandler.GET);
Log.e("Response: ", "> " + json);
if (json != null) {
try {
JSONObject jsonObj = new JSONObject(json);
if (jsonObj != null) {
JSONArray categories = jsonObj
.getJSONArray("categories");
for (int i = 0; i < categories.length(); i++) {
JSONObject catObj = (JSONObject) categories.get(i);
Category cat = new Category(catObj.getInt("id"),
catObj.getString("name"));
categoriesList.add(cat);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("JSON Data", "Didn't receive any data from server!");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pDialog.isShowing())
pDialog.dismiss();
populateSpinner();
}
}
/**
* Async task to create a new food category
* */
private class AddNewCategory extends AsyncTask<String, Void, Void> {
boolean isNewCategoryCreated = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Creating new category..");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(String... arg) {
String newCategory = arg[0];
// Preparing post params
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", newCategory));
ServiceHandler serviceClient = new ServiceHandler();
String json = serviceClient.makeServiceCall(URL_NEW_CATEGORY,
ServiceHandler.POST, params);
Log.d("Create Response: ", "> " + json);
if (json != null) {
try {
JSONObject jsonObj = new JSONObject(json);
boolean error = jsonObj.getBoolean("error");
// checking for error node in json
if (!error) {
// new category created successfully
isNewCategoryCreated = true;
} else {
Log.e("Create Category Error: ", "> " + jsonObj.getString("message"));
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("JSON Data", "Didn't receive any data from server!");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pDialog.isShowing())
pDialog.dismiss();
if (isNewCategoryCreated) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// fetching all categories
new GetCategories().execute();
}
});
}
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(
getApplicationContext(),
parent.getItemAtPosition(position).toString() + " Selected" ,
Toast.LENGTH_LONG).show();
Intent intent = new Intent(MainActivity.this, Map.class);
String text = spinnerFood.getSelectedItem().toString();
intent.putExtra("SPINNER_KEY", text);
startActivity(intent);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
}
Here is Map.java:
package com.example.cillin.infoandroidhivespinnermysql;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
/**
* Created by cillin on 06/07/2015.
*/
public class Map extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//This page layout is located in the menu XML file
//SetContentView links a Java file, to its XML file for the layout
setContentView(R.layout.map);
/*Spinner mySpinner = (Spinner)findViewById(R.id.spinFood);
String text = mySpinner.getSelectedItem().toString();
EditText e = (EditText) findViewById (R.id.editText1);
e.setText(text);*/
String spinnerString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
spinnerString= null;
} else {
spinnerString= extras.getString("STRING_I_NEED");
}
} else {
spinnerString= (String) savedInstanceState.getSerializable("STRING_I_NEED");
}
/*if (getIntent() != null && getIntent().getExtras() != null) {
Bundle bundle = getIntent().getExtras();
if (bundle.getString("SPINNER_KEY") != null) {
spinnerString = bundle.getString("SPINNER_KEY");
}
}*/
//String a = "ddd";
TextView e = (TextView)findViewById(R.id.textView);
e.setText(spinnerString);
Button mainm = (Button)findViewById(R.id.mainmenu);
mainm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//This button is linked to the map page
Intent i = new Intent(Map.this, MainMenu.class);
//Activating the intent
startActivity(i);
}
});
}
}
Here is my map.xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:id="#+id/imageView"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/map_image"
android:contentDescription="#string/map"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="46dp" />
<Button
android:id="#+id/mainmenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="140dp"
android:layout_marginTop = "450dp"
android:text="Main Menu" />
<TextView
android:layout_width="200dp"
android:layout_height="20dp"
android:id="#+id/textView"
android:layout_below="#+id/imageView"
android:layout_alignRight="#+id/imageView"
android:layout_alignEnd="#+id/imageView" />
</RelativeLayout>
you have to use getIntent().getStringExtra("STRING_I_NEED");
getIntent.getExtras() will work only if you pass Bundle in calling activity
I fixed it:
String spinnerString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
spinnerString= null;
} else {
spinnerString= extras.getString("STRING_I_NEED");
}
} else {
spinnerString= (String) savedInstanceState.getSerializable("STRING_I_NEED");
}
I changed "STRING_I_NEED" to "SPINNER_KEY"