Check if intent is calling or Activity is started by default - android

how can I check if Activity is started by default or a method of the Activity is called from an intent in an other activity?
I think at the moment my Code is very bad, because i handle it over a Try/Catch
It works fine, but i want better code
public class MyScan extends Activity {
public final static String EXTRA_MESSAGE = ".MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkIntent();
}
public void checkIntent() {
try {
Intent i = getIntent();
String method_name = i.getStringExtra("method_name");// is firing an error if there is no intent call
if (method_name.equals("scanBarcode")) {
scanBarcode2();// That starts my method
}
} catch (Exception e) {
setContentView(R.layout.activity_my_scan); // that shows just my Content
}
}
....
Thanky you for your hint Alex Terreaux
i changed the code this way
public void checkIntent() {
Intent i = getIntent();
if (i != null) {
String method_name = i.getStringExtra("method_name");
if (method_name != null && method_name.equals("scanBarcode")) {
scanBarcode2();
} else {
setContentView(R.layout.activity_my_scan);
}
}
}
and that works.

Try checking if the result of getIntent() is null.

You could use extras. In strings.xml add a new string:
<string name="starting_from_intent">STARTING_FROM_INTENT</string>
In the file where you are starting the activity by intent you can use:
intent.putExtra(getString(R.string.starting_from_intent), 1);
Then, in the checkIntent(), do:
boolean startedFromIntent;
Intent i = getIntent();
if (i.getIntExtra(getString(R.string.starting_from_intent), 0) == null
|| i.getIntExtra(getString(R.string.starting_from_intent), 0) == 0)
startedFromIntent = false;
else
startedFromIntent = true;
Hope this wasn't too hard to understand and hope this helps.

When your activity was started just by startActivity() a getCallingActivity() method in target activity will return null.
When it was called by startActivityForResult() it will return name of calling activity.

Related

Go to another activity when error is thrown by catch() in AsyncTask

