Intent from MainActivity options menu to second Activity Error/Android Manifest - android

I am having a difficult time understanding this error. I have an inent that starts in the Main_Activitie option menu.
I am getting this error in my LogCat:
07-07 20:09:40.317: E/AndroidRuntime(2803): FATAL EXCEPTION: main
07-07 20:09:40.317: E/AndroidRuntime(2803): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.TS.3000/com.TS.3000.AddRestaurantActivity}:java.lang.NullPointerException
When I debug there says there is NPE and No Source Found Window comes up. I've tried add new source folders but not change in error. Here is the section in my main activity that is calling the intent:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.add, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// this handles when user selects add button
Intent addRestaurant = new Intent(MainActivity.this,
AddRestaurantActivity.class);
Log.i("First", "Log.v");
startActivity(addRestaurant);
Log.i("Second", "Log.v");
return super.onOptionsItemSelected(item);
}
*****AddRestaurantActivity****** second activity being called
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_restaurant);
Log.i("fourth", "Log.v");
restName = (EditText) findViewById(R.id.edtT_rest_name);
restStreet = (EditText) findViewById(R.id.edtT_restaurant_street_address);
restCity = (EditText) findViewById(R.id.edtT_restaurant_city_address);
phoneNumber = (EditText) findViewById(R.id.edtT_restaurant_phone);
Button saveRestaurant = (Button) findViewById(R.id.btn_saveRestaurant);
saveRestaurant.setOnClickListener(saveRestaurantButtonClicked);
}
OnClickListener saveRestaurantButtonClicked = new OnClickListener() {
String restaurantName = restName.getText().toString();
#Override
public void onClick(View v) {
if (restName.getText().length() != 0) {
Intent intent = new Intent(AddRestaurantActivity.this,
MainActivity.class);
intent.putExtra("restName", restaurantName);
startActivity(intent);
Log.i("fifth", "Log.v");
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(
AddRestaurantActivity.this);
builder.setTitle(R.string.errorTitle);
builder.setMessage(R.string.errorMessage);
builder.setPositiveButton(R.string.errorButton, null);
builder.show();
}
}
};
Here is the XML where I added the intent:
<activity
android:name=".AddRestaurantActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DEFAULT" />
</intent-filter>
</activity>
When I comment out my OnClickListner the intent from the MainActivity to the AddRestaurantActivity operates fine.
I'm not sure if the problem is in declaring my intent in the manifest for the AddRestaurantActivity, or needing to add a source to android.jar. I'm new to android and debugging this problem is difficult. Thanks

Are Main Activity and AddRestaurantActivity in the same package? You could try to change android:name=".AddRestaurantActivity" to full package name, like android:name="com.myapplication.activity.AddRestaurantActivity".

Related

Activity not closing on Back press when theme is Theme.NoDisplay

I am setting Activity Theme to Theme.NoDisplay but When it open but on press back button Activity not closing/destroying. It should close/destroy on back press.
Guys help me why this is so and any solution to resolve this.
public class MainActivity extends Activity {
// Tag of the Activity
private static String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseManager.init(this);
NFCIItem mNFCItem = new NFCIItem();
mNFCItem.setSerialNumber(1);
DatabaseManager.getInstance().addWishList(mNFCItem);
final List<NFCIItem> wishLists = DatabaseManager.getInstance().getAllNFCSerialNumber();
Log.v(TAG, wishLists.toString());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
AndroidManifest.xml
<activity
android:name="com.example.appdemo.MainActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoDisplay" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I imagine it is closing but you see no evidence of this because it is 'NoDisplay'. An Activity using this theme has no visible UI (hence it is not logical for such an Activity to process UI events) and should not be kept alive. See this question for example:
how to completely get rid of an activity's GUI (avoid a black screen)
If you do want this Activity's layout to be visible and to handle events, you should use a different theme. If on the otherhand this is an invisible Activity that just does some background processing, call finish() in onCreate to close it when that processing is done.
You can override the back button event to manually close the activity
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
YourActivity.this.finish();
return true;
}
}
You can override the back button to launch the main activity and instantly close it without animation. This will appear as a single action to the user.
#Override
public void onBackPressed() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
overridePendingTransition(R.anim.slide_in_right,
R.anim.slide_out_right);
}

