Displaying captured image in another activity - java

I am working on a android app and part of it requires the user to take a picture, the moment the user takes the picture it saves it to the file system and start a new activity to display the recent captured picture. The activity starts with no problem except it's blank!
When I hard-code the path into a string by typing the path manually, the image appears, so what's the problem?
This is the method of the saved file and creating the intent;
capturePicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
File f = capturePicture();
Intent intent = new
Intent(postSharingActivity.this, settingPostParam.class);
intent.putExtra("picture", f);
startActivity(intent);
}
});
This is the other activity and retrieving the image file;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting_post_param);
savedImage = findViewById(R.id.savedImage);
File pic = (File) getIntent().getExtras().get("picture");
Uri uri = Uri.fromFile(pic);
Toast.makeText(settingPostParam.this, "+uri.toString(),Toast.LENGTH_LONG)
.show();
if (isStoragePermissionGranted()) {
Picasso.get().load(uri).into(savedImage);
} else {
Toast.makeText(settingPostParam.this, "error", Toast.LENGTH_LONG).show();
}
}
UPDATE: I found the problem, it execute the intent before the capturePicture() complete. It takes the path before even the file is saved!
So i changed back to my original way, which is changing views not activities.
And added the AsyncTask.
private class myAsyncTask extends AsyncTask<Void,Void,Void>{
File f;
#Override
protected Void doInBackground(Void... voids) {
f= capturePicture();
return null;
}
#Override
protected void onPostExecute(Void result){
String rr = f.getAbsolutePath();
File g=new File(rr);
Toast.makeText(postSharingActivity.this,"onBloodyClick: "+g.toString(),Toast.LENGTH_LONG).show();
Uri uri = Uri.fromFile(g);
Toast.makeText(postSharingActivity.this,"URI :"+uri.toString(),Toast.LENGTH_LONG).show();
if(isStoragePermissionGranted()){
savedImage.setImageURI(uri);
cameraPreviewView.setVisibility(View.GONE);
postCaptureView.setVisibility(View.VISIBLE);
} else{
Toast.makeText(postSharingActivity.this,"error",Toast.LENGTH_LONG).show();
}
}
}
And here is the onClickListener
capturePicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new myAsyncTask().execute();
}
});
I've tested it and it is the same problem, the Toasts are in this order:
onBloodyClick: /storage/0/emulated/0/DCIM/Camera/IMG_20180604_104845.jpg
URI:file:////storage/0/emulated/0/DCIM/Camera/IMG_20180604_104845.jpg
Saved: /storage/0/emulated/0/DCIM/Camera/IMG_20180604_104845.jpg
The third one is in the capturePicture() method.
What am i doing wrong here? And thanks for replying.

Don't pass file object through intent, pass the path(String) of the file.
intent.putExtra("picture",f.getAbsolutePath());
And then, receive file path form this code
File pic = new File( getIntent().getStringExtras("picture"));

I found it.
The problem is in the calling of the methods and returning types.
The returning type of the method doInBackground and the params type of the two methods, the onPostExecute is going to use the resulting file of the doInBackground method
private class myAsyncTask extends AsyncTask<File,Void,File>{
#Override
protected File doInBackground(File... voids) {
File f = capturePicture();
return f;
}
#Override
protected void onPostExecute(File f){
String rr = f.getAbsolutePath();
File g=new File(rr);
Toast.makeText(postSharingActivity.this,"onBloodyClick: "+g.toString(),Toast.LENGTH_LONG).show();
Uri uri = Uri.fromFile(g);
Toast.makeText(postSharingActivity.this,"URI :"+uri.toString(),Toast.LENGTH_LONG).show();
if(isStoragePermissionGranted()){
savedImage.setImageURI(uri);
cameraPreviewView.setVisibility(View.GONE);
postCaptureView.setVisibility(View.VISIBLE);
} else{
Toast.makeText(postSharingActivity.this,"error",Toast.LENGTH_LONG).show();
}
}
}
And then on the onClickListener, you specify the order
capturePicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
myAsyncTask task=new myAsyncTask();
task.doInBackground();
task.execute();
}
});

