Android - Unable to create new Intent which triggered from OptionMenu - java

I am new to Android development and currently stuck when trying to develop a simple app based on This Tutorial
What i want is basically start a new intent when user click on a button via the setting menu (of the said app).
This are some segment of my code:
MainActivity.java
Here i am getting an error with SET_TIME_REQUEST_ID which is a constant that has not been declared anywhere in my code. Should i declare it, i am not sure what is the type of the constant and what value should i assign it with.
*** REST OF THE CODE ****
private void setTime() {
Intent i = new Intent(getBaseContext(), CountdownSetTime.class);
startActivityForResult(i, SET_TIME_REQUEST_ID);
}
*** REST OF THE CODE ***
CountdownSetTime.java
The error i am getting with this part are; context and secondsSet cannot be resolved to any variable. Again, i am not sure what to do with this. Should i declare a variable called secondsSet? If yes, what is the type?
*** REST OF THE CODE ***
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.set_time);
context = this.getApplicationContext(); // ERROR HERE.
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayList<Integer> spinnerList = new ArrayList<Integer>();
for (int i = MIN; i <= MAX; i++) {
spinnerList.add(i);
}
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(context,
android.R.layout.simple_spinner_item, spinnerList);
adapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
secondsSet = (Integer)parent.getItemAtPosition(pos); // ERROR HERE
}
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
});
}
*** REST OF THE CODE ***
manifest.xml
I am absolutely clueless with this. I am not sure how could i register my new intent.
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.gelliesmedia.countdown.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.gelliesmedia.countdown.CountdownSetTime"
android:label="#string/app_name"
android:parentActivityName="com.gelliesmedia.countdown.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.gelliesmedia.countdown.MainActivity" />
</activity>
</application>
Could anyone point me to the right direction?

I have read the tutorial you give as a link. That tutorial doesn't give the full code. According to what I see the variables you mention must be defined.
For SET_TIME_REQUEST_ID usually you add this at the beginning with something like that
private static final int SET_TIME_REQUEST_ID = 1;
because onActivityResult(int, int, Intent)
That ID is your internal identification. I put 1 but you can put any number. It is an ID for you so that when the activity closes you can fetch the result.
So yes you have to define it.
Same for secondsSet.
The type seems to be Integer because the parent.getItemAtPostion is cast to Integer. It is used but not defined. Seems to me to be a global variable. The ones you put at the top of your class.
So yes you have to define it also :-)
And finally it is the same for context. It is used but not declared. It seems the tutorial you use declares all these variable globally.
EDIT
The manifest file tells the system that an intent (activity) exist.
You should have some thing like that
<activity
android:name="com.gelliesmedia.countdown.CountdownSetTime">
</activity>

Related

Why previous Activity get destroyed pressing up button on Setting Activity Toolbar?