Android: Title of the action bar disappears

so, in my main activity, on the onCreate() method, I check if it is the app first run with shared preferences... If it is the first run of the app, the user is redirected to a welcome activity, and then, when I press the back button and return to the main activity, the title in the action doesn't show up.. I have tested with api 9 and 17, and this only happens with api 9, so I'm guessing the error must be something about using the support library for the action bar .. Can someone help me ?
Main:
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
public class MainActivity extends ActionBarActivity {
SessionManager session;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// session
session = new SessionManager(getApplicationContext());
// check first time app run
session.checkFirstRun();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
SessionManager First Run check method
// check first run
public void checkFirstRun() {
if(getFirstRunStatus() == true) {
// set first run key as false
editor.putBoolean("FIRST_RUN", false);
editor.commit();
// first time running the app, redirect user to welcome activity
Intent i = new Intent(_context, WelcomeActivity.class);
// Closing all the Activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Add new Flag to start new Activity
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
_context.startActivity(i);
}
}
public boolean getFirstRunStatus() {
return pref.getBoolean(FIRST_RUN, true);
}
Add the title in a couple ways:
XML:
<activity
android:name=".....WelcomeActivity"
android:icon="#drawable/logo"
android:label="#string/app_name"
</activity>
On the Fly:
.setTitle("TITLE");
.setIcon(R.drawable.logo);
You can pass the title in an intent to if you want it to be dynamic... not sure if that is what you want:
.setTitle(extras.getString("title"));
Hope that helps.
try this in your onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.action_menu_actions, menu);
ActionBar actionBar = getSupportActionBar();
actionBar.setTitle("title");
actionBar .setDisplayShowTitleEnabled(true);
// OR:
// getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME);
return true;
}

searchView setQuery does not work

I am using the Search interface in andriod, and folowing the android guide I have set up the the interface.
I create a SearchableActivity which will handle both the user input the search result.
Now I meet a problem in that when user input something in the SearchView and hit the search key, the Search requset will be submited, then I will receive the query string and do the search, but at this moment, the text in the SearchView was changed to the default SearchHit value while I want it to be the query string.
So I tried to use the searchView.setQuery(query, false);, but it does not work, what's the problem?
The core Activity codes:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_activity_layout);
Log.d("map", "create");
handleIntent(getIntent());
}
public void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
Log.d("map", "handleIntent");
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
//try search
Log.d("map", "search and set query:" + query);
searchView.setQuery(query, false); // reset the value in of the SearchView
}
}
The AndroidManifest.xml:
<activity
android:name=".ui.MapActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
I suggest you to delay the setting until the next event loop (add it to the message queue), so the code may looks like this:
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
final String query = intent.getStringExtra(SearchManager.QUERY);
searchView.post(new Runnable() {
#Override
public void run() {
// Important! Make sure searchView has been initialized
// and referenced to the correct (current) SearchView.
// Config changes (e.g. screen rotation) may make the
// variable value null.
searchView.setQuery(query, false);
}
};
}
}
This doesn't work
mSearchView.setQuery(mKeyword, true);
MenuItemCompat.expandActionView(mMenuSearch);
This does
MenuItemCompat.expandActionView(mMenuSearch);
mSearchView.setQuery(mKeyword, true);
It seems it only remembers it after you expanded the action view.
I'm using MenuItemCompat just for backwards compatibility
need to put code in post handler with MenuItemCompat
inflater.inflate(R.menu.menu_my_team, menu);
// search manager integration for search widget
SearchManager searchManager = (SearchManager) getActivity()
.getSystemService(Context.SEARCH_SERVICE);
final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
// MenuItem helpTutorialMenuItem = menu.findItem(R.id.action_help);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
mSearchView.setSearchableInfo(searchManager
.getSearchableInfo(getActivity().getComponentName()));
mSearchView.setQueryHint("Search by");
if (!TextUtils.isEmpty(queryText)) {
mSearchView.post(new Runnable() {
#Override
public void run() {
MenuItemCompat.expandActionView(searchMenuItem);
mSearchView.setQuery(queryText, false);
}
});
}
mSearchView.clearFocus();
It seems that when the intent with Action Intent.ACTION_SEARCH is received, the following method will be called:
handleIntent();
onCreateOptionsMenu();
And the handleIntent will run before the onCreateOptionsMenu.
At the same time, people used to setup the searchView at the onCreateOptionsMenu.
Which means that the option menu will be re-inflated, and the searchView will be re-build, then all the settings in the handleIntent will not work.
I think this is the reason.
Please feel free to fix me if I am wrong.
In my case, it wasn't working because the fragment I was in was no longer attached to the window. Moving it to above where I swapped in the new search results fragment fixed it.

