My goal is to create a simple ball in the mobile screen center so I can move it around the screen as they drag my finger.
For that I wanted to use the Canvas and bitmap (I do not know if it's the best way seen as already said I am new in the Android world).
I created a function in my Activity so that when a button was clicked, a activity containing the script to the canvas design was created (Again not know if it's the best way. In a php script or javascript I would create the ball in the function itself). My code is as follows:
public void StartGame(View v) {
Intent i = new Intent(MainActivity.this, ball.class);
startActivity(i);
}
By doing this it should call the following activity:
com.teste package;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class ball extends View {
Paint pincelPreto private;
Paint pincelAmerelo private;
Public ball (Context context) {
super (context);
}
Public ball (Context context, attributeSet attrs) {
super (context, attrs);
setBackgroundColor (Color.LTGRAY);
pincelPreto = new Paint ();
pincelPreto.setColor (Color.BLACK);
pincelAmerelo = new Paint ();
pincelPreto.setColor (Color.YELLOW);
setFocusable (true);
}
#Override
protected void onDraw (Canvas canvas) {
super.onDraw (canvas);
canvas.drawCircle (200, 200, 200, pincelAmerelo);
}
}
And both draw a ball at every location ...
But I get the following error:
Android.content.ActivityNotFoundException: Unable to find explicit activity class {com.teste / com.teste.ball}; have you declared this activity in your AndroidManifest.xml?
What am I doing wrong?
OBS.: I maybe call activity because i dont know the real name of it.
Expanding on Neo's answer above and given your edited question:
The reason you are getting the Android.content.ActivityNotFoundException is because "ball" is a View, not an Activity, and so you cannot start "ball" as an activity.
public void StartGame(View v) {
Intent i = new Intent(MainActivity.this, ball.class);
startActivity(i);
}
Since you are new to Android, try to visualize an Activity as a component that usually takes over the whole screen, and a View as a smaller piece of that. You want your ball to display within your activity.
In your res/layout folder you should have a layout xml file for your MainActivity. You can add your ball view in here with some xml, similar to the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.teste.ball
android:id="#+id/ball"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.teste.ball>
</LinearLayout>
You may hit other problems once you've gotten that far, but it should be easier to debug then.
I agree with the comment above to learn the basics first before jumping in to a complicated application. Take a look at the Android Developer pages to learn the components and trying simple tutorials. There are a lot of components that make up an Android application and fully understanding them and how they interact with each other will make your life easier :). Good luck and welcome to Android!
Edit to answer question below ...can i do it with java? i searched something about "inflate" a view but i dont know if it is correct?
Yes you can add a view to the Activity's parent layout using addView. Inflate is for instantiating views in your XML into Java objects, so it will not work in your case because you don't have an xml file for your Ball layout. You would need to create a new Ball object and use addView to add it to your layout:
LinearLayout layout = findViewById(R.id.main);
Ball ball = new Ball(this);
ball.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
layout.addView(ball);
where layout is the parent layout found in your activity's XML. You may need to assign it an ID if you haven't already, so if we use my example above, your LinearLayout tag would look like:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
If you want to create an activity then you need to extend it by Activity class. By extending view you can create a custom view, which you can use within xml or dynamically in your activity or fragment. For example ImageView, TextView, EditText, All layouts extends View, that you can use within your activity or fragment either by xml or dynamically.
As others have noted, Ball extends View, which is not an Activity. To use the startActivity() method, you need to pass it an Activity. First create your BallView:
package com.test.myapplication;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class BallView extends View {
private final Paint pincelPreto;
private final Paint pincelAmerelo;
public BallView(final Context context) {
super(context);
setBackgroundColor(Color.LTGRAY);
pincelPreto = new Paint();
pincelPreto.setColor(Color.BLACK);
pincelAmerelo = new Paint();
pincelAmerelo.setColor(Color.YELLOW);
}
#Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(200, 200, 200, pincelAmerelo);
}
}
Then create a BallActivity. This consists of both a Java class and an XML resource that you put under res/layout/activity_ball.xml. Below is an example XML resource:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.test.myapplication.BallView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"/>
</FrameLayout>
And the BallActivity class:
package com.test.myapplication;
import android.app.Activity;
import android.os.Bundle;
public class BallActivity extends Activity {
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ball);
}
}
The last thing that needs to be done in order to launch BallActivity is to add it to AndroidManifest.xml (otherwise you'll continue to get ActivityNotFoundException):
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.test.myapplication"
xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".BallActivity"/>
</application>
</manifest>
Hope this helps.
Related
Here's my code for clicking the button from my class showInforActivity:
btnRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(showInfoActivity.this, InformationFragment.class);
startActivity(intent);
}
});
Whenever I click the button I got error Unable to find explicit activity class {com.example.drawerapplication/com.example.drawerapplication.ui.information.InformationFragment}; have you declared this activity in your AndroidManifest.xml? and it loads the previous class and layout instead of loading this
InformationFragment class:
package com.example.drawerapplication.ui.information;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.example.drawerapplication.databinding.FragmentInformationBinding;
public class InformationFragment extends Fragment {
private FragmentInformationBinding binding;
private EditText name, address, age, contact;
private Button btnAdd, btnViewData;
DatabaseHelper mDatabaseHelper;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentInformationBinding.inflate(inflater, container, false);
View root = binding.getRoot();
name = binding.name;
address = binding.address;
age = binding.age;
contact = binding.contact;
btnAdd = binding.add;
btnViewData = binding.viewdata;
mDatabaseHelper = new DatabaseHelper(getActivity());
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (name.length() != 0 && address.length() != 0
&& age.length() != 0 && contact.length() != 0){
mDatabaseHelper.addData(name.getText().toString(), address.getText().toString(),
age.getText().toString().trim(), Long.valueOf(contact.getText().toString().trim()));
toastMessages("Data Successfully Inserted!");
}else {
toastMessages("Please complete all the requirements needed");
}
}
});
btnViewData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getContext(), ListDataActivity.class);
startActivity(intent);
}
});
return root;
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
private void toastMessages(String message){
Toast.makeText(getContext(),message,Toast.LENGTH_SHORT).show();
}
}
The layout of this InformationFragment is fragment_information:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.information.InformationFragment"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp">
...
Heres my **AndroidManifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.drawerapplication">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<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.DrawerApplication">
<activity android:name=".ui.information.ListDataActivity"/>
<activity android:name=".ui.information.showInfoActivity"/>
<activity
android:name=".MainActivity"
android:exported="true"
android:label="#string/app_name"
android:theme="#style/Theme.DrawerApplication.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I tried adding InformationFragment there however, it says Class referenced in the manifest, com.example.drawerapplication.InformationFragment, was not found in the project or the libraries
Please let me know what I'm missing or if you need more information. Thanks!
You cannot use an Intent to start/create a Fragment much like you would for an Activity. A Fragment actually lives inside an Activity i.e. its lifecycle is bound to an Activity. To start a Fragment you have to use the FragmentManager that is available with the Activity instance
This error is coming up because Android thinks that your InformationFragment is an Activity rather than a Fragment and hence it is asking you if you have declared it in your AndroidManifest.xml file because as the rule says, you need to have each Activity in your app declared inside the AndroidManifest.xml file
So, now you can use something like this, inside your showInfoActivity. Technically there are many solutions available as to what you could essentially do and that's why I linked you to all possible solutions rather than just writing them here
You can not use Intent for navigate to Fragment from a Activity.
For this reason you are getting this error. As, Intent receive 2 parameter Intent(FromActivity, ToActivity.class) . you are using fragment in 2nd parameter. We know that, when we create a activity then it it declared with AndroidManifest.xml file. Here, in your manifest file there are not any activity called InformationFragment.
You can learn Android Navigation Component to easily communicate with Activity and fragments.
This question already has answers here:
Android 1.6: "android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application"
(16 answers)
Closed 5 years ago.
Whenever I launch my activity it crashes. I don't know what the problem is. My code, xml resources and Android manifest looks fine. If anyone could
help me that would be appreciated!
The issue is caused by a android.view.WindowManager$BadTokenException, which is mentioned in the LogCat
Java Code
package com.example.hp.machine;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class Machine extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.machine);
Button click = (Button) findViewById(R.id.click);
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(Machine.this);
builder.setTitle("Warning")
.setIcon(R.drawable.bomb)
.setMessage("Do you want to Die ?")
.setCancelable(false) ;
AlertDialog alert = builder.create();
alert.show();
}
});
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/machine"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.hp.machine.Machine"
android:background="#drawable/splash_screen"
>
<Button
android:layout_height="wrap_content"
android:layout_width="130dp"
android:text="click"
android:layout_marginTop="200dp"
android:id="#+id/click"
android:textColor="#android:color/white"
android:textStyle="bold"
android:fontFamily="serif"
android:background="#android:color/background_dark"
/>
</RelativeLayout>
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hp.machine">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Machine">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
LogCat
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:789)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:298)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.app.Dialog.show(Dialog.java:325)
at com.example.hp.machine.Machine.onCreate(Machine.java:46)
at android.app.Activity.performCreate(Activity.java:6609)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3113)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3275)
at android.app.ActivityThread.access$1000(ActivityThread.java:218)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1744)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:7007)
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:1404) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
07-19 17:13:23.830 28841-28841/com.example.hp.machine I/Process: Sending signal. PID: 28841 SIG: 9
You can not write AlertDialog in onCreate() method.
Replace it at onResume() method.
Change the getBaseContext() to Machine.this
package com.example.hp.machine;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class Machine extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.machine);
Button click = (Button) findViewById(R.id.click);
AlertDialog.Builder builder = new AlertDialog.Builder(Machine.this);
builder.setTitle("Warning")
.setIcon(R.drawable.bomb)
.setMessage("Do you want to Die ?")
.setCancelable(false) ;
AlertDialog alert = builder.create();
alert.show();
}
}
I assume the space in AppCompatActivity (the extend part) is an SO import issue.
You use getBaseContext, when you should reference the context to the current object:
AlertDialog.Builder builder = new AlertDialog.Builder(Machine.this
/*Inside nested classes, this refers to that class. This is just good practice to do even
if you aren't inside a nested class/thread*/);
When showing dialogs, you need to do it:
On the UI thread
With the application context
Using outside the UI thread ends up with leaked window.
Just saw now, you run on a different thread.
Inside the onClick method, you add this:
runOnUiThread(new Runnable() {
#Override
public void run() {
//Add your dialog code here
}
});
and add the dialog code inside.
One thing I do not understand how come onClick get called while activity is being created.
onClick should be called on clicking event.
I am currently building an android app. I understand the basics and I did a number of apps but now my project is bigger. My app include a number of screens with NavigationDrawer included which forces me to use an extension of Fragment class on every class I want to be displayed on my application.
Here is my problem -some time ago I create an app a simple one page google maps screen and it works just fine. I want to do the same thing on the app I am currently working on but all it gives me when I go to the page is the google log at the bottom left screen and the rest is grey like view (no map is displayed).I searched for solution in a lot of places including this site and I could get as an answer was that it might have to do with my API key given to me by google.I ckecked that and I am pretty sure it is not from the key because I applied it on my one page google map app and it worked perfect.I also have all the permissions needed I checked that like 6 times.So my conclusion is there is something in the code that is preventing the map to be displayed.
Here is my code:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class guide extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflat and return the layout
View v = inflater.inflate(R.layout.test, container,
false);
return v;
}
class HoldFragmentPlace extends FragmentActivity{
private GoogleMap mMap;
public HoldFragmentPlace(){
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflat and return the layout
View v = inflater.inflate(R.layout.test, container,
false);
return v;
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
}
I need that Fragment extension for my NavigationDrawer to work so I create an inner class and applied the code for the map there.
Here is what I have in my manifest:
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="#string/google_maps_key" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
And here is my xml for the map:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_marginTop="-470dp" />
</LinearLayout>
I also tried a few other variations of the java code some of them does not include inner class and the result is still the same.I am either missing something very fundamental or I am misunderstanding some conception about Android.If you have read all that thank you for the spared time!
Check the APK signing. You have to assign a debug API key in testing and a Release API key when releasing APK. Insert the correct API key, clean and rebuild your project.
I've been there a year a go and I can assure that this was the problem. Double check your key and if it's a debug or release key.
Another thing to check is the package name of your app...
Let me know if you did and still get the grey view instead of the
UPDATE:
I was trying to include everything when I realized that your problem is only in the signing phase.
You only need to get the SHA-1 fingerprint of the debug keystore and put it in your API Key dialog. And trust me there's nothing I can write that can be more clear and informative than the Google documentation.
Follow the steps in this link to get the debug certificate and the SHA-1 fingerprint.
UPDATE 2:
In order to get the SHA-1 of the keystore you might check this thread .
I suspect some part missing :
(1) Declare permission to use MAPS_RECEIVE :
<permission android:name="com.example.yourpackage.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<!-- after declare use this -->
<uses-permission android:name="com.example.yourpackage.permission.MAPS_RECEIVE"/>
(2) Missing Declare gms version variable :
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
(3) The API_KEY may have some problem with generation :
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="your_key" />
Please check with above 3 suspects first : then if still error is there you can re-confirm steps to enable Google Maps from here
Check things related to API_KEY carefully
You can use SupportMapFragment to display map in your fragment.
The xml should be changed to
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/mapView"
android:layout_marginTop="-470dp"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
and your class would be like below
public class guide extends Fragment {
private GoogleMap mMap;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflat and return the layout
View v = inflater.inflate(R.layout.test, container, false);
((SupportMapFragment) getFragmentManager()
.findFragmentById(R.id.mapView)).getMapAsync (new OnMapReadyCallback(){
#Override
public void onMapReady(final GoogleMap map) {
this.mMap = map;
mMap.setMyLocationEnabled(true);
setUpMap();
}
});
return v;
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
Note: Please update your google play services if you dont find the getMapAsync method for your SupportMapFragment.
I have been trying to find the cause of weird formatting style inconsistencies for my Views throughout my application and I think I have narrowed it down with this example.
I set up two equivalent layouts of various Viewss with exactly the same procedure and only varying the Context supplied in creation. In the first set, each View is created with the application's context through Activity.getApplicationContext(), whereas in the second set the Views are fed the activity's context through this.
The result is vastly different:
Any suggestions on why using the application context causes the garbage (and inconsistent - colours are white as well as grey) formatting seen in the screenshot?
Activity code:
import android.os.Bundle;
import android.app.Activity;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TextViews
TextView tv1 = new TextView(getApplicationContext());
tv1.setText("With Application context");
TextView tv2 = new TextView(this);
tv2.setText("With Activity context");
// Spinners
Spinner sp1 = new Spinner(getApplicationContext());
sp1.setAdapter(new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, new String[] {"App context 1", "App context 2", "App context 3"}));
Spinner sp2 = new Spinner(this);
sp2.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, new String[] {"Act context 1", "Act context 2", "Act context 3"}));
// Edittexts
EditText et1 = new EditText(getApplicationContext());
et1.setText("Application Context");
EditText et2 = new EditText(this);
et2.setText("Activity Context");
// Buttons
Button b1 = new Button(getApplicationContext());
b1.setText("Application Context");
Button b2 = new Button(this);
b2.setText("Activity Context");
// Layout structure
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
ll.addView(tv1);
ll.addView(sp1);
ll.addView(et1);
ll.addView(b1);
ll.addView(tv2);
ll.addView(sp2);
ll.addView(et2);
ll.addView(b2);
setContentView(ll);
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo.Light" >
<activity
android:name="com.test.test.MainActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo.Light" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
In Android sources getApplicationContext() returns Application object which extends ContextWrapper, so using getApplicationContext() you are passing ContextWrapper subclass, but when you pass this, you are passing an Activity object which extends ContextThemeWrapper so you are passing ContextThemeWrapper subclass. Now the difference between ContextWrapper and ContextThemeWrapper is that ContextWrapper simply delegates all of its calls to another Context and ContextThemeWrapper allows you to modify the theme from what is in the wrapped context.
Although, the question was more about why exactly this is happening (as opposed to the cause which was clear), here are also some helpful posts which explain the perils of incorrectly using application context and how to choose a context correctly:
When to call activity context OR application context?
Using Application context everywhere?
Most importantly from #CommonsWare:
"getApplicationContext() is not a complete Context and consequently does not support everything that Activity does."
Awesome post about Context that should clarify everything:
http://www.doubleencore.com/2013/06/context/
So I just started learning to develop Android apps, and I have a programming background (Python mainly), so I somewhat know what I'm doing. I'm having a problem with using startActivity(). I've commented code to figure out exactly where the error gets thrown, and it happens right as startActivity() is encountered. The error I get is from the emulator and it is just a popup window that says, "Unfortunately, Test has stopped." (Test is my program name) after I click my button. My code is this
package com.test.test;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class TestActivity extends Activity {
public final static String EXTRA_MESSAGE = "com.test.test.MESSAGE";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public class DisplayMessageActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
}
public void sendMessage(View view) {
setContentView(R.layout.main);
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.textBox1);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
Now I know that won't do anything yet, but why is it crashing?
My XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<EditText android:id="#+id/textBox1"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="#string/textBox1Hint" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button1"
android:onClick="sendMessage" />
</LinearLayout>
My manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TestActivity"
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=".DisplayMessageActivity" >
</activity>
</application>
</manifest>
I saw that a lot of other people were having problems with this because they had not declared their activities in the manifest, but I think I have done so properly. Any help would be so greatly appreciated.
One possible problem is that
EditText editText = (EditText) findViewById(R.id.textBox1);
returns null because you dont set anywhere the layout for your activity (with setContentView)
If your editetext is included in view (passed to sendMessage), you can find it with
EditText editText = (EditText) view.findViewById(R.id.textBox1);
I think problem is you are on DisplayMessageActivity and starting the same activity.
What you need to do is start test activity and call DisplayMessageActivity from intent.
Use separate files for TestActivity and DisplayMessageActivity classes. In your given code you are not specifying a layout for your DisplayMessageActivity activity using setContentView.
the problem is this,
you declare in the manifest that the main class is TestActivity:
<activity
android:name=".TestActivity"
android:label="#string/app_name" >
but you wanted to start DisplayMessageActivity,
so, change this to the following:
public class TestActivity extends Activity {
#Override
I can't understand what you are actually trying to achieve by starting the same activity again. Try this,
public class DisplayMessageActivity extends Activity {
private String message ;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setLayout(R.layout.<name of the xml file> ); // change the name if it is not in layout folder
EditText editText = (EditText) findViewById(R.id.textBox1);
String message = editText.getText().toString();
Button submitBtn = (Button) findViewById(R.id.button1);
submitBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast toast = Toast.makeText(DisplayMessageActivity.this,
message,
Toast.LENGTH_SHORT);
toast.show();
}});
}
}
The above code simply displays the String, This is just a sample code... Hope that helps!!!
EDIT
To run this code you must also add id tag to your Button Tag inside XML file having value button1..
Actullay you have created the Activity inside activity. Which is not much pref-able but if want to stick with that then you have to change the android:name=".DisplayMessageActivity" to