GOAL: when the user press back on SettingsActivity toolbar the previous Activity should be resumed from where the user left.
PROBLEM: From Activity lifecycle reported on android developer website I understand that the previous Activity should be resumed calling OnResume method, instead in my case the MainActivity start again calling OnCreate method.
In particular the flow is as follows:
1) User click on icon to start SettingsActivity
2)MapsActivity invokes onPause, then onSaveInstanceState, then onStop
3) User click back button on SettingsActivity
4)MapsActivity invokes onDestroy then onCreate (and everything I tried to save during point 2 with saveInstanceState is lost because Bundle is always null)
CODE
MapsActivity (main activity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// .... other initialization code ... //
// If location permission is granted initialize Map
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mapSync();
} else {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("prova", true);
}
// Where I start the second activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.connection_type:
// .... handle this case ... //
case R.id.settings:
Intent intent = new Intent(MapsActivity.this, SettingsActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
SettingsActivity (called activity)
public class SettingsActivity extends AppCompatActivity
{
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
// Set the toolbar
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
myToolbar.setTitle("Settings");
myToolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24px);
myToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
setSupportActionBar(myToolbar);
}
public static class MainSettingsFragment extends PreferenceFragmentCompat {
public final static String KEY_ENABLE_BACKGROUND_UPDATE = "enable_background_update";
public final static String KEY_ENABLE_LAST_KNOWN_LOCATION = "enable_last_known_location";
public final static String KEY_DELETE_DB_DATA = "delete_db_data";
public final static String KEY_CHANGE_MAP_COLOR ="change_map_color";
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener;
#Override
public void onCreatePreferences(Bundle bundle, String s) {
// Load the Preferences from the XML file
addPreferencesFromResource(R.xml.preferences);
preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals(KEY_DELETE_DB_DATA))
{
String connectivityType = sharedPreferences.getString(key, null);
new DeleteAreaAsync(SignalAreaDatabase.getDatabase(getContext()), connectivityType).execute();
} else if(key.equals(KEY_CHANGE_MAP_COLOR)){
String gradientColor = sharedPreferences.getString(key, null);
SignalAreaDrawer signalAreaDrawer = SignalAreaDrawer.getSignalAreaDrawer();
signalAreaDrawer.setGradientColor( gradientColor);
}
}
};
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(preferenceChangeListener);
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Less accurate location: telephony manager and location requests -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Access to wifi network information -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Change wifi connectivity state -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:parentActivityName=".MapsActivity"
android:theme="#style/PreferenceScreen" />
</application>
QUESTION: how can I restore the previous Activity state and show to the user exactly what he was visualizing when he opened the second Activity?
EDIT #1:
I tried to override oonDestroy() , onSaveInstance(), onRestoreInstance() and this is what happens:
when I start the setting activity, the main activity go onPause() as I would expect.
when I press the back button on the settings activity , the main activity go before onDestroy() and immediately after onCreate(), not calling onSaveInstance() or onRestoreInstance() at all.
EDIT #2: the app didn't go through onSaveInstanceState(Bundle outState) probably because I declared it public. Now the app calls it. So I tried to save some info like outState.putBoolean("prova", true); but when the mainActivity is destroyed , at new onCreate(Bundle savedInstanceState) invokation the Bundle savedInstanceState is always null.
EDIT #3: as #SherifelKhatib suggested I tried to delete all finish() statement from MapsActivity, and I tried to substitute MapsActivity with a minimal EmptyActivity to see if the problem was in MapsActivity. Unfortunately the app has the same behaviour.
When the user press the back button the previous app is always destroyed. No way to restore its state.
EDIT #4: what I tried and still doesn't work. Modifying SettingsActivity :
First approach
#Override
public void onBackPressed(){
moveTaskToBack(true);
}
Second approach
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
Third approach
#Override
public void onBackPressed() {
Intent backIntent = new Intent(this, MapsActivity.class);
backIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(backIntent);
}
And add this in MainActivity:
Intent intent = new Intent(MapsActivity.this, SettingsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
SOLUTION:
Add this attribute to MainActivity in the manifest .
android:launchMode="singleTop"
Explanation
The "standard" and "singleTop" modes differ from each other in just
one respect: Every time there's a new intent for a "standard"
activity, a new instance of the class is created to respond to that
intent. Each instance handles a single intent. Similarly, a new
instance of a "singleTop" activity may also be created to handle a new
intent. However, if the target task already has an existing instance
of the activity at the top of its stack, that instance will receive
the new intent (in an onNewIntent() call); a new instance is not
created.

Android Nougat, Oreo - How to add long press action to Quick toggles?

I need some help for my app that I'm developing. Current code that I'm using, on long press it launches app info. I want to change that to launch an activity of my app.
The Quick.java class.
#TargetApi(24)
public class Quick extends TileService {
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onTileAdded() {
super.onTileAdded();
}
#Override
public void onTileRemoved() {
super.onTileRemoved();
}
#Override
public void onStartListening() {
super.onStartListening();
}
#Override
public void onStopListening() {
super.onStopListening();
}
#Override
public void onClick() {
super.onClick();
startActivity(Main);
}
}
Just need a onLongClick() method on this code.
In my manifest under <application> tag.
<service
android:name=".Quick"
android:icon="#drawable/ic_quick"
android:label="#string/quick_title"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
Caution : It's 100% possible to do that in android N and O, for an example take look at this app
Ok I get yes you can implement the Long click listner but here is a issue
Long clicking on your quick settings tile will, by default, go to your app’s info screen. You can override that behavior by adding an intent-filter to one of your activities like so:
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES"/>
</intent-filter>
As you have done in your manifest file here a link that might be helpfull look very closely long press quick setting tile in android

requestFeature() before adding content error when trying to make AndEngine work with Google Play Game Service

I have a game I'm working on, that uses AndEngine.
AndEngine has a "BaseGameActivity" and so does Google Play Game Service. I had to rename BaseGameActivity from AndEngine to AEBaseGameActivity and have it as a parent class BaseGameActivity instead of Activity.
But it is giving me this error:
Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:226)
at org.andengine.util.ActivityUtils.requestFullscreen(ActivityUtils.java:56)
at org.andengine.ui.activity.AEBaseGameActivity.applyEngineOptions(AEBaseGameActivity.java:427)
at org.andengine.ui.activity.AEBaseGameActivity.onCreate(AEBaseGameActivity.java:83)
Now AndEngine has this piece of code:
public static void requestFullscreen(final Activity pActivity) {
final Window window = pActivity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
window.requestFeature(Window.FEATURE_NO_TITLE);
}
if I comment the requestFeature line, my projects runs! But it has an ugly title bar.
Does anyone please know a fix for this ?
EDIT, HERE IS SOME MORE CODE:
PS: AEBaseGameActivity.php extends BaseActivity which extends BaseGameActivity (previously just activity)
AEBaseGameActivity.php
public abstract class AEBaseGameActivity extends BaseActivity implements IGameInterface, IRendererListener {
#Override
protected void onCreate(final Bundle pSavedInstanceState) {
if(BuildConfig.DEBUG) {
Debug.d(this.getClass().getSimpleName() + ".onCreate" + " #(Thread: '" + Thread.currentThread().getName() + "')");
}
super.onCreate(pSavedInstanceState);
this.mGamePaused = true;
this.mEngine = this.onCreateEngine(this.onCreateEngineOptions());
this.mEngine.startUpdateThread();
this.applyEngineOptions(); //REQUEST FULLSCREEN
this.onSetContentView(); //SET CONTENT VIEW
}
...
private void applyEngineOptions() {
final EngineOptions engineOptions = this.mEngine.getEngineOptions();
if(engineOptions.isFullscreen()) {
ActivityUtils.requestFullscreen(this); //ACTIVITY UTIL SHOWN LATER
}
...
}
...
protected void onSetContentView() {
this.mRenderSurfaceView = new RenderSurfaceView(this);
this.mRenderSurfaceView.setRenderer(this.mEngine, this);
this.setContentView(this.mRenderSurfaceView, AEBaseGameActivity.createSurfaceViewLayoutParams());
}
}
ActivityUtils.java
public class ActivityUtils {
public static void requestFullscreen(final Activity pActivity) {
final Window window = pActivity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
window.requestFeature(Window.FEATURE_NO_TITLE); //IF COMMENTING THIS, THE GAME IS RUNNING
}
...
}
EDIT2:
The code is basically only AndEngine, here is the original code:
https://github.com/nicolasgramlich/AndEngine/tree/GLES2/src/org/andengine/ui/activity
My changes:
renamed BaseGameActivity to AEBaseGameActivity
BaseActivity extends BaseGameActivity (taken from Google Play Game Service) instead of Activity
BaseGameActivity and GameHelper.java taken from BaseGameUtils from Google Play Game Service.
Ok so this is what I did:
I commented out the line that is causing the problem (ActivityUtils.java line 56 of AndEngine)
I added this in my activity to the Android Manifest:
android:theme="#android:style/Theme.NoTitleBar"
It ends up looking something like:
<activity
android:name=".GameActivity"
android:theme="#android:style/Theme.NoTitleBar"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Exception requestFeature() must be called before adding content telling everything
call requestFullscreen() before setContenview()
Edit
try REQUEST FULLSCREEN after super.onCreate()
#Override
protected void onCreate(final Bundle pSavedInstanceState) {
super.onCreate(pSavedInstanceState);
this.applyEngineOptions(); //REQUEST FULLSCREEN

Class Not found Exception Android

I am trying to learn android programming and I am creating an app that starts with a splash screen and loads a menu class after that. the problem is I get this exception
06-04 10:59:37.166: E/AndroidRuntime(926): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.em.example1.MENU" on path: /data/app/com.em.example1-1.apk
I understand what the exception states but I do not understand why this is happening. In my splash screen class I load the Menu activity like this
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread timer = new Thread() {
public void run() {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Intent mainApp = new Intent("com.em.example1.MENU");
startActivity(mainApp);
}
}
};
timer.start();
and the menu class is defined in the manifest file like this
<activity
android:name="com.em.example1.MENU"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.em.example1.MENU" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
When i was loading a main activity with two buttons and a label everything was working ok. But when I changed it (inside my splash screen activity) so it would load Menu Activity it keeps giving me this error.
Thanks in advance
Right click on your project goto properties. Java Build Path. Choose Order export tab. Make sure that Android Private Libraries is selected. If you have referenced library project. do the same for the library project also. Clean and Build.
Maybe you should use this:
Intent mainApp = new Intent(this,com.em.example1.MENU.class);
startActivity(mainApp);
You may use this code, i have made some changes. it may be help u..
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread timer = new Thread() {
public void run() {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
MENU.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Intent mainApp = new Intent(MENU.this,com.em.example1.MENU.class);
MENU.this.startActivity(mainApp);
}
});
}
}
};
timer.start();
the stuff f in manifest before what you listed is what? What you are looking for is that to seee what the app package name is..
Try changing this line in your manifest file.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
And also try this thing
Try going to Project -> Properties -> Java Build Path -> Order & Export and ensure Android Private Libraries are checked for your project and for all other library projects you are using. Clean all projects afterwards and see what happens.
As it turns out I the error was too simple to realize...... I had the word Menu capitalized in Android Manifest in the name and not only in action name. Thanks for trying to help me everyone

