add to bundle without extract it - android

I have two classes. class A and class B. In class A, I put some strings into a bundle object and then send it to class B.
My question is here:
Can I put some string or int to this bundle directly without extracting it in class B and add extra info to it and then create a new Bundle.
*******EDIT*******
other scenario:
I have sent a bundle from intent service to activity then in activity I want to put some extra to this bundle and finally I'll send this bundle to background thread for saving on sharePreference. how could i do that?

Yes you can do that. So in your Class B, when you want to open Class C, you can get the bundle from previous intent and then go ahead and add to the same bundle and open C
Intent newIntent = new Intent(ActivityB.this, ActivityC.class);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
bundle.putString("newKey","newValue");
newIntent.putExtras(bundle);
}
startActivity(newIntent);
Update
since you want to pass this Bundle in BG thread and assuming you are using AsyncTask for that you can do following -
Declare your Async task as below -
class MyBGClass extends AsyncTask<Bundle,Void,Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Bundle... params) {
return null;
}
}
Then to call it you can do -
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
bundle.putString("newKey","newValue");
}
new MyBGClass().execute(bundle);
UPDATE 2:
To pass data from your resultReceiver -
receiver.send(RESULT_CODE, bundle);
Then in your activity where you would have passed this resultreceiver to your Service implement
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
//resultData is your bundle. to add to it -
if (resultData != null) {
resultData.putString("newKey","newValue");
}
}
Then call your BG thread.
Change the constructer of your WorkerThread class like below and pass bundle to your thread when you create the object of the class-
private class WorkerThread extends HandlerThread {
private static final int SAVE = 1;
PreferenceModel instancePreferenceModel;
Bundle bundle;
private Handler mHandler;
public WorkerThread(Bundle bundle) {
super("WorkerThread", Process.THREAD_PRIORITY_BACKGROUND);
App app = (App) getApplication();
this.bundle = bundle;
instancePreferenceModel = app.getInstancePreferenceModel();
}
#Override
protected void onLooperPrepared() {
super.onLooperPrepared();
mHandler = new Handler(getLooper()) {
#Override // receive message from uiThread as Bundle object.
public void handleMessage(Message msg) {
switch (msg.what) {
case SAVE:
Log.i(TAG, "handleMessage: saved completed");
Bundle data = (Bundle) msg.obj;
Log.i(TAG, "getData: " + data.getString(LoginIntentService.EXTRA_FIRST_NAME));
instancePreferenceModel.saveUserInfo(data);
break;
}
}
};
}
// this method is access to main ui thread.by this method UiThread can send a Message
// Background Thread
public void write(Bundle b) {
Message msg = new Message();
msg.obj = b;
Message obtain = Message.obtain(mHandler, SAVE, msg.obj);
mHandler.sendMessage(obtain);
}
}

Related

Activity bundle missing extras even though they should always be added in the newIntance method

I have an unexpected crash on my app in production. I have an activity that I always start using a newInstance method that add some extras to the intent :
public static Intent newInstance(final Context context, #NonNull final Location location) {
final Intent intent = new Intent(context, LocationActivity.class);
final Bundle extras = new Bundle();
extras.putParcelable(BUNDLE_ITEM_LOCATION, Location);
intent.putExtras(extras);
return intent;
}
And here is my onCreate method :
#Override
#CallSuper
public void onCreate(#Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Bundle extras = getIntent().getExtras();
if (extras == null || !extras.containsKey(BUNDLE_ITEM_LOCATION)) {
throw new IllegalArgumentException(LocationActivity.class.getName()
+ " must be created by using newInstance()");
}
[... Some other code ...]
}
And this IllegalArgumentException is thrown in production. It's super weird because this case should never happen. Any idea about the cause?
Thanks in advance.
Try this:
public static Intent newInstance(final Context context, #NonNull final Location location {
final Intent intent = new Intent(context, LocationActivity.class);
intent.putExtras(BUNDLE_ITEM_LOCATION, Location);
return intent;
}

receiving result from intent service inside custom adapter for listview