Android: Return search query to current activity

I followed the steps described on http://developer.android.com/guide/topics/search/search-dialog.html to implement a search feature in my notepad application.
My problem is, that when I finish the search a new activity opens capturing my search query. But what I really want, is the query returned to the current activity instead of starting a new one.
Is this possible?
UPDATE:
AndroidManifest.xml
<activity android:name="MyNotepad"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.SEARCH"></action>
</intent-filter>
<meta-data android:resource="#xml/searchable" android:name="android.app.searchable"></meta-data>
</activity><activity android:name="Preferences" android:label="Preferences" >
</activity>
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint">
</searchable>
JAVA-code
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_pad);
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
Toast.makeText(getApplicationContext(), query, Toast.LENGTH_LONG).show();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case R.id.menuItemSearch:
startSearch("", false, null, false);
break;
}
return true;
}
Even if I use the search-button on the phone it doesn't work. I therefor believe that the problem is in the AndroidManifest.xml
In your Application Manifest you need to define the current activity as a searchable activity.
<activity android:name="BrowseItems" android:label="#string/browseitems"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/itemsearchable" />
</activity>
You then use the following code, which is from http://developer.android.com/guide/topics/search/search-dialog.html#LifeCycle
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
// Do work using string
}
}
You can then use the string to reload your activity, if its a list activity you can call your code that you use to load data and use the string in that.
Add to AndroidManifest.xml in your Searchable Activity:
android:launchMode="singleTop"
so, your AndroidManifest.xml looks like:
<activity android:name="MyNotepad"
android:label="#string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.SEARCH"></action>
</intent-filter>
<meta-data android:resource="#xml/searchable" android:name="android.app.searchable"></meta-data>
</activity><activity android:name="Preferences" android:label="Preferences" >
The reason:
From this post:
The activity launch mode has four valid values:
"standard"
"singleTop"
"singleTask"
"singleInstance"
The 'standard' is the default value. The four values fall into two groups:
'standard' and 'singleTop' can instantiate multiple activity instances and the instance will stay in the same task.
For 'singleTask' or 'singleInstance', the activity class uses the singleton pattern, and that instance will be the root activity of a new task. Let's examine each value:
"standard":
Multiple instances of the activity class can be instantiated and multiple instances can be added to the same task or different tasks. This is the common mode for most of the activities.
"singleTop":
The difference from 'standard' is, if an instance of activity already exists at the top of the current task and system routes intent to this activity, no new instance will be created because it will fire off an onNewIntent() method instead of creating a new object.
I simply use this:-
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
//on submit
return false;
}
#Override
public boolean onQueryTextChange(String s) {
//get all text changes
return false;
}
});
This is best used when you have to search across a listview and have to filter out items. I never go by implementing the search function using the manifest file. The 2 methods do all the job.
I was also facing the same problem, then I wrote this code and it solved my problem.
Implement this in your Activity
**implements SearchView.OnQueryTextListener, SearchView.OnCloseListener**
Add this function in the class:
private void setupSearchView()
{
searchView.setIconifiedByDefault(true);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
if (searchManager != null)
{
List<SearchableInfo> searchables = searchManager.getSearchablesInGlobalSearch();
// Try to use the "applications" global search provider
SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
for (SearchableInfo inf : searchables)
{
if (inf.getSuggestAuthority() != null && inf.getSuggestAuthority().startsWith("applications"))
{
info = inf;
}
}
searchView.setSearchableInfo(info);
}
searchView.setOnQueryTextListener(this);
searchView.setOnCloseListener(this);
}
Call the function in the onCreateOptionsMenu(Menu menu)
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
//restoreActionBar();
// Associate searchable configuration with the SearchView
//SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
//searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
setupSearchView();
return super.onCreateOptionsMenu(menu);
}
This will totally solve your problem..
Happy Coding!!
Briefly:
Add android:launchMode="singleTop" to the searchable activity definition in the AndroidManifest.xml
Implement onNewIntent in the searchable activity and handle the search there.
I followed Lachlan's clue of "You can then use the string to reload your activity", and finally worked this out. So please read Lachlan's post first, and then take the following 3 steps "to reload your activity":
Save query string in ApplicationContext.
Finish the new opened search Activity.
Override OnResume, get query string you just saved, and then refresh the list.
Codes in List Activity:
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String searchText = intent.getStringExtra(SearchManager.QUERY);
((MyApp)this.getApplicationContext()).setSearchText(searchText);
this.finish();
}
}
protected void onResume() {
super.onResume();
String searchText = ((MyApp)this.getApplicationContext()).getSearchText();
//refresh your list here...
}
MyApp class: (This original idea is from here: Android: How to declare global variables?)
public class MyApp extends Application {
private String mSearchText;
public String getSearchText() {
return mSearchText;
}
public void setSearchText(String searchText) {
this.mSearchText = searchText;
}
}
Don't forget to add property android:name=".MyApp" to your application in the Manifest file. Good luck!
in the manifest file, add:
android:launchMode="singleTop"
To your search activity. Then, let your search activity implement SearchView.OnSuggestionListener
finally:
mSearchView.setOnSuggestListener(this)
this way you can handle the suggestion click event with out creating a new instance of your search activity.
It doesn't bring up a new activity if the SearchView.OnSuggestionListener on the searchView is set, and the overridden methods return true (overriding the default behavior). You can do that in the onCreateOptionsMenu() implementation, like this:
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
#Override
public boolean onSuggestionSelect(int position) {
return true;
}
#Override
public boolean onSuggestionClick(int position) {
CursorAdapter selectedView = searchView.getSuggestionsAdapter();
Cursor cursor = (Cursor) selectedView.getItem(position);
int index = cursor.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_TEXT_1);
searchView.setQuery(cursor.getString(index), true);
return true;
}
});
No need to force the activity to singleTop or other hacks.
Just add
<application>
<meta-data
android:name="android.app.default_searchable"
android:value="#Activity_Name" />
<!-- All your activities, service, etc. -->
</application>
in your android_manifest.xml file where #Activity_Name is the name of the activity that handles the search.

