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.
Related
I am trying to create maximum 6 line array of place names and LatLngs and then use an intent to send it to a map class where the user can select name. The name needs to still be tied to the LatLng so the map can centre and zoom to it.
I have added edited code below. I have a mix of putExtra and putParcelable as I'm trying anything to get a working prototype. Hopefully it makes some sense.
The Sending Class Geocode is this:
private void geocodeLocation(String gPlace) {
Geocoder gGeocoder = new Geocoder(this, Locale.getDefault());
try{
List<Address> results = null;
if(Geocoder.isPresent()){
results = gGeocoder.getFromLocationName(gPlace, numberOptions);
} else {
return;
}
Iterator<Address> locations = results.iterator();
String country;
int opCount = 0;
while(locations.hasNext()){
Address location = locations.next();
raw += location+"\n";
strAddressOutput[opCount] = location.getAddressLine(0) + ", " + location.getAddressLine(1) + country + "\n";
strLatOutput[opCount] = location.getLatitude();
strLongOutput[opCount] = location.getLongitude();
gLatLng = new LatLng(location.getLatitude(),location.getLongitude());
strLatLng[opCount] = gLatLng;
opCount ++;
}
for(int i = 0; i<opCount; i++){
}
} catch (IOException e){
}
The Sending Class Intent is this:
public void onConnected(Bundle bundle) {
if (!android.location.Geocoder.isPresent()) {
return;
}
if (gAddressRequested) {
geocodeLocation(gPlace);
Intent tdMap = new Intent(this, com.dm4_map_test.todos3maps.MainMap.class);
tdMap.putExtra(Constants.RETURNEDADDRESS, strAddressOutput);
Bundle args = new Bundle();
args.putString(Constants.PLACE, gPlace);
args.putParcelable(Constants.MAPCENTRE, gMapCentre);
args.putParcelableArray(Constants.LATLNGS, strLatLng);
tdMap.putExtra("bundle", args);
startActivity(tdMap);
}
}
The Receiving Class is this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_map);
MapFragment mapFrag = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
if (savedInstanceState == null) {
needsInit = true;
}
mapFrag.getMapAsync(this);
mPlace = (EditText) findViewById(R.id.txAddress);
mAddressList = (Spinner) findViewById(R.id.spinAddressList);
mPlace.setText(getIntent().getStringExtra(Constants.PLACE));
String[] recAddressAA = getIntent().getStringArrayExtra(Constants.RETURNEDADDRESS); // NULLS from Geocoder?
recAddressOutput = recAddressAA;
String testAddressOutput = Arrays.toString(recAddressAA);
Bundle bundleMapCentre = getIntent().getParcelableExtra("bundle");
mMapCentre = bundleMapCentre.getParcelable (Constants.MAPCENTRE);
Bundle bundleLatLng = getIntent().getParcelableExtra("bundle");
LatLng[] mLatLng = bundleLatLng.getParcelableArrayList(Constants.LATLNGS);
mAdapter = new ArrayAdapter<String>(MainMap.this, android.R.layout.simple_spinner_item, recAddressOutput);
mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mAddressList.setAdapter(mAdapter);
});
}
The line 'LatLng[] mLatLng = bundleLatLng.getParcelableArrayList(Constants.LATLNGS);' errors but I have stepped back to see if this a workable approach
Intent lets you pass through ints, doubles, strings, etc. but if you want to pass a custom object you will have to create the custom object implementing Parceable. You can see a little bit about how to do that here
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.
I'm trying to send data on SharedPreferenceson from MainActivity to a BroadcastReceiver.
but that always return null .
I tried very code but all of them returned null.
this is my code on MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences shpMobile = getSharedPreferences("text", MODE_PRIVATE);
final String MobileNumber = (shpMobile.getString("MobileDevice", "0"));
Intent inte = new Intent();
inte.setAction("MyBroadcast");
inte.putExtra("Phone", MobileNumber);
sendBroadcast(inte);
and this is my BroadcastReceiver class
String phoo1;
#Override
public void onReceive(Context context, Intent intent) {
//updateWidget();
Bundle extras = intent.getExtras();
if (extras != null) {
String phoo1 = (String) extras.get("Phone");//getting null value
Toast.makeText(context, phoo1 +"این شماره انتقال دهنده است", 5000).show();
}
But phoo is null.
Whats wrong?
Had a similar problem some time ago. Try it using getStringExtra() from the intent instead of extras.get() from bundle:
String phoo1 = intent.getStringExtra("Phone");
that solved my problem.
Try to replace this code:
Bundle extras = intent.getExtras();
if (extras != null) {
String phoo1 = (String) extras.get("Phone");//getting null value
Toast.makeText(context, phoo1 +"این شماره انتقال دهنده است", 5000).show();
}
With this:
String phoo1 = intent.getStringExtra("Phone") !=null? intent.getStringExtra("Phone"):"";
Toast.makeText(context, phoo1 +"این شماره انتقال دهنده است", 5000).show();
thanks all.
but i cant get value with this solution. and i was searched on net to find another way to get the values.
finally ,i find a new sulotion . code is in below: ( i used to Shareperferenced to get values in BroadcastReceiver)
SharedPreferences prefs = context.getSharedPreferences("text",
Context.MODE_PRIVATE);
final String MobileNumber = (prefs.getString("MobileDevice", null));
this code work for me and reply the our Qustion for #Opiatefuchs request
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{
}
for some specific requirement
I am required to change Android Default Home application
with my customized Home application ( a setting inside my app that will toggle default home = my application or previous home)
I don't want the user to travel android settings that are very complicated.
Can any one help me out like where it registers launcher.apk for default
home application or how to change that
The only thing I could find was that old question: How to change default Android's Desktop application?
but no answers at all.
I have seen HomeSwitcher in the Market that do the trick, but no answer for the developer that might certainly be busy.
EDIT
I found this on the web http://www.mail-archive.com/android-developers#googlegroups.com/msg74167.html
But I got the same issue:
this is my code:
private void makePreferred() {
PackageManager pm = getPackageManager();
IntentFilter f = new IntentFilter("android.intent.action.MAIN");
f.addCategory("android.intent.category.HOME");
f.addCategory("android.intent.category.DEFAULT");
ComponentName cn = new ComponentName("com.example.android.home", "com.example.android.home.Home");
pm.addPreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, null, cn);
I have the android.permission.SET_PREFERRED_APPLICATIONS set in the
manifest. After executing the code above, the logs claim things have
been added like expected (same logs as when I tick off "Make default"
from IntentResolver's list). However, when I proceed by clicking home,
the list still shows up and the logs say:
INFO/PackageManager(52): Result set changed, dropping preferred
activity for Intent { act=android.intent.action.MAIN cat=
[android.intent.category.HOME] flg=0x10200000 } type null
So it seems the resolver deletes the default entry. Am I doing
something wrong, or is this a security measure? What are the ideas
behind this?
I did an extensive research on that and starting from 2.2 there is no way to do that. The only way is using some hacking that toddler lock app does but this app put samsung phones recently in the infinite loop, so it is a risky approach.
if you look at the froyo source code here of packagemanager class, you will see this small condition in the addPreferredActivity method:
if (getUidTargetSdkVersionLockedLP(Binder.getCallingUid())
< Build.VERSION_CODES.FROYO) {
Slog.w(TAG, "Ignoring addPreferredActivity() from uid"
+ Binder.getCallingUid());
return;
}
HomeSwitcher does not work properly on 2.2 since it uses this very method and developer made a comment on app page "Froyo(2.2) is not supported
due to the API change"
"Result set changed" means that the set of packages matching that intent has changed from the set you specified when you created the default - - so the default is no longer valid. Your list of components (which you are currently setting to null) needs to contain all homescreen apps present on device, not just yours.
Here's example code that I have tested (using adb shell am start http://www.google.co.uk/ ) and used to set the default browser. XXX represents a customer name that I had to black out.
Note that in order to call addPreferredActivity you must have compiled against a minimum-sdk version of 8 (2.2) and you must have specified the SET_PREFERRED_APPLICATIONS permission. That permission is protection level 2, so you need to be signed with the same certificate as PackageManager.
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.VIEW");
filter.addCategory("android.intent.category.DEFAULT");
filter.addDataScheme("http");
Context context = getApplicationContext();
ComponentName component = new ComponentName("com.opera.mini.XXX", "com.opera.mini.XXX.CustomerBrowser");
ComponentName[] components = new ComponentName[] {new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"),
component};
pm.addPreferredActivity(filter, IntentFilter.MATCH_CATEGORY_SCHEME, components, component);
ETA - if you marked this response down, could you let me know why. The code I posted above is tested and working...
startActivity(new Intent(Settings.ACTION_HOME_SETTINGS));
This code works on my ICS device: I use a service that is sensible to some call, one of them is called SET_PREFERRED_LAUNCHER, the put in a bundle your new default Launcher package (PREFERRED_PACKAGE_KEY) and it's activity (PREFERRED_ACTIVITY_KEY)
Method installPackageMethod = null;
Method deletePackageMethod = null;
Method setPreferredActivityMethod = null;
Method replacePreferredActivityMethod = null;
Object pm = null;
#Override
public void onCreate() {
super.onCreate();
if (pm == null)
pm = getPackageManager();
try {
if (setPreferredActivityMethod == null)
setPreferredActivityMethod = pm.getClass().getMethod(
"addPreferredActivity", IntentFilter.class, int.class,
ComponentName[].class, ComponentName.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
private final class ServiceHandler extends Handler {
private Context context;
public ServiceHandler(Looper looper, Context ctx) {
super(looper);
context = ctx;
}
#Override
public void handleMessage(Message msg) {
Intent intent = (Intent) msg.getData().getParcelable(
UPDATER_SERVICE_ACTION);
int request = intent.getIntExtra(
REQUEST_KEY,
REQUEST_UNKNOWN);
Bundle bundle = intent.getExtras();
switch (request) {
case INSTALL_APPLICATION: {
if (bundle != null) {
String appPath = bundle
.getString(APP_PATH_KEY);
if (appPath != null) {
LogUtil.e(TAG, "try to install " + appPath);
try {
am.installPackage(appPath);
} catch (Exception e) {
e.printStackTrace();
}
LogUtil.e(TAG, "install of " + appPath + " done");
}
}
break;
}
case UNISTALL_PACKAGE: {
if (bundle != null) {
String packagename = bundle
.getString(PACKAGE_NAME_KEY);
if (packagename != null) {
LogUtil.e(TAG, "unistall " + packagename);
try {
deletePackageMethod
.invoke(pm, packagename, null, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
break;
}
case SET_PREFERRED_LAUNCHER: {
if (bundle != null) {
String package_name = bundle
.getString(PREFERRED_PACKAGE_KEY);
if (package_name == null) {
LogUtil.e(TAG,
"WARNING: setDefaultActivity cannot continue, package is NULL");
return;
}
String activity_name = bundle
.getString(PREFERRED_ACTIVITY_KEY);
if (activity_name == null) {
LogUtil.e(TAG,
"WARNING: setDefaultActivity cannot continue, activity is NULL");
return;
}
LogUtil.e(TAG, "setDefaultActivity activity="
+ activity_name + " package=" + package_name);
IntentFilter filter = new IntentFilter(
"android.intent.action.MAIN");
filter.addCategory("android.intent.category.HOME");
filter.addCategory("android.intent.category.DEFAULT");
ComponentName[] components = new ComponentName[] {
new ComponentName("com.android.launcher",
"com.android.launcher2.Launcher"),
new ComponentName(package_name, activity_name) };
ComponentName activity = new ComponentName(package_name,
activity_name);
try {
setPreferredActivityMethod.invoke(pm, filter,
IntentFilter.MATCH_CATEGORY_EMPTY, components,
activity);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
Remember to add in your manifest file this permission:
<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"/>
Usage:
public void setPreferredLauncher(String activity_name,String package_name)
{
Intent intent = new Intent(UPDATER_SERVICE_ACTION);
intent.putExtra(REQUEST_KEY, SET_PREFERRED_LAUNCHER);
intent.putExtra(PREFERRED_ACTIVITY_KEY, activity_name);
intent.putExtra(PREFERRED_PACKAGE_KEY, package_name);
context.startService(intent);
}
where:
public static final String _UPDATER_SERVICE_ACTION = "com.android.updaterservice.ACTION";
public static final String REQUEST_KEY = "com.android.updaterservice.REQUEST_KEY";
public static final String PACKAGE_NAME_KEY = "com.android.updaterservice.PACKAGE_NAME_KEY";
public static final String APP_PATH_KEY = "com.android.updaterservice.APP_PATH_KEY";
public static final String PREFERRED_ACTIVITY_KEY = "com.android.updaterservice.PREFERRED_ACTIVITY_KEY";
public static final String PREFERRED_PACKAGE_KEY = "com.android.updaterservice.PREFERRED_PACKAGE_KEY";
public static final String INSTALL_PACKAGE_RESULT = "com.android.updaterservice.INSTALL_PACKAGE_RESULT";
public static final String PACKAGE_NAME = "PACKAGE_NAME";
public static final String INSTALL_SUCCEEDED = "INSTALL_SUCCEEDED";
public static final int REQUEST_UNKNOWN = -1;
public static final int INSTALL_APPLICATION = 1;
public static final int UNISTALL_PACKAGE = 2;
public static final int SET_PREFERRED_LAUNCHER = 3;