what i am trying to do is the following
I have a button inside my custom adapter layout that interact with php script on server to download a file on server
the download procedure is handled by calling an IntentService in the background
when the service is done i want to update my listview that is initiated inside an activity
i am stuck with the Receiver class
my code so far is as follow :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
if(IsRepository){
view = vi.inflate(R.layout.filerepositorylayout, null);
}
}
BindLayoutElemnts(view, position);
return view;
}
Here is where The Intent service is being called :
private void BindLayoutElemnts(View view, int position) {
myFiles = (files) getItem(position);
img_Download.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(),DownloadService.class);
intent.putExtra("FileID",""+myFiles.getID());
intent.putExtra("FileName",myFiles.getName());
context.startService(intent);
}
});
}
The calling activity
Here is where the Receiver is being called
public class user_repositry extends AppCompatActivity implements DownloadReceiver.Receiver {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myDownloadReceiver = new DownloadReceiver(new Handler());
myDownloadReceiver.setReceiver(this);
}
#Override
public void onReceiveResult(int resultCode, Bundle resultData) {
Toast.makeText(user_repositry.this, "Downloaded", Toast.LENGTH_SHORT).show();
}
The Intent service code :
ResultReceiver rec;
#Override
protected void onHandleIntent(Intent intent) {
rec = intent.getParcelableExtra("DownloadReceiver");
}
private void UpdateDBRecord() {
HashMap<String, String> PostData=new HashMap<String, String>();
PostData.put("call","UpdateFile");
PostData.put("ID", ""+file_ID);
BackgroundWorker registerWorker= new BackgroundWorker(this,this,PostData);
registerWorker.setShowLoadingMessage(false);
registerWorker.execute(Helper.getPhpHelperUrl());
}
this function is the function called in Post execute from the registerWorker above
#Override
public void processFinish(String results) {
Log.d("Download","Download DB updated");
Bundle bundle = new Bundle();
//bundle.putString("resultValue", "My Result Value. Passed in: " );
// Here we call send passing a resultCode and the bundle of extras
rec.send(Activity.RESULT_OK, bundle);
}
I am stuck with this error now :
Failed resolution of: Lcom/bassem/donateme/classes/DownloadReceiver;
I understood that the receiver is not being initiated but i can't seem to find the missing code in my logic
Appreciate your help
Try this,
Step 1: Create the result handler using ResultReceiver inside activity
public ResultReceiver downloadReceiver = new ResultReceiver(new Handler()) {
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
//Broadcast /send the result code in intent service based on your logic(success/error) handle with switch
switch (resultCode) {
case 1: {
//Get the resultData and do your logic here
//Update your list view item here
break;
}
case 2: {
//Get the resultData and do your logic here
//Update your list view item here
break;
}
}
}
};
Step 2: Put the result handler inside the intent and start the intent service
Intent intent = new Intent(getContext(), DownloadService.class);
intent.putExtra("receiver",downloadReceiver);
Step 3: Handle the intent in service class(get the value of result handler)
final ResultReceiver receiver;
#Override
protected void onHandleIntent(Intent intent) {
receiver = intent.getParcelableExtra("receiver");
}
Step 4: Send/Broadcast the data to the result handler
//based on your logic, change the result code and data
//Add your result data (success scenario)
Bundle bundle = new Bundle();
bundle.putString("result","Some text");
receiver.send(1,bundle);
//Add your result data (failure scenario)
receiver.send(0,bundle);
The missing code is not in your logic, it's in the logic of the DownloadReciever. Look for errors more broadly and figure out why that didn't load. That or publish some code from it so that it could be answered. Is it for example, looking for a uri that doesn't exist and thus crashes? What is it expecting and failing and why is it failing. You did not post any code that is crashing. You posted code that calls something that crashes.

How to check state of app optimally?