Related

Set Receive Intent back to Default Value in Android using Java

FirstActivity.java
startActivity(new Intent(FirstActivity.this, SecondActivity.class)
.putExtra("passed_value", true));
SecondActivity.java
#Override
public void onPageFinished(final WebView view, String url) {
if(getIntent().getBooleanExtra("passed_value", false)){
}
}
After receiving intent value from FirstActivity.java every reload it runs the if block . But i need this intent to run only in onPageFinished method.
So how to run if block only when it comes from FirstActivity.java. Is there any way so that i can make this intent value back to default value after if block executed?
In your SecondActivity create a class level variable as boolean passed_value = false;
Then in your onCreate(), change its value like - passed_value = getIntent().getBooleanExtra("passed_value", false);
Finally you can use it like -
#Override
public void onPageFinished(final WebView view, String url) {
if(passed_value){
}
}
A fairly straight forward method would be to have a Boolean passedValue variable that you instantiate with the intent extra in onCreate, and then set as false in the if block. Something along the following lines should work,
public class SecondActivity extends AppCompatActivity {
Boolean passedValue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
passedValue = getIntent().getBooleanExtra("passed_value", false);
//Other code things
}
#Override
public void onPageFinished(final WebView view, String url) {
if(passedValue){
//Do what you need to do
passedValue = false
}
}
}

How do I add data I have keyed in a EditText box into an array to list in another activity?