This is my AsyncTask:
public class GetDataTask extends AsyncTask<Void, Void, JSONArray> {
#Override
protected void onPreExecute() {
// [...]
}
#Override
protected void onPostExecute(JSONArray result) {
int result_length = 0;
try {
result_length = result.length();
} catch (NullPointerException e) {
e.printStackTrace();
// Redirect the user back to the original activity
Intent intent = new Intent(ResultActivity.this, MainActivity.class);
startActivity(intent);
}
for (int i = 0; i < result_length; i++) {
// [...]
}
}
#Override
protected JSONArray doInBackground(Void... params) {
// [...]
}
}
When result is null, .length() throws a NullPointerException. That's why I want to redirect the url back to MainActivity when this happen.
try {
result_length = result.length();
} catch (NullPointerException e) {
e.printStackTrace();
// Redirect the user back to the original activity
Intent intent = new Intent(ResultActivity.this, MainActivity.class);
startActivity(intent);
The problem is that it doesn't work. I get e.printStackTrace() but the activity doesn't change. It's like Intent is not "fast" enough to change activity, and the code below (for (int i = 0; i < result_length; i++) {}) still keeps running.
What can I do? Is my solution wrong? Thank you in advance.
In the AsyncTask contructor provide the Activity reference.
private Activity activity;
public GetDataTask (Activity activity) {
this.activity = activity;
}
then you can call it like this
activity.startActivity(new Intent(activity, MainActivity.class));
It's like Intent is not "fast" enough to change activity
When you launch an activity via startActivity(), you are not immediately spawning that action. You are just kindly asking the framework to launch the specified activity for you. And it doesn't mean, that after startActivity() the code below it wouldn't be called. The executor will continue to execute the code until the end of scope. If you want to stop execution afterward you have to return immediately after startActivity().
Personally, catch (NullPointerException ) is always wrong. Plus if (variable == null) is arguably faster.
AsyncTask should just return; or stop, not necessarily start anything.
Another suggestion: Make sure that doInBackground returns an empty JSONArray instead of null.
and the code below (for (int i = 0; i < result_length; i++) {}) still keeps running
Sure, because the for loop is not inside the try block...
try {
result_length = result.length();
} catch (NullPointerException e) {
e.printStackTrace();
// Redirect the user back to the original activity
Intent intent = new Intent(ResultActivity.this, MainActivity.class);
startActivity(intent);
}
// The result is still null here...
Replace all catching with a simpler null check and simply don't let the loop be entered.
#Override
protected void onPostExecute(JSONArray result) {
int result_length = result == null ? 0 : result.length();
for (int i = 0; i < result_length; i++) {
// This loop won't run when the result is null...
}
If you really want to, then check if (result_length == 0), but again, the Activity should be called back to when the result finishes, and then you can start some other activity.
Ref: How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

Android: Memory Leak

I am using the code below in my activity class:
public static Activity list_Addresses_Activity;
And in my onCreate I used from this :
list_Addresses_Activity = this;
But it throws an error stated below:
Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
I need to use it from static because I will use from this in my Service class.
My CloseActivies.class :
public class CloseActivies {
Activity a;
Activity b;
Activity c;
protected void CLSActivities(Activity ListAddresses, Activity ListOrder, Activity SendReports) {
a = ListAddresses;
b = ListOrder;
c = SendReports;
if (ListAddressesActivity.FlagLiveAddress && a != null) {
Log.e("ADASFSDAGWEG", "X");
a.finish();
ListAddressesActivity.FlagLiveAddress = false;
}
if (ListOrderActivity.FlagLiveOrder && b != null) {
Log.e("ADASFSDAGWEG", "Y");
b.finish();
ListOrderActivity.FlagLiveOrder = false;
}
if (SendReportsActivity.FlagSendReport && c != null) {
Log.e("ADASFSDAGWEG", "Z");
c.finish();
SendReportsActivity.FlagSendReport = false;
}
}
protected void CLSActivities() {
if (ListAddressesActivity.FlagLiveAddress && a != null) {
Log.e("ADASFSDAGWEG", "X");
a.finish();
ListAddressesActivity.FlagLiveAddress = false;
}
if (ListOrderActivity.FlagLiveOrder && b != null) {
Log.e("ADASFSDAGWEG", "Y");
b.finish();
ListOrderActivity.FlagLiveOrder = false;
}
if (SendReportsActivity.FlagSendReport && c != null) {
Log.e("ADASFSDAGWEG", "Z");
c.finish();
SendReportsActivity.FlagSendReport = false;
}
}
}
It will cause a memory leak as your service class is working on a separate thread and passing a static reference to your activity will keep the instance in memory even if the activity is dismissed and not garbage collected, a safer way to do this is passing a reference of your activity as a parameter to your service and storing it in a weakreference something like this
public class MyIntentService extends IntentService {
private final WeakReference<Context> mContextWeakReference;
public MyIntentService() {
super("MyIntentService");
}
public static void startActionFoo(Context context) {
mContextWeakReference = new WeakReference<>(context);
Intent intent = new Intent(context, MyIntentService.class);
context.startService(intent);
}
#Override
protected void onHandleIntent(Intent intent) {
Context context = mContextWeakReference.get();
if(context != null) {
//do your work as since context is not null means
//activity is still present and if activity is dismissed
//context will come null
}
}
}
If you need activity reference for one of its static variable you can pass it in intent extras, or you want to call a static function of activity, a broadcast receiver would be a better choice to do this.
If you are starting service from activity and use some data of activity in that service. You can pass them in intent.
Intent intent = new Intent(this,MyService.class);
intent.putExtra("data", "some_value");
startService(intent);

How to get string value from string array in Android

I am trying to create an application that reads an NFC tag and checks the tag against strings in a string array and then sets the text on another activity. I have got it working so that it checks if the string exists and sets the text in the new activity, but I want to be able to specify which string I want it to check against within the array, because there will be multiple strings in the NFC tag that I want to then display in the new activity. I have tried this for it:
result == getResources().getString(R.string.test_dd)
Here is the relevant code:
String[] dd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dd = getResources().getStringArray(R.array.device_description);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
if(doesArrayContain(dd, result)) {
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(800);
Intent newIntent = new Intent(getApplicationContext(), TabsTest.class);
Bundle bundle1 = new Bundle();
bundle1.putString("key", result);
newIntent.putExtras(bundle1);
startActivity(newIntent);
Toast.makeText(getApplicationContext(), "NFC tag written successfully!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), result + " is not in the device description!", Toast.LENGTH_SHORT).show();
}
}
}
EDIT:
Here is the method used and please can anyone help me with this problem:
public static boolean doesArrayContain(String[] array, String text) {
for (String element : array) {
if(element != null && element.equalsIgnoreCase(text)) {
return true;
}
}
return false;
}
For comparing equality of strings (and other objects) use the equals() method. == compares identity of objects (same string object).
Here is the solution that I found:
Create a new method:
public static boolean stringCaseInsensitive(String string, String result) {
if(string != null && string.equalsIgnoreCase(result)) {
return true;
}
return false;
}
And call it in like this:
if(stringCaseInsensitive(getResources().getString(R.string.test_dd), result))
{
Intent newIntent = new Intent(getApplicationContext(), TabsTest.class);
Bundle bundle1 = new Bundle();
bundle1.putString("key", result);
newIntent.putExtras(bundle1);
startActivity(newIntent);
Toast.makeText(getApplicationContext(), "NFC tag written successfully!", Toast.LENGTH_SHORT).show();
}
else{
}

Android - Trouble passing variables between activities using intents

I'm new to Android and I'm just trying to pass two doubles from one activity to another. This question has been asked several different times on this site in several different ways, but something about my implementation is causing my app to force close. I think my problem may be with my "savedInstanceState" Bundle in the activity I'm trying to pass the variables to. I left out a lot of code obviously, but I included all the places where Bundles are used.
[EDIT] - I found a bad programming solution for what I need to do. I put public static variables in the receiving class and access them from the sending class. I realize this is bad programming, but it does what I want. Thanks to all who tried to help. I'm going to continue to try to do this the proper way.
Without the i.putExtra lines and any lines involving the Bundle extra, it works fine. Here's the code:
int lat = 0;
int lon = 0;
private void createNote() {
Intent i = new Intent(this, NoteEdit.class);
i.putExtra("lat", lat);
i.putExtra("lon", lon);
startActivityForResult(i, ACTIVITY_CREATE);
}
This is the activity I sent them to:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extra = getIntent().getExtras();
int lat = extra.getInt("lat");
int lon = extra.getInt("lon");
mRowId = (savedInstanceState == null) ? null : (Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
if (mRowId == null) {
Bundle extras = getIntent().getExtras();
mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) : null;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId);
}
#Override
protected void onPause() {
super.onPause();
saveState();
}
#Override
protected void onResume() {
super.onResume();
populateFields();
}
private void saveState() {
String title = mTitleText.getText().toString();
String body = mBodyText.getText().toString();
String lattitude = mLatText.getText().toString();
String longitude = mLonText.getText().toString();
String date = mDateText.getText().toString();
String time = mTimeText.getText().toString();
if (mRowId == null) {
long id = mDbHelper.createNote(title, body, lattitude, longitude, date, time);
if (id > 0) {
mRowId = id;
}
} else {
mDbHelper.updateNote(mRowId, title, body, lattitude, longitude, date, time);
}
}
This is how you should pass values.
Bundle bundle = new Bundle();
bundle.putString("str1", str1);
bundle.putInt("int1", int1);
bundle.putDouble("double1", double1);
Intent i = new Intent(this, Activity2.class);
i.putExtras(bundle);
startActivityForResult(i);
And this is how you get them in next activity
int int1 = getIntent().getExtras().getInt("int1")
String str1 = getIntent().getExtras().getString("str1")
double double1 = getIntent().getExtras().getDouble("double1")
does this clear your doubts?
The looks fine, you problem is someplace else.
Try adding prints before setting the intent to make sure your key and value are what you really think they are
int name = getIntent().getExtras().getInt(key);
You are calling startActivityforresult.so try getting the bundle in onActivityResult not in oncreate.you can override this onActivityResult
I think this is the problem try getting the bundle using this.you will get the value to this new variable.