How to add click listeners into a string in Android/Java Textview?

What im trying to accomplish is something that is standard in most twitter apps, in a textview there may be an "#" mention or a "#" hashtag preceding a word in a text string and they are actually able to add a click listener onto that word that launches another activity, does anyone know how this is achieved? below I have attached an example photo showing what i'm trying to achieve, any help would go a long way thanks
Take a look at the Linkify class. It allows you to add Links within you TextViews, for a given regular expression.
The following has been extracted from this article:
TextView mText = (TextView) findViewById(R.id.mytext);
Pattern userMatcher = Pattern.compile("\B#[^:\s]+");
String userViewURL = "user://";
Linkify.addLinks(mText, userMatcher, userViewURL);
Pattern is used to create new pattern from given reguler expression like example above which catch any text like #username in the given text , then you have to define your user:// scheme this also have to be defined in activity which will catch the clicks and last one Linkify.addLinks make all of them work together. Lets look at Android.manifest file for intent filter.
<activity android:name=”.DirectMessageActivity” >
<intent-filter>
<category android:name=”android.intent.category.DEFAULT”/>
<action android:name=”android.intent.action.VIEW” />
<data android:scheme=”user” />
</intent-filter>
</activity>
When you click #username this is the activity that will catch the click and process the clicked string. Yes we didnt mention about what is send to DirectMessageActivity when user click #username , as you might guess “username” string will be passed to DirectMessageActivity. You can get this string like this.
Uri data = getIntent.getData();
if(data != null){
String uri = data.toString();
username = uri.substring(uri.indexOf("#")+1);
}
Try it this way.......
TextView tv[] = new TextView[subCategory.length];
for (int i = 0; i < subCategory.length; i++) {
tv[i] = new TextView(this);
tv[i].setText(subCategory[i]);
tv[i].setId(i);
sCategoryLayout.addView(tv[i]);
tv[i].setOnClickListener(onclicklistener);
}
onclicklistener method :
OnClickListener onclicklistener = new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v == tv[0]){
//do whatever you want....
}
}
};

Categories