Below are the 3 java classes which I am using for my android application development. I would like to add the student data (name and phone number) from the AddActivity to be stored in MainActivity page after clicking "Add". I have researched on this and tried using an array. But I am quite confused on how the logic must be for the code to send the data keyed in AddActivity into the MainActivity page. Can anyone give me a guidance on how to work this out and would really be grateful if you could show me another way rather the way I am trying. I want the data to be stored in a ListView format in the MainActivity after each "Add" I have clicked in the AddActivity page. I do hope that someone will be able to guide me in doing this. Thank you.
MainActivity.java -
https://jsfiddle.net/eb1fprnn/
public class MainActivity extends AppCompatActivity {
ListView listView;
Button addStudent;
ArrayList<Student> students = new ArrayList<Student>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
add();
}
public void add() {
Student student;
addStudent = (Button) findViewById(R.id.add);
addStudent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
startActivity(intent);
}
});
}
}
AddActivity.java -
https://jsfiddle.net/40k5mas2/
public class AddActivity extends AppCompatActivity {
EditText name, phone;
Button add;
int FphoneNumber;
String Fname;
ArrayList<Student> students;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
students = (ArrayList<Student>) getIntent().getSerializableExtra("AddNewStudent");
setContentView(R.layout.activity_add);
edit();
addStudent();
}
public void edit() {
name = (EditText) findViewById(R.id.StudentName);
phone = (EditText) findViewById(R.id.phone);
final Button addStudent = (Button) findViewById(R.id.AddStudent);
name.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
addStudent.setEnabled(!name.getText().toString().trim().isEmpty());
Fname = name.getText().toString();
String phoneNumber = phone.getText().toString();
FphoneNumber = Integer.parseInt(phoneNumber);
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
public void addStudent() {
add = (Button) findViewById(R.id.AddStudent);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(AddActivity.this, MainActivity.class);
intent.putExtra("studentName",name.getText().toString() );
intent.putExtra("phoneNumber",phone.getText().toString());
startActivity(intent);
Student student = new Student(Fname, FphoneNumber);
students.add(student);
}
});
}
public void addStudent(){
add = (Button) findViewById(R.id.AddStudent);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(AddActivity.this,Record.class);
startActivity(intent);
}
});
}
Student.java -
https://jsfiddle.net/gy0g7b0s/
public class Student {
String mName;
int mPhoneNumber;
public Student (String name, int number){
mName = name;
mPhoneNumber = number;
};
public String getmName() {
return mName;
}
public String getmName(String newName) {
return (this.mName = newName);
}
public int getmPhoneNumber() {
return this.mPhoneNumber;
}
public int getmPhoneNumber(int newPhoneNumber) {
return (this.mPhoneNumber = newPhoneNumber);
}
#Override
public String toString() {
return String.format("%s\t%f",this.mName, this.mPhoneNumber);
}
[1] : [Image of Main Activity Page] http://imgur.com/a/pMWt4
[2] : [Image of Add Activity Page] http://imgur.com/a/8YvVc
as mentioned above, the correct way would be to use the startActivityForResult method. Check this.
And how to go about it, Damn easy!
Modifying your code:
public void add() {
Student student;
addStudent = (Button) findViewById(R.id.add);
addStudent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
startActivityForResult(intent,123);
}
});
}
}
and in the same activity (MainActivity) listen for the result
Also would recommend you to use the parceler.org lib for sending objects
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode== Activity.RESULT_OK && requestCode==123){
// perform your list addition operation here and notify the adapter for change
// the returned data comes in 'data' parameter and would recommend you to use parcels.org lib
// for sending parcelable pojo across activities and fragments.
list.add(Parcels.unwrap(data.getParcelableArrayExtra(YOUR_KEY)));
adapter.notifyDataSetChanged();
}
}
And in your AddActivity, when you add just do this.
public void addStudent() {
// add the 'add' button view to the oncreatemethod
// add = (Button) findViewById(R.id.AddStudent);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do not restart the activity that opened this activty
// this activity is anyways on top of the MainActivity. Just finish this activty setting the result
// Intent intent = new Intent(AddActivity.this, MainActivity.class);
// intent.putExtra("studentName",name.getText().toString() );
// intent.putExtra("phoneNumber",phone.getText().toString());
// startActivity(intent);
// How to do that?
Student student = new Student(Fname, FphoneNumber);
Intent intent = new Intent();
intent.putExtra(YOUR_KEY, Parcels.wrap(student));
// you can also do it without the parcels lib
// intent.putExtra("studentName",name.getText().toString() );
// intent.putExtra("phoneNumber",phone.getText().toString());
setResult(123,intent); // set the result code. it should be the same one as the one your listening on in MainAcitivty
// then just finish this activity.
finish();
// this calls the onActivtyResultMethod in MainActivity which furtther does the logic
// students.add(student);
}
});
}
That should work! Cheers!
Use StartActivityForResult for AddActivity and return object from here and use in MainActivity. For example see here
Since you store the data in a file, the add activity should just write the data to the file. Then the main activity should always read the file to refresh the list.
I will suggest using a static class if you don't want to use a Database.
Or if you should use a file is just very simple to write into a file when you add and read from it in the next activity.
Just create a Static class like this.
public static class MyStaticClass{
private static ArrayList <Student> mStudents = new ArrayList<Student>()
public static void addStudent(Student theNewStudent){
mSudents.add(theNewStudent);
}
public static List<Student> getStudents(){
return mStudents;
}
}
or with a file:
public static class MyFileClass{
private static String pathFile = "Your path";
public static void addStudent(Student theNewStudent){
File file = new OutputStreamWriter(new FileOutputStream(pathFile,true)); //the true is to append to the file
file.write(/*parse your student as a string*/);
file.close();
}
public static List<Student> getStudents(){
ArrayList<Student> students = new ArrayList<>()
File file = new File(pathFile);
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String line = sc.nextLine();
//parse your line to a student object
students.add(yourNewStudent);
}
sc.close();
return students;
}
}
Just call the add student and the get students in the proper class as follows.
MyStaticClass.addStudent(student);
or
MyFileClass.addStudent(student);
Hope it helps.
In your onclick listener:
public void onClick(View v) {
Intent intent = new Intent(AddActivity.this, MainActivity.class);
Student student = new Student(Fname, FphoneNumber);
MyStaticClass.addStudent(student); // or the FileClass
startActivity(intent);
}
and i cant see where do you retrieve the list. but just use the getStudents of the class.
Intent yourFirstAct= new Intent(firstAct.this,second.class);
yourFirstAct.putExtra("","");
startActivitForResult(yourFirstAct);
in first Activity,
#Override
public void onAcitivityResult(....){
super();
}
in your second activity when you done,
do your stuff whatever you want in second activity. and pass it to mainActivity
Intent yoursecAct= new Intent();
yourSecAct.putExtra("","");
setResult(yourSecAct);
finish();
IF YOU ARE USING IN FRAGMENT
if you do startActivityResult() in fragment means,
your fragment mainActivity must return super() in
public void onAcitivityResult(...){super()}
After getting the details from the student, put the respective details in a bundle and just use intent to go back to the main activity. Then use bundles to extract the data in the main activity.
You can use startActivityForResult for the same. if you haven't found the answer yet then please let me know. I will provide you the code.
Many above answers already defined this thing in a very good way.
This is about communication between Activities. You can use event bus to realize this.
https://github.com/JackZhangqj/EventBus
Then 1. Add event bus dependency to the App's build.grade
compile "de.greenrobot:eventbus:3.0.0
Register and unregister your subscribe in the MainActivity.java
#Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
3.Post event in the AddActivity.java
EventBus.getDefault().post(new Student(name.getText().toString(), phone.getText().toString()));
4.Implement event handling method in MainActivity
//The student is the added student in the AddActivity.java
public void onEventMainThread(Student student) {
}
To kind of expand a little bit on MadScientist's answer, ListView's need adapters in order set the data in it's view. You'll need to define an ArrayAdapter for your list view to communicate with. This will need to go in your MainActivity and will be initialized in the onCreate method. Assuming you want to display both types of information, you'll need to construct your adapter with the built in layout for showing two items via android.R.layout.simple_list_item_2. If you would like to create your own layout, however, you can look up how to do that here.
public class MainActivity extends AppCompatActivity {
Button addStudent;
ArrayAdapter<Student> adapter;
ArrayList<Student> students = new ArrayList<Student>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_2, students);
ListView listView = (ListView) findViewById(R.id.listView);
listView.addAdapter(adapter);
add();
}
Call the startActivityForResult(intent, 123) in your Listener to start the new activity. Then, once you have typed in your data, add your items to the intent and call finish() in your AddActivity. Override the onActivityResult in your MainActivity to pull the items off your intent and add them to your list. Finally, notify the adapter of the changes via adapter.notifyDataSetChanged()