I develop android app. It needs save Internet data and login/password pair. I need to check that in every activity. How to do that optimally? My solution:
I create the BaseActivity class:
public class BaseActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkRequirements();
}
private void checkRequirements() {
if (needToCheckInternetConnection())
checkInternetConnection();
//check other requirements
}
private void checkInternetConnection() {
if (!Updater.getInstance(context).checkInternetConnection()) {
Bundle data = new Bundle();
data.putSerializable(SplashScreenActivity.FIELD_ACTION, SplashScreenActivity.Action.SHOW_TEXT);
data.putString(SplashScreenActivity.FIELD_TEXT, getString(R.string.splashScreenInternetNotAvailable));
changeActivity(SplashScreenActivity.class, data);
}
}
protected void changeActivity(Class<?> goTo, Bundle data) {
Intent intent = new Intent(context, goTo);
if (data != null)
intent.putExtras(data);
startActivity(intent);
finish();
}
}
And I extends all activity classes from this.
But finish() not working. So, how to change that architecture or force to work the finish() method?

Passing Object with multiple parts from one activity to another

Hi I have a Requirement like Person Details for that i have multiple details like personal,educational,job like In first activity am enter personal details and then educational and then job like that one after another for that how can i maintain all details in single object and pass through app please help me.
Be aware that you need to bundle an object in an Intent, that object must implement the Parcelable interface. Here's a common implementation taken from the Parcelable documentation...
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
Once you've done that, simply pass the object around in an Intent...
Intent i = new Intent(getApplicationContext(), ACTIVITY_TO_START.class);
i.putExtra("extra_key", new MyParcelable());
startActivity(i);
to retrieve the object for the starting activity...
Bundle extras = getIntent().getExtras();
if(extras != null && extras.containsKey("extra_key"))
{
MyParcelable p = (MyParecelable)extras.getParcelable("extra_key");
}
Simple solution: Use intents for this
Personal.class
public class Personal extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personal);
Intent i = new Intent(getApplicationContext(), Educational.class);
i.putExtra("personal_details",<-get data from object->);
startActivity(i);
}
}
Educational.class
public class Personal extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personal);
String personal_details;
Bundle extras = getIntent().getExtras();
if (extras != null) {
personal_details= extras.getString("personal_details");
}
Intent i = new Intent(getApplicationContext(), educational.class);
i.putExtra("personal_details",personal_details);
i.putExtra("educational_details",<-get data from object->);
startActivity(i);
}
}
Job.class
public class Personal extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personal);
String personal_details,educational_details;
Bundle extras = getIntent().getExtras();
if (extras != null) {
personal_details= extras.getString("personal_details");
educational_details= extras.getString("educational_details");
}
Intent i = new Intent(getApplicationContext(), FinalResult.class);
i.putExtra("personal_details",personal_details);
i.putExtra("educational_details",educational_details);
i.putExtra("job_details",<-get data from object->);
startActivity(i);
}
}
FinalResult.class
public class Personal extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personal);
String personal_details,educational_details,job_details;
Bundle extras = getIntent().getExtras();
if (extras != null) {
personal_details= extras.getString("personal_details");
educational_details= extras.getString("educational_details");
job_details= extras.getString("job_details");
}
}
}
{EDIT-1}
have a look at one of my answers in different storage options in
android - Click Here
You can achieve it using application variable or shared
preferences but i would not recommend it. !
Try storing it in POJO(Plain old Java class)
{EDIT-2}
Hmm if i understand correctly your question:: You are connected to internet(Wifi,Wired,... etc) basically you are trying to show a dialog when there is no network connectivity ! .... You can take the help of Broadcast receivers ...
Try this:: Set the broadcast receiver to fire the intent when there is no net connectivity ....
Write the code to catch that intent and pop the dialog .... In this dialog give the user option to reconnect the connectivity !

Android send data from activity to activity using bundle

i have to activities AnswerQuestion.java and SendAnswerToServer.java, and i want to send data from first activity to another one
on the AnswerQuestion activity i write this:
Bundle basket = new Bundle();
basket.putString("time", timeToAnswer+"");
Intent goToSendServer = new Intent(AnswerQuestion.this, SendAnswerToServer.class);
goToSendServer.putExtras(basket);
startActivity(goToSendServer);
my question what have i to write on the SendAnswerToServer activity , thank you
in SendAnswerToServer Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getIntent().getExtras();
if(bundle !=null)
{
//ObtainBundleData in the object
String strdata = bundle.getString("time");
//Do something here if data received
}
else
{
//Do something here if data not received
}

Categories

Resources