Android: Launching new activity from dialog

I'm trying to use a custom dialog to get user input for a title String, and then if the user clicks OK, it will fire up a new Activity (basically a notepad) with that title String as the title. However, when I try to call the method that fires the new activity inside onClick(), it gives me an error.
Here's the code
class NewListDialog extends Dialog implements OnClickListener {
Button search;
EditText text;
public NewListDialog(Context context) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.newlist_dialog);
search = (Button) findViewById(R.id.dialog_confirm);
text = (EditText) findViewById(R.id.dialog_editable);
search.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == search) {
String title_name = text.getText().toString();
// method for launching new activity
fireListEdit(title_name);
}
}
}
void fireListEdit(String title_name) {
Intent i = new Intent(this, ListEdit.class);
i.putExtra(InvenDB.KEY_TITLE, title_name);
startActivityForResult(i, ACTIVITY_CREATE);
}
And I call this dialog with
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case INSERT_ID:
NewListDialog dialog = new NewListDialog(this);
dialog.show();
return true;
case QUIT_ID:
finish();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
Edit: when I run it on emulator, when I click OK on the custom dialog it just gives me "the application stopped unexpectly" error
EDIT:
This is the logcat, I'm not really sure what they mean :\
01-12 17:39:27.668: ERROR/AndroidRuntime(426): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jin.inventoryapp/com.jin.inventoryapp.ListEdit}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
From what I can tell there is a problem with the Adapter (data) part of your application. Whatever Adapter class you used to back your com.jin.inventoryapp.ListEdit, it has a problem accessing the data. i.e. if you are using an array or database to populate your ListView, check there first.
This is useful to figure out who is throwing an exception.

Categories

Resources