How initialize correctly static variable in PreferenceActivity

I have Preference class extent PreferenceActivity.
I create public static String quality; in Preference.class i add in onCreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref);
quality = "QUALITY_HIGH";//initialize
}
and add in Preference.class this method
public void getQuality() {
if (keyquality.equals("480p")) {
quality = "QUALITY_LOW";
//
}
if (keyquality.equals("720p")) {
//
quality = "QUALITY_720P";
}
if (keyquality.equals("1080p")) {
//
quality = "QUALITY_HIGH";
}
}
in another class i create method to get my variable and set settings
private void getqualityvideo() {
/*if (Prefernce.quality == null) {
preferencecamrecoder = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
} else {*/
if (Prefernce.quality.equals("QUALITY_LOW")) {
preferencecamrecoder = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
}
if (Prefernce.quality.equals("QUALITY_720P")) {
preferencecamrecoder = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
}
if (Prefernce.quality.equals("QUALITY_HIGH")) {
preferencecamrecoder = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
}
// }
}
Problem:
when start application
private void startServes() {
btnStart = (ImageView) findViewById(R.id.StartService);
btnStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
v.startAnimation(mAnimationImage);
Intent intent = new Intent(MainActivity.this, RecorderService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(intent);
changeCamera
.setEnabled(false);
btnStart.setEnabled(false);
setings.setEnabled(false);
moveTaskToBack(false);
}
});
}
in another class in method
getqualityvideo() error NullPointerException
error in this first line
if (Prefernce.quality.equals("QUALITY_LOW"))
why the quality variable is empty?
The reason is that you're setting Preference.quality in the onCreate method in your Preference class. So what's probably happening is that when you start your application in your other class, Preference.quality is going to be null because it was never initialized to anything. The reason is that the other class has no way to access the onCreate method in your Preference class as of now. onCreate is executed when an activity starts, but that doesn't seem to happen anywhere in your code. A solution could be to initialize public static String quality outside of your onCreate method but still within the Preference class,
public static String quality = "QUALITY_HIGH";
#Override
public void onCreate(Bundle savedInstanceState) {
//insert code here
}
The problem was merely a scope issue.

