I'm new on Android development and I have been struggling on how to draw some graphics after a HTTP request to a Mysql database. I have looked into SyncTask, custom View and onDraw method but I must be missing something because I just can't get it to work. Basically the http request selects some records from the db (I got that working) and I need to create a graph with the data. The http request is an asynchronous process so by the time the http request is done, the onDraw method got executed with no data, that's why I started looking into SyncTask but I can't manage to pass the array that stores the data to be drawn from the onPostExecute method. Any help would be greatly appreciated and if you can point to some sample code that would be great. Thank you
Here is some code that I found online and I have been trying to make it work, so far I can get the data, to simplify it I'm only working with the field location, and I want to drawtext location:
public class TestFragment extends Fragment {
private static final String TAG = "AsyncTestFragment";
// get some fake data
private static final String TEST_URL = "http://jsonplaceholder.typicode.com/comments";
//private static final String TEST_URL = "http://localhost/~juan/A_get_tanks.php";
private static final String ACTION_FOR_INTENT_CALLBACK = "THIS_IS_A_UNIQUE_KEY_WE_USE_TO_COMMUNICATE";
ProgressDialog progress;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_test, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getContent();
}
private void getContent() {
// the request
try {
HttpGet httpGet = new HttpGet(new URI(TEST_URL));
RestTask task = new RestTask(getActivity(), ACTION_FOR_INTENT_CALLBACK);
task.execute(httpGet);
progress = ProgressDialog.show(getActivity(), "Getting Data ...", "Waiting For Results...", true);
}
catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onResume() {
super.onResume();
getActivity().registerReceiver(receiver, new IntentFilter(ACTION_FOR_INTENT_CALLBACK));
}
#Override
public void onPause() {
super.onPause();
getActivity().unregisterReceiver(receiver);
}
/**
* Our Broadcast Receiver. We get notified that the data is ready, and then we
* put the content we receive (a string) into the TextView.
*/
public BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String location;
// clear the progress indicator
if (progress != null) {
progress.dismiss();
}
String response = intent.getStringExtra(RestTask.HTTP_RESPONSE);
try {
JSONObject mainObject = new JSONObject(response);
JSONArray tank_data = mainObject.getJSONArray("tank_data");
JSONObject tankObj = tank_data.getJSONObject(0);
location = (String) tankObj.getString("Location");
} catch (JSONException e) {
location = null;
e.printStackTrace();
}
new TankView(context, location);
Log.i(TAG, "RESPONSE = " + location);
}
};
}
public class RestTask extends AsyncTask<HttpUriRequest, Void, String>
{
private static final String TAG = "AsyncRestTask";
public static final String HTTP_RESPONSE = "httpResponse";
private Context mContext;
private HttpClient mClient;
private String mAction;
public RestTask(Context context, String action) {
mContext = context;
mAction = action;
mClient = new DefaultHttpClient();
}
public RestTask(Context context, String action, HttpClient client) {
mContext = context;
mAction = action;
mClient = client;
}
#Override
protected String doInBackground(HttpUriRequest... params) {
try {
HttpUriRequest request = params[0];
HttpResponse serverResponse = mClient.execute(request);
BasicResponseHandler handler = new BasicResponseHandler();
return handler.handleResponse(serverResponse);
}
catch (Exception e) {
// TODO handle this properly
e.printStackTrace();
return "";
}
}
#Override
protected void onPostExecute(String result) {
Log.i(TAG, "RESULT = " + result);
Intent intent = new Intent(mAction);
intent.putExtra(HTTP_RESPONSE, result);
// broadcast the completion
mContext.sendBroadcast(intent);
}
}
package com.alvinalexander.asynctest;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
public class TestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
TestFragment testFragment = new TestFragment();
getFragmentManager().beginTransaction().add(android.R.id.content, testFragment).commit();
setContentView(new TankView(this, ""));
}
}
}
public class TankView extends View {
private String location;
private Paint _paintTank = new Paint();
public TankView(Context context, String location) {
super(context);
// TODO Auto-generated constructor stub
init(null, 0);
this.location = location;
}
public TankView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init(attrs, 0);
}
public TankView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init(attrs, 0);
}
public TankView(TestActivity testActivity, String location) {
super(testActivity);
this.location = location;
}
public TankView(TestActivity testActivity, Object o) {
super(testActivity, (AttributeSet) o);
}
private void init(AttributeSet attrs, int defStyle) {
_paintTank.setColor(Color.RED);
_paintTank.setAntiAlias(true);
_paintTank.setStyle(Paint.Style.STROKE);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (this.location != null) {
canvas.drawText(this.location, 10, 10, _paintTank);
}
}
}
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:background="#AEECFF">
<!-- fill the screen with a textview. the app will write text into it. -->
<com.alvinalexander.asynctest.TankView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Related
I looked into other threads, but found no solution for this, except it was originally detected for API 21, i.e. Lollipop. While, I am facing this issue in Lollipop as well as post-Lollipop versions.
I am using YouTube Data API, to display the content of the particular channel in my app. And I am successful in getting the response from the API and displaying content in the RecyclerView.
But when I try to load the video in the YouTubeSupportFragment, the app crashes while invoking the cueVideo() of YouTubeSupportFragment with the following exception.
Note: I am using the latest version (1.2.2) of the YouTube API.
Here's the exception thrown by the YouTube Player:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.acme.youtubeplayer, PID: 16757
java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.google.android.youtube.api.service.START }
at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:2101)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:2225)
at android.app.ContextImpl.bindService(ContextImpl.java:2203)
at android.content.ContextWrapper.bindService(ContextWrapper.java:560)
at com.google.android.youtube.player.internal.r.e(Unknown Source)
at com.google.android.youtube.player.YouTubePlayerView.a(Unknown Source)
at com.google.android.youtube.player.YouTubePlayerSupportFragment.a(Unknown Source)
at com.google.android.youtube.player.YouTubePlayerSupportFragment.onCreateView(Unknown Source)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:7007)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Here's my ListFragment.java, where the app crashes:
public class ListFragment extends android.support.v4.app.Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private static final String KEY_TRANSITION_EFFECT = "transition_effect";
private static final int RECOVERY_REQUEST = 1;
private int mCurrentTransitionEffect = JazzyHelper.HELIX;
private JazzyRecyclerViewScrollListener jazzyScrollListener;
YouTubePlayerView youtube_player;
MyPlayerStateChangeListener playerStateChangeListener;
MyPlaybackEventListener playbackEventListener;
YouTubePlayer playerFragment;
JSONObject jObjectAPI;
JSONArray jArrayResponse;
int listSize;
JSONObject jObjectResponse, jObject;
public static final String YOUTUBE_API = "https://www.googleapis.com/youtube/v3/search?key=" + Config.YOUTUBE_API_KEY + "&channelId=" + Config.YOUTUBE_CHANNEL_ID + "&part=snippet,id&order=date&maxResults=20";
//Local Variables
RecyclerView recyclerView;
Button seekToButton;
YouTubePlayerSupportFragment youTubePlayerFragment;
String[] thumbnailVideo;
String[] titleVideo;
String[] descriptionVideo;
String[] idVideo;
int itemLayoutRes = R.layout.item;
boolean isStaggered = false;
private OnFragmentInteractionListener mListener;
private ProgressDialog pDialog;
public ListFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment ListFragment.
*/
// TODO: Rename and change types and number of parameters
public static ListFragment newInstance(String param1, String param2) {
ListFragment fragment = new ListFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
// Inflate the layout for this fragment
recyclerView = (RecyclerView) view.findViewById(R.id.rv_video_list);
recyclerView.setLayoutManager(createLayoutManager(itemLayoutRes, isStaggered));
recyclerView.setHasFixedSize(false);
new GetList().execute();
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
private RecyclerView.LayoutManager createLayoutManager(int itemLayoutRes, boolean isStaggered) {
if (itemLayoutRes == R.layout.item) {
return new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
} else {
if (isStaggered) {
return new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
} else {
return new GridLayoutManager(getActivity(), 1);
}
}
}
private void setupJazziness(int effect) {
mCurrentTransitionEffect = effect;
jazzyScrollListener.setTransitionEffect(mCurrentTransitionEffect);
}
private void showMessage(String message) {
Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();
}
public final class MyPlaybackEventListener implements YouTubePlayer.PlaybackEventListener {
#Override
public void onPlaying() {
// Called when playback starts, either due to user action or call to play().
showMessage("Playing");
}
#Override
public void onPaused() {
// Called when playback is paused, either due to user action or call to pause().
showMessage("Paused");
}
#Override
public void onStopped() {
// Called when playback stops for a reason other than being paused.
showMessage("Stopped");
}
#Override
public void onBuffering(boolean b) {
// Called when buffering starts or ends.
}
#Override
public void onSeekTo(int i) {
// Called when a jump in playback position occurs, either
// due to user scrubbing or call to seekRelativeMillis() or seekToMillis()
}
}
public final class MyPlayerStateChangeListener implements YouTubePlayer.PlayerStateChangeListener {
#Override
public void onLoading() {
// Called when the youtube_player is loading a video
// At this point, it's not ready to accept commands affecting playback such as play() or pause()
playerFragment.loadVideo(idVideo.toString());
}
#Override
public void onLoaded(String s) {
// Called when a video is done loading.
// Playback methods such as play(), pause() or seekToMillis(int) may be called after this callback.
playerFragment.play();
}
#Override
public void onAdStarted() {
// Called when playback of an advertisement starts.
playerFragment.pause();
}
#Override
public void onVideoStarted() {
// Called when playback of the video starts.
}
#Override
public void onVideoEnded() {
// Called when the video reaches its end.
if (playerFragment.hasNext()) {
playerFragment.next();
}
}
#Override
public void onError(YouTubePlayer.ErrorReason errorReason) {
// Called when an error occurs.
Toast.makeText(getActivity(), "Please check your Internet Connection", Toast.LENGTH_LONG).show();
}
}
public static JSONObject getJSONObjectFromURL(String urlString) throws IOException, JSONException {
HttpURLConnection urlConnection = null;
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setDoOutput(true);
urlConnection.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
char[] buffer = new char[1024];
String jsonString;
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
jsonString = sb.toString();
System.out.println("JSON: " + jsonString);
return new JSONObject(jsonString);
}
private class GetList extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try {
jObjectAPI = getJSONObjectFromURL(YOUTUBE_API);
Log.e("response", String.valueOf(jObjectAPI));
jArrayResponse = jObjectAPI.getJSONArray("items");
Log.e("array", String.valueOf(jArrayResponse));
listSize = jArrayResponse.length();
thumbnailVideo = new String[listSize];
titleVideo = new String[listSize];
descriptionVideo = new String[listSize];
idVideo = new String[listSize];
for (int i = 0; i < listSize; i++) {
jObjectResponse = jArrayResponse.getJSONObject(i);
thumbnailVideo[i] = jObjectResponse.getJSONObject("snippet").getJSONObject("thumbnails")
.getJSONObject("default")
.optString("url");
titleVideo[i] = jObjectResponse.getJSONObject("snippet").optString("title");
if (!(jObjectResponse.getJSONObject("snippet").optString("description").equals(""))
&& !(jObjectResponse.getJSONObject("snippet").optString("description").equals(null))
&& (jObjectResponse.getJSONObject("snippet").optString("description").length() > 0)) {
descriptionVideo[i] = jObjectResponse.getJSONObject("snippet").optString("description");
} else {
descriptionVideo[i] = "No Description Found";
}
idVideo[i] = jObjectResponse.getJSONObject("id").optString("videoId");
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON Exception", e.toString());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
**/
recyclerView.setAdapter(new VideoListAdapter(thumbnailVideo, titleVideo, descriptionVideo, idVideo, itemLayoutRes, getActivity()));
jazzyScrollListener = new JazzyRecyclerViewScrollListener();
recyclerView.setOnScrollListener(jazzyScrollListener);
setupJazziness(R.anim.slide_left_in);
playerStateChangeListener = new MyPlayerStateChangeListener();
playbackEventListener = new MyPlaybackEventListener();
youTubePlayerFragment = new YouTubePlayerSupportFragment();
youTubePlayerFragment.initialize(Config.YOUTUBE_API_KEY, new YouTubePlayer.OnInitializedListener() {
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
playerFragment = player;
player.setPlayerStateChangeListener(playerStateChangeListener);
player.setPlaybackEventListener(playbackEventListener);
if (!wasRestored) {
player.cueVideos(Arrays.asList(idVideo));
}
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider arg0, YouTubeInitializationResult errorReason) {
// TODO Auto-generated method stub
if (errorReason.isUserRecoverableError()) {
errorReason.getErrorDialog(getActivity(), RECOVERY_REQUEST).show();
} else {
String error = String.format(getString(R.string.player_error), errorReason.toString());
Toast.makeText(getActivity(), error, Toast.LENGTH_LONG).show();
}
}
});
android.support.v4.app.FragmentManager fmPlayer = getFragmentManager();
FragmentTransaction transaction = fmPlayer.beginTransaction();
transaction.replace(R.id.youtube_player_view, youTubePlayerFragment);
transaction.commit();
}
}
}
Here's my Adapter class:
public class VideoListAdapter extends Adapter<VideoListAdapter.VideoListViewHolder> {
private List<String> thumbnail;
private List<String> title;
private List<String> desc;
private List<String> id;
private int itemLayoutRes;
private static Activity mContext;
public VideoListAdapter(String[] videoThumbnail, String[] videoTitle, String[] videoDesc, String[] videoId, int itemLayoutRes, Activity context) {
this.thumbnail = Arrays.asList(videoThumbnail);
this.title = Arrays.asList(videoTitle);
this.desc = Arrays.asList(videoDesc);
this.id = Arrays.asList(videoId);
this.itemLayoutRes = itemLayoutRes;
this.mContext = context;
}
#Override
public VideoListAdapter.VideoListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view;
view = inflater.inflate(itemLayoutRes, parent, false);
return new VideoListViewHolder(view);
}
#Override
public void onBindViewHolder(final VideoListViewHolder holder, final int position) {
Picasso.with(mContext).load(thumbnail.get(position)).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
// loaded bitmap is here (bitmap)
holder.thumbnailVideo.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Toast.makeText(mContext, "Image load failed", Toast.LENGTH_LONG).show();
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
Log.e("thumbnail Adapter", String.valueOf(thumbnail.get(position)));
holder.titleVideo.setText(title.get(position));
holder.descVideo.setText(desc.get(position));
holder.idVideo = id.get(position);
}
#Override
public int getItemCount() {
return title.size();
}
#Override
public int getItemViewType(int position) {
// return isStaggered ? position % 2 : 0;
return position;
}
public static class VideoListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
final TextView titleVideo, descVideo;
final YouTubeThumbnailView thumbnailVideo;
String idVideo;
public VideoListViewHolder(View view) {
super(view);
thumbnailVideo = (YouTubeThumbnailView) view.findViewById(R.id.thumbnail_video);
titleVideo = (TextView) view.findViewById(R.id.title_video);
descVideo = (TextView) view.findViewById(R.id.desc_video);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, YouTubeBaseActivity.class);
//Intent intent = YouTubeStandalonePlayer.createVideoIntent((Activity) v.getContext(), Config.YOUTUBE_API_KEY, idVideo);
v.getContext().startActivity(intent);
}
}
}
Finally I got rid of this issue. I replaced the YouTubeSupportFragment with YouTubeBaseActivity and used YouTubePlayerView to play the video.
In other words, I used an Activity extending YouTubeBaseActivity to play the video instead of a Fragment.
Hope it helps someone getting the issue.
I have a problem related to AsyncTask. I want to change the text inside the onPostExecute method, but it doesn't work. I really don't know what I am doing wrong. Can somebody help me out please?
I don't understand why it work when I declare the AsyncTask as a nested class but it don't work when I declare it as a own class.
Here is my code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button button = null;
private Helper helper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.helper = new Helper(this, getLayoutInflater());
this.button = (Button) findViewById(R.id.button1);
this.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
new MyAsyncTask(helper).execute("");
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
Helper.java
public class Helper {
private Context context;
private LayoutInflater inflater;
public Helper(Context context, LayoutInflater inflater) {
setContext(context);
setInflater(inflater);
}
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public LayoutInflater getInflater() {
return inflater;
}
public void setInflater(LayoutInflater inflater) {
this.inflater = inflater;
}
}
MyAsyncTask.java
public class MyAsyncTask extends AsyncTask<String, String, String> {
private Helper helper;
public MyAsyncTask(Helper helper) {
setHelper(helper);
}
public String getJSON(String url, int timeout) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-length", "0");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.setConnectTimeout(timeout);
c.setReadTimeout(timeout);
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
}
} catch (MalformedURLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String s) {
TextView t = (TextView) getHelper().getInflater().inflate(R.layout.activity_main, null).findViewById(R.id.textView);
t.setText("" + s); //has no effect on the UI but the text was set????
Toast.makeText(getHelper().getContext(), t.getText(), Toast.LENGTH_LONG).show();
super.onPostExecute(s);
}
#Override
protected String doInBackground(String... params) {
return getJSON("testside.com", 10000);
}
public Helper getHelper() {
return helper;
}
public void setHelper(Helper helper) {
this.helper = helper;
}
}
Thanks :)
Utilize you AsyncTask outside of your main Class using separate files
class MyActivity{
new MyAsyncTask().execute();
}
Your AsyncTask lives as another class Extending AsyncTask
class MyAsyncTask extends AsyncTask{
public MyAsyncTask(Context appContext){
}
}
Be sure to pass in your App's Context. You can only execute each instance of the task once.... but you can create and run a new instance when needed...
Wouldn't fly:
class MyActivity{
MyAsyncTask myTask = new MyAsyncTask();
myTask.execute();
//DO OTHER STUFF
myTask.execute();
}
You would instead do each time needed:
new MyAsyncTask().execute();
Your code looks fine but it doesn't work because it take reference to TextView from new layou which you inflate.
You have two options:
In your helper store TextView which you want to change, you can make it optional if your helper looks something like this:
public class Helper {
private Context context;
private LayoutInflater inflater;
private TextView textView;
...
public void addTextView(TextView textView){
this.texView = textView;
}
public TextView getTextView(){
return textView;
}
}
and then in your postExecute() call TextView t = helper.getTextview().
Pass textView directly to your AsyncTask so it look like
public MyAsyncTask(Helper helper, TextView t) {
setHelper(helper);
this.textView = t;
}
Your AsyncTask is executed on a background thread. To update your UI call,
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText("Text");
}
});
on an activity.
I am finding the solution of my problem but not satisfied from all of them.
I create an android library which shows a ad view layout witch is and know I want to call this layout in unity but can't find any solution please anyone help me how can I call my layout in unity?
public class RedeemLayout extends LinearLayout implements View.OnClickListener,HttpCallBacks {
public Dialog dialogBox;
public ImageButton close;
public ImageView advert;
public TextView location_text;
TextView tv_massagetext;
EditText et_redeemdetial;
Button btn_redem;
ImageButton btn_closead;
DeviceInfo device = new DeviceInfo();
String adClickUrl;
HttpNetworkCalls httpNetworkCalls;
Context context;
Activity activity;
ImageView bmImage;
FrameLayout redeemLayout;
AdInfo ad;
private AdInfo adInfo;
private UserInfo user;
public RedeemLayout(Context context) {
super(context);
initialize(context);
this.context = context;
}
public RedeemLayout(Activity activity, Context context) {
super(context);
initialize(context);
this.context = context;
this.activity = activity;
}
public RedeemLayout(Context context, AttributeSet attr) {
super(context, attr);
initialize(context);
this.context = context;
}
private void initialize(Context context) {
inflate(context, R.layout.ad_lyout, this);
tv_massagetext = (TextView) findViewById(R.id.massagetext);
et_redeemdetial = (EditText) findViewById(R.id.redeemdetail);
btn_redem = (Button) findViewById(R.id.btn_redeem);
btn_closead = (ImageButton) findViewById(R.id.btn_CloseFullScreenAd);
bmImage = (ImageView) findViewById(R.id.adimage);
redeemLayout = (FrameLayout) findViewById(R.id.redeemLayout);
httpNetworkCalls = new HttpNetworkCalls(this);
btn_redem.setOnClickListener(this);
btn_closead.setOnClickListener(this);
DownloadAdAccordingToLocation();
}
public void onClick(View view) {
int i = view.getId();
if (i == R.id.btn_redeem) {
Toast.makeText(getContext(), "Thanks for Redeem You will get Massage soon...", Toast.LENGTH_LONG).show();
Map<String, String> data = new HashMap<>();
data.put("ad_id",ad.getAdId());
data.put("app_id","1");
data.put("location","lahore");
data.put("session","1");
try {
httpNetworkCalls.post(data, API.UPDATE_IMPRESSIONS);
// call AsynTask to perform network operation on separate thread
} catch (Exception e) {
e.printStackTrace();
}
// call AsynTask to perform network operation on separate thread
}
if (i == R.id.btn_CloseFullScreenAd) {
redeemLayout.removeAllViews();
redeemLayout.setVisibility(View.GONE);
Map<String, String> data = new HashMap<>();
data.put("ad_id",ad.getAdId());
data.put("app_id","1");
data.put("location","lahore");
data.put("session","1");
Toast.makeText(getContext(), "Thanks for Redeem You will get Massage soon...", Toast.LENGTH_LONG).show();
try {
httpNetworkCalls.post(data, API.UPDATE_IMPRESSIONS);
// call AsynTask to perform network operation on separate thread
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void DownloadAdAccordingToLocation() {
try {
httpNetworkCalls.get(API.RANDOM_ADVERTISEMENT);
} catch (IOException e) {
e.printStackTrace();
}
}
public void adButtonClicked(View v) {
// FullScreenAdDialog db = new FullScreenAdDialog(this, ad, updateAdClick);
// db.show();
// Intent x = new Intent(xcontext, AdActivity.class);
// x.putExtra("image_link", ad.getImage_link());
// x.putExtra("url", ad.getUrl());
// x.putExtra("adid", ad.getAdId());
// x.putExtra("adclickurl", updateAdClick);
// startActivity(x);
}
#Override
public void HttpResponse(final int apiCode, final JSONObject response, final boolean isSuccess) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
if (apiCode == API.RANDOM_ADVERTISEMENT) {
if (response.has("networkError")) {
Log.e("Error", response.getString("networkError"));
} else {
ad = AdInfo.fromJson(response);
if (ad.isSuccess()) {
Picasso.Builder builder = new Picasso.Builder(context);
builder.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
redeemLayout.removeAllViews();
redeemLayout.setVisibility(View.GONE);
}
});
Picasso pic = builder.build();
pic.load(ad.getImage_url()).into(bmImage);
// Picasso.with(context)
// .load(ad.getImage_url())
// .error(R.drawable.imagecross)
// .into(bmImage);
} else {
Log.e("Error", response.getString("parseError"));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
and call my library in android app like this.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout layout= (RelativeLayout)findViewById(R.id.test);
RedeemLayout redeemLayout= new RedeemLayout(this, this);
redeemLayout.setGravity(Gravity.CENTER);
layout.addView(redeemLayout);
}
}
It's more unity3d question. You cannot call your layout directly, you can only send message to android code. Read Unity3d script documentation (or google for code) of AndroidJavaClass and AndroidJavaObject.
From Android perspective I think that you should implement some kind of static method that you can call from unity and it should broadcast or send event in event bus that will be handled by your advertisement engine.
Unity part of code should be similar to this:
AndroidJavaClass javaClass = new AndroidJavaClass("com.mypackage.MyClassWithMyStaticMethod");
javaClass.getStatic<AndroidJavaObject>("MyStaticMethod", 42);
Android MyClassWithMyStaticMethod class should implement:
public static void MyStaticMethid(int param) {...}
Check this doc: AndroidJavaClass
First of all, I am relatively new to android programming.
I am creating a ViewPager application with two Fragments. One of the Fragments requests data from a server and return a result to the main FragmentActivity. My problem is that this request to the server can take sometime, and I have been trying to get a ProgressDialog to appear with AsyncTask while the user waits for the data to be retrieved. Once I create the background thread to retrieve the data, I successfully execute some code in the onPostExecute() method and set some variables. However, the return statement that sends information back to the FragmentActivity is being executed before the background thread actually ends. I can't seem to figure out a way for the main thread to wait on the background thread. Using Asyctask's get() method results in the ProgressDialog from appearing. I have looked through a lot of posts in here, but can't seem to find an answer.
Anything helps.
Code below:
SplashScreen.java
public class SplashScreen extends FragmentActivity {
MainMenu mainMenu;
MapScreen mapScreen;
PagerAdapter pagerAdapter;
ViewPager viewPager;
List<LatLng> geoPoints;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_splash_screen);
context = this;
initializePaging();
}
private void initializePaging()
{
mainMenu = new MainMenu();
mapScreen = new MapScreen();
pagerAdapter = new PagerAdapter(getSupportFragmentManager());
pagerAdapter.addFragment(mainMenu);
pagerAdapter.addFragment(mapScreen);
viewPager = (ViewPager) super.findViewById(R.id.viewPager);
viewPager.setAdapter(pagerAdapter);
viewPager.setOffscreenPageLimit(2);
viewPager.setCurrentItem(0);
viewPager.setOnPageChangeListener(new OnPageChangeListener()
{
#Override
public void onPageScrollStateChanged(int postion){}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2){}
#Override
public void onPageSelected(int position)
{
switch(position){
case 0: findViewById(R.id.first_tab).setVisibility(View.VISIBLE);
findViewById(R.id.second_tab).setVisibility(View.INVISIBLE);
break;
case 1: findViewById(R.id.first_tab).setVisibility(View.INVISIBLE);
findViewById(R.id.second_tab).setVisibility(View.VISIBLE);
break;
}
}
});
}
//Called from onClick in main_mainu.xml
public void getDirections(View view)
{
InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
try
{
geoPoints = mainMenu.getDirections(context);
mapScreen.plotPoints(geoPoints);
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(), "Error! Invalid address entered.", Toast.LENGTH_LONG).show();
mainMenu.clear();
}
}
}
MainMenu.java
public class MainMenu extends Fragment {
String testString;
int testInt;
TextView testTV;
private TextView tvDisplay;
private EditText departure;
private EditText destination;
private Geocoder geocoder;
private List<Address> departAddress;
private List<Address> destinationAddress;
private List<LatLng> geoPoints;
private String departString;
private String destinationString;
private Address departLocation;
private Address destinationLocation;
private LatLng departurePoint;
private LatLng destinationPoint;
private Context contextMain;
private GetData task;
public MainMenu()
{
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View root = (View) inflater.inflate(R.layout.main_menu, null);
geoPoints = new ArrayList<LatLng>(2);
return root;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
departure = (EditText) getView().findViewById(R.id.depart_field);
destination = (EditText) getView().findViewById(R.id.destination_field);
tvDisplay = (TextView) getView().findViewById(R.id.textView1);
}
public List<LatLng> getDirections(Context context)
{
contextMain = context;
geocoder = new Geocoder(getActivity());
departString = departure.getText().toString();
destinationString = destination.getText().toString();
try
{
task = new GetData(new Callback(){
public void run(Object result)
{
//return geoPoints;
}
});
task.execute((Void[])null);
}catch(Exception e)
{
e.printStackTrace();
}
return geoPoints;
}
public void clear()
{
departure.setText("");
destination.setText("");
tvDisplay.setText("Enter departure point, and destination point");
}
private class GetData extends AsyncTask<Void, Void, List<List<Address>>>
{
Callback callback;
private ProgressDialog processing;
public GetData(Callback callback)
{
this.callback = callback;
}
#Override
protected void onPreExecute()
{
processing = new ProgressDialog(contextMain);
processing.setTitle("Processing...");
processing.setMessage("Please wait.");
processing.setCancelable(false);
processing.setIndeterminate(true);
processing.show();
}
#Override
protected List<List<Address>> doInBackground(Void...arg0)
{
List<List<Address>> list = new ArrayList<List<Address>>(2);
try
{
departAddress = geocoder.getFromLocationName(departString, 5, 37.357059, -123.035889, 38.414862, -121.723022);
destinationAddress = geocoder.getFromLocationName(destinationString, 5, 37.357059, -123.035889, 38.414862, -121.723022);
list.add(departAddress);
list.add(destinationAddress);
}catch(IOException e)
{
e.printStackTrace();
}
return list;
}
#Override
protected void onPostExecute(List<List<Address>> list)
{
departLocation = list.get(0).get(0);
destinationLocation = list.get(1).get(0);
departurePoint = new LatLng(departLocation.getLatitude(), departLocation.getLongitude());
destinationPoint = new LatLng(destinationLocation.getLatitude(), destinationLocation.getLongitude());
if(geoPoints.size() >= 2)
{
geoPoints.clear();
}
geoPoints.add(departurePoint);
geoPoints.add(destinationPoint);
callback.run(list);
processing.dismiss();
}
}
}
#Override
protected Object doInBackground(Void...arg0)
{
Object result = null;
try
{
departAddress = geocoder.getFromLocationName(departString, 5, 37.357059, -123.035889, 38.414862, -121.723022);
destinationAddress = geocoder.getFromLocationName(destinationString, 5, 37.357059, -123.035889, 38.414862, -121.723022);
}catch(IOException e)
{
e.printStackTrace();
}
return result;
}
You never set the value of result...
I'm implementing an asyncTask class to load the data from server.
I have the data already and I want to pass it to the UI Thread, but I don't know how.
This is the code:
public class InboxHandler extends FragmentActivity implements OnLineSelectedListener {
static final int GET_CODE = 0;
private TextView textView3, textView2;
private Button button1, button2, button3;
private LinearLayout tab1, tab2, tab3;
private CheckBox cbVerPorCategoria;
private ActionBar actionBar;
private TextView txtTitle;
private Settings settings;
FragmentTransaction fragmentTransaction;
BottomPanel bottomPanel;
public List<OrderRequest> orderRequestArray;
private OrderRequestParser orderRequestParser;
public static int number;
int clickCounter = 0;
private boolean doubleBackToExitPressedOnce = false;
private static Context context;
DataLoader dataLoader;
private MyAsynckTask myAsynckTask;
public InboxHandler(){}
public List<OrderRequest> getOrderRequestArray() {
return orderRequestArray;
}
public void setOrderRequestArray(List<OrderRequest> orderRequestArray) {
this.orderRequestArray = orderRequestArray;
}
public static Context getContext()
{
return context;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inbox);
context = this.getApplicationContext();
settings = Settings.getInstance();
settings.setPrefs(getSharedPreferences(settings.getPREFERENCES(), Activity.MODE_PRIVATE));
settings.setPrefsEditor(settings.getPrefs().edit());
settings.getPrefsEditor().putBoolean("isLoggedIn", true);
settings.isVistaSimple = true;
actionBar = (ActionBar) findViewById(R.id.actionbar);
initComponents();
prepareActionBar();
}
private void initComponents() {
try {
MyAsynckTask myAsynckTask = new MyAsynckTask(this);
myAsynckTask.execute();
//HERE I USED A SUGGESTION IN A SIMILAR QUESTION. THAT IS: PASS THE ACTIVITY TO THE ASYNCTASK, AND FROM IT, SAVE IN THE ACTIVITY, THE DATA THAT IU WANT FROM THE ASYNCTASK. I DO THAT, BUT IN THE ACTIVITY, THE DATA IS NULL I SUPPOSE DUE TO, I DONT EVEN SEE IN THE LOGCAT, THE FOLLOWING RESULT:
try{
Log.e("e", ""+this.getOrderRequestArray().get(0).getDocNumber());
} catch(Exception e){
e.printStackTrace();
}
//If you see the onPostExecute, I test if the data I want is there. and it is there! I set that to the list of the class InboxHandler, but in the above code, when i try to test if it is there, it´s not. And that code don´t even appear in logcat. The "Log.e("e", ""+this.getOrderRequestArray().get(0).getDocNumber());" nor the "e.printStackTrace();"
bottomPanel =new BottomPanel();
Bundle bundle = new Bundle();
bundle.putSerializable("arrayPedidos", (Serializable) orderRequestArray);
bottomPanel.setArguments(bundle);
//actionBar.setTitle("Inbox");
NotificationFragment notificationFragment = new NotificationFragment(orderRequestArray, actionBar);
Bundle bundleNotificationFragment = new Bundle();
bundleNotificationFragment.putString("title", "Inbox");
notificationFragment.setArguments(bundleNotificationFragment);
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.frame_list_container, notificationFragment);
fragmentTransaction.add(R.id.frame_bottom_panel, bottomPanel);
fragmentTransaction.commit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private class MyAsynckTask extends AsyncTask {
private String stringMensaje;
public List<OrderRequest> orderRequestArray;
private OrderRequestParser orderRequestParser;
private Request request;
private Settings settings;
private InboxHandler inboxHandler;
public MyAsynckTask(InboxHandler inboxHandler){
this.inboxHandler = inboxHandler;
}
#Override
protected Object doInBackground(Object... params) {
List<OrderRequest> array = this.getOrderRequests();
settings = Settings.getInstance();
if(array != null){
settings.setOrderRequestArray(array);
orderRequestArray = array;
Log.e("orderRequestArray", "Me trajo el orderRequestArray en doInBackground!");
} else {
Log.e("orderRequestArray", "No me trajo el orderRequestArray en doInBackground!");
}
return array;
}
#Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
List<OrderRequest> array = (List<OrderRequest>) result;
this.setOrderRequestArray(array);
if(orderRequestArray != null){
inboxHandler.setOrderRequestArray(orderRequestArray);
Log.e("orderRequestArray", "is not null en onPostExecute!");
} else {
Log.e("orderRequestArray", "is null en onPostExecute!");
}
if(inboxHandler.getOrderRequestArray() != null){
Log.e("inboxHandler.getOrderRequestArray()", "is not null en onPostExecute!");
}
else {
Log.e("orderRequestArray", "is null en onPostExecute!");
}
}
public List<OrderRequest> getOrderRequests() {
orderRequestParser = new OrderRequestParser();
orderRequestArray = new ArrayList<OrderRequest>();
List<OrderRequest> orderRequestArray = orderRequestParser.listOrderRequest();
Settings.getInstance().setOrderRequestArray(orderRequestArray);
if(orderRequestArray != null){
Log.e("orderRequestArray", "Me trajo el orderRequestArray en getOrderRequestArray!");
} else {
Log.e("orderRequestArray", "No me trajo el orderRequestArray en getOrderRequestArray!");
}
return orderRequestArray;
}
public void setOrderRequestArray(List<OrderRequest> orderRequestArray) {
this.orderRequestArray = orderRequestArray;
}
public List<OrderRequest> getOrderRequestArray() {
return orderRequestArray;
}
}
protected void onPostExecute(Object result)
it is running in GUI thread, you can access GUI elements there.
and only there should be the:
try{
Log.e("e", ""+this.getOrderRequestArray().get(0).getDocNumber());
} catch(Exception e){
e.printStackTrace();
}
and
Bundle bundle = new Bundle();
bundle.putSerializable("arrayPedidos", (Serializable) orderRequestArray);
bottomPanel.setArguments(bundle);
I can't see any reason, why is this question down voted.