Intent extras null on configuration change - android

I created a layout that displays on a SurfaceView and I can get the setDataSource by using Bundle extras = getIntent().getExtras().
Everything works fine until I try to set the landscape layout from land\layout.xml.
My logcat is
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference
at asia.sumikawa.cybereyeview.liveActivity.onCreate(liveActivity.java:65)
at android.app.Activity.performCreate(Activity.java:6092)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2481)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2608) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4216) 
at android.app.ActivityThread.access$900(ActivityThread.java:178) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1476) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5637) 
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:959) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754) 
My java coding
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate");
setContentView(R.layout.activity_live_alternate);
//loadLibrary();
final String newString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
newString = null;
} else {
newString = extras.getString("urlAddress");
}
} else {
newString = (String) savedInstanceState.getSerializable("urlAddress");
}
urlLink = "rtsp://" + newString.trim().substring(2);
urlString = newString;
The null pointer exception is on line
urlLink = "rtsp://" + newString.trim().substring(2);
which gets the value from
Bundle extras = getIntent().getExtras();
PS I would prefer not using android:configChanges="orientation" as I'm trying to make the layout have different height/width value
EDIT
After adding these code thanks to cricket_007
if (newString != null){
urlLink = "rtsp://" + newString.trim().substring(2);
}else{
Log.i(LOG,"Error");
}
I got this error instead
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'char java.lang.String.charAt(int)' on a null object reference
at asia.sumikawa.cybereyeview.liveActivity.playAll(liveActivity.java:307)
at asia.sumikawa.cybereyeview.liveActivity.onCreate(liveActivity.java:77)
which point to these lines of codes
void playAll(){
if(urlString.charAt(0) == '1'){
videoPlay();
}else if(urlString.charAt(0) == '2'){
videoPlay();videoPlay2();
}else if(urlString.charAt(0) == '3'){
videoPlay();videoPlay2();
videoPlay3();
}else if(urlString.charAt(0) == '4'){
videoPlay();videoPlay2();
videoPlay3();videoPlay4();
}}
Just in case this is needed,these are the codes I use to pass the String from the previous class
Intent i = new Intent(addressActivity.this, liveActivity.class);
String strName = content.toString();
i.putExtra("urlAddress", strName);
startActivity(i);

which gets the value from
Bundle extras = getIntent().getExtras();
Not always - if savedInstanceState is not null, then newString is the value of savedInstanceState.getSerializable("urlAddress");, which could possibly return null.
Alternatively, getIntent().getExtras() is null, therefore you hit
if (extras == null) {
newString = null;
}
Which will definitely cause an error.
In either case, you can catch the error by using this
if (newString != null) {
urlString = "rtsp://" + newString.trim().substring(2);
// Code that requires urlString
playAll();
} else {
// Show an error
}
And, then to address the problem, you might have to implement onSaveInstanceState to put the url string into that savedInstanceState Bundle. But, you should be using putString and getString, probably, instead of put / get - Serializable. That way you avoid the cast.
In order to find where the variable is getting null, it's just a matter of logging and debugging appropriately.
Approaches to saving your data between orientation changes can be found at Handling Runtime Changes

So I decided to make it manually
I use
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
setContentView(R.layout.activity_live_alternate_land);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
setContentView(R.layout.activity_live_alternate);
}
with this setting on AndroidManifest.xml
android:configChanges="orientation"
This will make the height/width value different without destroying the activity

Related

Is it possible to exclude SIM contacts when using Intent.ACTION_PICK?