Can't play this video error

public class MainActivity extends AppCompatActivity {
Button clk;
VideoView videov;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
clk=(Button) findViewById(R.id.video);
videov=(VideoView)findViewById(R.id.videoView);
}
public void videoplay(View v){
String videopath = "android.resource://"+getPackageName()+"+R.raw.movie";
Uri uri =Uri.parse(videopath);
videov.setVideoURI(uri);
videov.requestFocus();
videov.start();
}
}
Can't play this video error...!! see the picture Screen Shot
What to do ?
After pressing play button it says cant play this video..!!
Need solution of this problem.
Hi day before yesterday i had same problem and tried almost everything but didn't get any success. After that i used this library and it work fine. Just follow few steps:
Step1. Add it to your gradle
compile "fm.jiecao:jiecaovideoplayer:4.7.0"
Step2. Add it as your video play in xml layout.
<fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard
android:id="#+id/videoPlayer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Step 3. Check from here how to use this library in your class,
public class PlayVideoActivity extends BaseActivity {
#BindView(R.id.videoPlayer)
JCVideoPlayerStandard mVideoPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
restoreFromIntent(getIntent());
}
#Override
public int getLayout() {
return R.layout.activity_play_video;
}
//create intent for this activity with all the necessary params
public static Intent createIntent(Context context, String videoUrl) {
Intent intent = new Intent(context, PlayVideoActivity.class);
intent.putExtra(ValueConstants.VIDEO_URL, videoUrl);
return intent;
}
// get video path from intent and play the video here
private void restoreFromIntent(Intent intent) {
String videoPath = intent.getExtras().getString(ValueConstants.VIDEO_URL);
mVideoPlayer.setUp(videoPath
, JCVideoPlayerStandard.SCREEN_LAYOUT_LIST, "");
}
#Override
public void onBackPressed() {
if (JCVideoPlayer.backPress()) {
return;
}
super.onBackPressed();
}
#Override
protected void onPause() {
super.onPause();
JCVideoPlayer.releaseAllVideos();
}
}
One more bonus thing from my side. You can do video cache also by using this library. Yesterday i found this also.One time play from internet.After it play without internet also.
Updated answer:
Above example i have provided for playing online videos from url but this question have problem related to video path problem.
Just Changed this path:
String videopath = "android.resource://"+getPackageName()+"+R.raw.movie";
Uri uri =Uri.parse(videopath);
To this,
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.yourvideo);
Thanks hope this will help you.

Show ProgressDialog during a network call until it's FINISHED