Can't start an activity in application onCreate

I am trying to start an activity after n seconds with a handler. The application was crashing on the startActivity call, so I put the handler code in my application's onCreate, and it is still crashing (which makes me think that the error comes from me not using startActivity well) :
#Override
public void onCreate(){
String roomName = this.getSettingValue(R.string.PREFERENCES_ROOM_NAME, "");
Room room;
try {
room = this.getRoomWithName(roomName);
} catch (ReservatorException ex) {
Toast err = Toast.makeText(this, ex.getMessage(),
Toast.LENGTH_LONG);
err.show();
return;
}
Intent i = new Intent(this, RoomActivity.class);
i.putExtra("room", room);
this.startActivity(i);
}
Strange thing is that this work when called from a view, by using exactly the same code, but different context :
Intent i = new Intent(getContext(), RoomActivity.class);
// ...
I am pretty new to Android ... so there may be information missing in that question, or I might even be trying to do something completely stupid who knows ?
EDIT
Link to the stacktrace : http://pastebin.com/vh2QC3xz
EDIT2
Here is the handler version of my code (so what I am trying to do in the end) :
public class ReservatorApplication extends Application {
private GoToFavouriteRoom goToFavouriteRoomRunable;
class GoToFavouriteRoom implements Runnable {
ReservatorApplication app;
public GoToFavouriteRoom(ReservatorApplication anApp){
app = anApp;
}
#Override
public void run() {
String roomName = app.getSettingValue(R.string.PREFERENCES_ROOM_NAME, "");
Room room;
try {
room = app.getDataProxy().getRoomWithName(roomName);
} catch (ReservatorException ex) {
Toast err = Toast.makeText(app, ex.getMessage(),
Toast.LENGTH_LONG);
err.show();
return;
}
RoomActivity.startWith(app, room);
}
}
private final ReservatorAppHandler handler = new ReservatorAppHandler();
class ReservatorAppHandler extends Handler{
#Override
public void handleMessage(Message msg){
return;
}
}
#Override
public void onCreate(){
String serverAddress = getSettingValue(R.string.PREFERENCES_SERVER_ADDRESS, "mail.futurice.com");// TODO: change to mail.futurice.com before delivery
proxy = new SoapDataProxy(serverAddress);
// proxy = new DummyDataProxy();
proxy = new CachedDataProxy(proxy);
addressBook = new FumAddressBook();
try {
addressBook.prefetchEntries();
} catch (ReservatorException e) {
// TODO: DIE!
}
goToFavouriteRoomRunable = new GoToFavouriteRoom(this);
handler.postDelayed(goToFavouriteRoomRunable, 20000);
}
Ok ... I finally solved my problem, mainly thanks to #Drax
Apparently, you just can't start an activity from an application ... you need an instance of an activity. So :
public class ReservatorApplication extends Application {
#Override
public void onCreate(){
Intent i = new Intent(this, RoomActivity.class);
this.startActivity(i);
}
}
Is just not valid, and causes a RunTimeException ...
As far as crashing is concern when you start activity in handler with "this". it will take handler's context. and when you do getContext() it will take activity context.
Intent i = new Intent(YourActivityName.this, RoomActivity.class);
or
Intent i = new Intent(getBaseContext(), RoomActivity.class);
It`s hard to answer without seeing the stack trace from logcat, but I found that sometimes you need to pass the application context to the a new Intent before starting an Activity.
Try this line:
Intent i = new Intent(getApplicationContext(), RoomActivity.class);

Categories

Resources