I need to pick contacts in my app and would like to exclude those which are stored in my SIM card. Is it possible with ACTION_PICK?
No, it's not possible
Unfortunately, it's not possible for now.
To proof it, let's dive into source code of ContanctsListActivity.
Here's an onCreate() method of the Activity. In it, ContactApp reads Intent(ACTION_PICK) we passing to it and handles it respectively:
#Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mIconSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
mContactsPrefs = new ContactsPreferences(this);
mPhotoLoader = new ContactPhotoLoader(this, R.drawable.ic_contact_list_picture);
// Resolve the intent
final Intent intent = getIntent();
// Allow the title to be set to a custom String using an extra on the intent
String title = intent.getStringExtra(UI.TITLE_EXTRA_KEY);
if (title != null) {
setTitle(title);
}
String action = intent.getAction();
String component = intent.getComponent().getClassName();
// When we get a FILTER_CONTACTS_ACTION, it represents search in the context
// of some other action. Let's retrieve the original action to provide proper
// context for the search queries.
if (UI.FILTER_CONTACTS_ACTION.equals(action)) {
mSearchMode = true;
mShowSearchSnippets = true;
Bundle extras = intent.getExtras();
if (extras != null) {
mInitialFilter = extras.getString(UI.FILTER_TEXT_EXTRA_KEY);
String originalAction =
extras.getString(ContactsSearchManager.ORIGINAL_ACTION_EXTRA_KEY);
if (originalAction != null) {
action = originalAction;
}
String originalComponent =
extras.getString(ContactsSearchManager.ORIGINAL_COMPONENT_EXTRA_KEY);
if (originalComponent != null) {
component = originalComponent;
}
} else {
mInitialFilter = null;
}
}
Log.i(TAG, "Called with action: " + action);
mMode = MODE_UNKNOWN;
if (UI.LIST_DEFAULT.equals(action) || UI.FILTER_CONTACTS_ACTION.equals(action)) {
.....
else if (Intent.ACTION_PICK.equals(action)) {
// XXX These should be showing the data from the URI given in
// the Intent.
final String type = intent.resolveType(this);
if (Contacts.CONTENT_TYPE.equals(type)) {
mMode = MODE_PICK_CONTACT;
} else if (People.CONTENT_TYPE.equals(type)) {
mMode = MODE_LEGACY_PICK_PERSON;
} else if (Phone.CONTENT_TYPE.equals(type)) {
mMode = MODE_PICK_PHONE;
} else if (Phones.CONTENT_TYPE.equals(type)) {
mMode = MODE_LEGACY_PICK_PHONE;
} else if (StructuredPostal.CONTENT_TYPE.equals(type)) {
mMode = MODE_PICK_POSTAL;
} else if (ContactMethods.CONTENT_POSTAL_TYPE.equals(type)) {
mMode = MODE_LEGACY_PICK_POSTAL;
}
....
// VERY LONG IF WITH DIFFERENT MODE-SELECTION
....
}
.....
if (mMode == MODE_JOIN_CONTACT) {
setContentView(R.layout.contacts_list_content_join);
} else if (mSearchMode) {
setContentView(R.layout.contacts_search_content);
} else if (mSearchResultsMode) {
setContentView(R.layout.contacts_list_search_results);
} else {
setContentView(R.layout.contacts_list_content);
}
setupListView();
...
}
It's very long method (and I also suggest to check setupListView() method), but pretty straightforward. And, as you can see, there's no parameter you can pass to specify source of contacts you want to pick from. Only thing you can configure here is the particular mMode ContactsApp to use (MODE_PICK_CONTACT, MODE_PICK_PHONE, etc.) - but unfortunately number of possible modes is very limited by 6 and non of them suits you.
(If anyone needs to pass mMode to ContanctsListActivity - use intent's setType() method, for example: intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);)
Workaround
As a workaround - as tiny sunlight's suggested in comments - render non-SIM contacts within the app and pick the one you needed from there.
How to get all android contacts but without those which are on SIM - this link looks like most promising one explaining how to query cursor with all contacts, apart from SIM ones.
I hope, it helps

Android SMS Broadcast Receiver checking message format

Iam building Android application that checks the format of the received message
if it starts with $A its starts Activity A and send the content of the message to Activity A
if it starts with $B it starts Activity B and send the content of the message to Activity B
Please Any help
You can do it like this
if(messages.getMessageBody().contains("$A")) {
//Write your code here
}
else if(messages.getMessageBody().contains("$B")) {
//Write your code here
}
And to pass data to the next activity,do it like this,,
Intent i = new Intent(FirstScreen.this, SecondScreen.class);
i.putExtra("STRING_I_NEED", strName);
Then, to retrieve the value try something like:
String newString;
if (savedInstanceState == null) {
extras = getIntent().getExtras();
if(extras == null) {
newString= null;
} else {
newString= extras.getString("STRING_I_NEED");
}
} else {
newString= (String) savedInstanceState.getSerializable("STRING_I_NEED");
}

why do i get an error on doInBackground

This is my code:
protected S3TaskResult doInBackground(Uri... uris) {
if (uris == null || uris.length != 1) {
return null;
}
// The file location of the image selected.
Uri selectedImage = uris[0];
ContentResolver resolver = activity.getContentResolver();
String fileSizeColumn[] = {OpenableColumns.SIZE};
Cursor cursor = resolver.query(selectedImage,
fileSizeColumn, null, null, null);
cursor.moveToFirst();
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
// If the size is unknown, the value stored is null. But since an int can't be
// null in java, the behavior is implementation-specific, which is just a fancy
// term for "unpredictable". So as a rule, check if it's null before assigning
// to an int. This will happen often: The storage API allows for remote
// files, whose size might not be locally known.
String size = null;
if (!cursor.isNull(sizeIndex)) {
// Technically the column stores an int, but cursor.getString will do the
// conversion automatically.
size = cursor.getString(sizeIndex);
}
cursor.close();
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(resolver.getType(selectedImage));
if(size != null){
metadata.setContentLength(Long.parseLong(size));
}
S3TaskResult result = new S3TaskResult();
// Put the image data into S3.
try {
s3ClientPasado.createBucket(Constants.getPictureBucket());
PutObjectRequest por = new PutObjectRequest(
Constants.getPictureBucket(), Constants.PICTURE_NAME,
resolver.openInputStream(selectedImage),metadata);
s3ClientPasado.putObject(por);
} catch (Exception exception) {
result.setErrorMessage(exception.getMessage());
}
return result;
}
It says that an error occurred while executing doInBackground()
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
Any help would be appreciated.
I had a similar problem when the Uri I passed turned to be of null value.
The problem occurred in the resolver.query method.
You should post the rest of your code so we could understand it better.
For example - if you are using this code after getting an image from the camera please post how you invoke the camera intent and how you get the Uri.
Good luck.

Why NullPointerException in Service after Application exit?

I am creating a webview based Android Application using Phonegap. To help the application, I have created a service that basically gets user's location from time to time and processes it and saves it.
This is what happens:
I run the application - I have startService() call in onCreate() of the MainActivity. There is no other activity in the application (until now).
The service runs, application runs. I can see all this in LogCat.
Now, when I press back key on application's first screen, application exits and as a result after few seconds I see stack trace in LogCat and message that application has stopped. The error is NullPointerException
I get the exception in method below at indicated line:
public void GetAvailableLocation(){
vstore = new VariableStorage(); //Even when I assigned new object to vstore
if(vstore.load("mobileNumber").equals("0")) // Exception occures here
return;
// Get all available providers
List<String> providers = locationManager.getAllProviders();
for(String provider: providers) {
Location newLocation = locationManager.getLastKnownLocation(provider);
if(isBetter(newLocation, locationListener.location)
&& newLocation != null) {
locationListener.location = newLocation;
}
}
}
The above method is first method called in onCreate() of service.
Please help me out on this.
Edit: here is the load method in vstore-
public String load(String key){
Log.d(TAG, "Load key: "+key);
try{
if(!loaded){
this.loadFromFile();
}
String result = null;
if(key.equals("loggedIn"))
result = Boolean.toString(loggedIn);
else if(key.equals("mobileNumber"))
result = Long.toString(mobileNumber);
else if(key.equals("password"))
result = password;
else if(key.equals("gettingService"))
result = Boolean.toString(gettingService);
else if(key.equals("providingService"))
result = Boolean.toString(providingService);
else if(key.equals("gettingServiceID"))
result = Integer.toString(gettingServiceID);
else if(key.equals("providingServiceTo"))
result = Long.toString(providingServiceTo);
else if(key.equals("usersName"))
result = usersName;
else if(key.equals("currLatitude"))
result = Double.toString(currLatitude);
else if(key.equals("currLongitude"))
result = Double.toString(currLongitude);
else if(key.equals("prevLatitude"))
result = Double.toString(prevLatitude);
else if(key.equals("prevLongitude"))
result = Double.toString(prevLongitude);
else if(key.equals("lastLocationUpdateTime"))
result = Integer.toString(lastLocationUpdateTime);
else if(key.equals("publicKey"))
result = publicKey;
else if(key.equals("notification"))
result = Integer.toString(notification);
else if(key.equals("verifyMobileNumber"))
result = Long.toString(verifyMobileNumber);
return result;
}
catch(Exception e){
Log.d(TAG, "VSLoad Error: " + e.getMessage());
return null;
}
}
that is a better way to write that condition:
if("0".equals(vstore.load("mobileNumber")))
"0" is always given. so if load returns null you will call return;
That is called null saved :)
Be sure that vstore.load("mobileNumber") returns something
or write something like:
if(vstore.load("mobileNumber") == null || vstore.load("mobileNumber").equals("0"))
return;