I am very frustrated as I've been trying to implement a super simple loading wheel while waiting on a network call. I have searched and read dozens of SO questions and I just feel like I must be missing something, unless nobody really does what I'm trying to do. I have tried going down the AsyncTask route, but that's not what I want.
Let me also say that right now my app works perfectly, it's just that the transition from screen to screen appears to hang as it waits on the network. I just want a loading wheel so that in the 1-2 seconds the user knows the app is working and didn't freeze.
Here's what my current network call looks like:
private static String sendDataToServer(String arg1, String arg2)
{
Thread dbThread = new Thread()
{
public void run()
{
// do the call that takes a long time
}
};
dbThread.start();
try {
// I do this so that my program doesn't continue until
// the network call is done and I have received the information
// I need to render my next screen
dbThread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
Now, why can't I just add the ProgressDialog like this? If I do this, the progressDialog never appears.
private static String sendDataToServer(String arg1, String arg2)
{
final ProgressDialog progress = new ProgressDialog(BaseActivity.getInstance());
progress.setIndeterminate(true);
progress.setMessage("Loading...");
progress.show();
Thread dbThread = new Thread()
{
public void run()
{
// do the call that takes a long time
}
};
dbThread.start();
try {
dbThread.join();
progress.dismiss();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
I think I'm stuck because the network call needs to be on a separate thread from the UI thread, yet I don't want to continue in my application because I need the results of that call to continue. But if I do thread.join() I hold up everything. I thought I needed AsyncTask but that went downhill quickly. Here's my question on that if you're curious.
Android's AsyncTask: multiple params, returning values, waiting
How the heck to I just show a loading dialog while this call happens without proceeding through the rest of my application?
EDIT
Here's my AsyncTask attempt.
private class PostToFile extends AsyncTask<PostToFile, Void, Void>{
private String functionName;
private ArrayList<NameValuePair> postKeyValuePairs;
private String result = "";
public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
functionName= function;
postKeyValuePairs = keyValuePairs;
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(BaseActivity.getInstance(), "Loading", "Please wait...", true, false);
}
#Override
protected Void doInBackground(PostToFile... params) {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair(FUNCTION_KEYWORD, functionName));
for (int i = 0; i < postKeyValuePairs.size(); i++) {
nameValuePairs.add(postKeyValuePairs.get(i));
}
try{
// ***do the POST magic.***
result = response.toString();
}
catch (Exception e){
// clean up my mess
}
return null;
}
private String getResult(){
return result; // can I use this somehow???
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
And when I use it:
new PostToPHP(FUNCTION_NAME, postPairings){
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try
{
if (result != null && !result.startsWith("null"))
{
JSONArray jArray = new JSONArray(result);
parseData(jArray);
}
}
catch (JSONException e)
{
Log.e(Constants.LOG_TAG, e.toString());
}
};
}.execute()
The problem is, I have a couple of these calls back to back, and they're each dependent on each other. So the first one starts, and the second one starts immediately after the first one starts, but before the first one is finished. So I get erroneous behavior. How can I start the second call only after the first is completely done?
Maybe this will work, I haven't tested, but you can try:
public class MyTask extends AsyncTask<String, Void, String> {
private int flag;
public MyTask(int flag) {
this.flag = flag;
}
#Override
protected String doInBackground(String... params) {
switch (flag) {
case 1:
return doNetworking1();
break;
case 2:
return doNetworking2();
break;
case 3:
return doNetworking3();
break;
default:
return doNetworking1();
}
}
#Override
protected void onPreExecute() {
//show progress dialog
}
#Override
protected void onPostExecute(String s) {
//hide progress dialog
switch (flag) {
case 1: //do something with result
new MyTask(2).execute();
break;
case 2: //do other stuff
new MyTask(3).execute();
break;
case 3: //do event more stuff
break;
default:
//do something
}
}
}
and usage:
new MyTask(1).execute();
In cases of network connections I would use IntentService instead of AsyncTask.
For example create IntentServices for network connection:
public class NetworkCallIntentService extends IntentService {
public static final String BROADCAST_ACTION = "com.yourpackage:NETWORK_CALL_BROADCAST";
public static final String RESULT = "com.yourpackage:NETWORK_CALL_RESULT";
public NetworkCallIntentService() {
super(NetworkCallIntentService.class.getSimpleName());
}
#Override
protected void onHandleIntent(Intent intent) {
// get data from intent if needed
// do the call that takes long time
// send broadcast when done
Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra(RESULT, "some_result");//and more results
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Next, start that service from activity, show progress dialog and move code responsible for showing next screen to BroadcastReceiver#onReceive() method:
public class SomeActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//start service
Intent serviceIntent = new Intent(this, NetworkCallIntentService.class);
//put extras into intent if needed
//serviceIntent.putExtra("some_key", "some_string_value");
startService(serviceIntent);
//here just show progress bar/progress dialog
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mNetworkCallReceiver,
new IntentFilter(NetworkCallIntentService.BROADCAST_ACTION));
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mNetworkCallReceiver);
}
private BroadcastReceiver mNetworkCallReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//hide progress bar/progress dialog
//here get results from intent extras
String result = intent.getStringExtra(NetworkCallIntentService.RESULT);
//process results and continue program(go to next screen, show error message etc.)
}
}
}
Declare service in manifest file:
<service
android:name="com.yourpackage.DownloadSvtValuesIntentService"
android:exported="false" >
</service>

Categories

Resources