Android Intent getExtras

I am passing values between two activities and fetching the values like this:
Bundle extras = getIntent().getExtras();
if (extras != null)
{
initialUrl = extras.getString("initialUrl");
isFollow = extras.getString("isFollow");
}
if (isFollow == "true") {
editUrl.setText(initialUrl);
setUpWebView(initialUrl);
} else if (isFollow == "false") {
editUrl.setText("http://www.google.com");
setUpWebView("http://www.google.com");
}
the problem is I can see the values being retrieved in the debug window by adding watch to the variables but when the compiler enters the statement if(isFollow=="true"), the condition fails. The else case is also not dealt with. What else do i need to do to ensure that my if condition is satisfied properly?
You should use
isFollow.equals("true")
in your statements.
If String type of data is put in bundle then Try with the following code
String isFollow = null;
Bundle extras = getIntent().getExtras();
if (extras != null)
{
initialUrl = extras.getString("initialUrl");
isFollow = extras.getString("isFollow");
}
if (isFollow.equals("true")) {
editUrl.setText(initialUrl);
setUpWebView(initialUrl);
} else if (isFollow.equals("false")) {
editUrl.setText("http://www.google.com");
setUpWebView("http://www.google.com");
}
If Boolean type of data is put in bundle then Try with the following code
boolean isFollow = null;
Bundle extras = getIntent().getExtras();
if (extras != null)
{
initialUrl = extras.getString("initialUrl");
isFollow = extras.getBoolean("isFollow");
}
if (isFollow) {
editUrl.setText(initialUrl);
setUpWebView(initialUrl);
} else {
editUrl.setText("http://www.google.com");
setUpWebView("http://www.google.com");
}
You need to test either
isFollow.equals("true") or if it is a boolean and not a string, either
isFollow == true or just plain isFollow
(note the no quotes on the second one)
I know this is a really late answer but it would be better to do this if you are passing a Boolean into the intent from the sender:
Boolean isFollow = extras.getBoolean("isFollow");
if(isFollow) {
//Do stuff
}

Categories

Resources