This is doing my head in, and it's probably something simple that's causing it - so I think I need a new set of eyes looking at it.
All activities are defined in the manifest. I've made sure all attributes are initialised in onCreate/constructor.
The 'Circle' object is just a generic object with gets and sets for x, y, radius and colour.
Any help greatly appreciated.
10-01 16:06:28.338: E/AndroidRuntime(18306): FATAL EXCEPTION: main
10-01 16:06:28.338: E/AndroidRuntime(18306): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dbk.parallelreaction/com.dbk.parallelreaction.GameActivity}: java.lang.NullPointerException
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2308)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2358)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.app.ActivityThread.access$600(ActivityThread.java:153)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.os.Looper.loop(Looper.java:137)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.app.ActivityThread.main(ActivityThread.java:5227)
10-01 16:06:28.338: E/AndroidRuntime(18306): at java.lang.reflect.Method.invokeNative(Native Method)
10-01 16:06:28.338: E/AndroidRuntime(18306): at java.lang.reflect.Method.invoke(Method.java:511)
10-01 16:06:28.338: E/AndroidRuntime(18306): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
10-01 16:06:28.338: E/AndroidRuntime(18306): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
10-01 16:06:28.338: E/AndroidRuntime(18306): at dalvik.system.NativeStart.main(Native Method)
10-01 16:06:28.338: E/AndroidRuntime(18306): Caused by: java.lang.NullPointerException
10-01 16:06:28.338: E/AndroidRuntime(18306): at com.dbk.parallelreaction.util.GameView.<init>(GameView.java:51)
10-01 16:06:28.338: E/AndroidRuntime(18306): at com.dbk.parallelreaction.GameActivity.onCreate(GameActivity.java:64)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.app.Activity.performCreate(Activity.java:5104)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
10-01 16:06:28.338: E/AndroidRuntime(18306): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262)
The two files in question:
GameActivity.java
package com.dbk.parallelreaction;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.dbk.parallelreaction.util.GameView;
public class GameActivity extends Activity {
// GameView object to hold current level
private GameView game;
// level/score persistance
private int currentLevel;
private int currentScore;
// game countdown timer
private CountDownTimer timer;
private int timerTime; // in milliseconds
private int timerPeriod; // in ms also
private int timerIndex;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
// initialise
timerTime = 10000;
timerPeriod = 50;
timerIndex = (int) timerTime / timerPeriod;
// aesthetic stuff
TextView ins = (TextView) findViewById(R.id.GameInstructions);
Typeface tf = Typeface.createFromAsset(getAssets(), "Economica-Regular.ttf");
ins.setTypeface(tf);
ins.setTextColor(Color.WHITE);
ins.setTextSize(18);
// get extras
Bundle extras = getIntent().getExtras();
currentLevel = extras.getInt("LEVEL");
currentScore = extras.getInt("SCORE");
// check if starting new game, or going to next level
switch(currentLevel) {
case 1:
// new level
break;
case 2:
// etc
break;
}
// add the game view to the layout
FrameLayout frame = (FrameLayout) findViewById(R.id.GameContainer);
game = new GameView(this, 2);
frame.addView(game);
// timer bar
final ProgressBar pb = (ProgressBar) findViewById(R.id.GameTimerBar);
pb.setMax(timerIndex);
pb.setProgress(timerIndex);
timer = new CountDownTimer(timerTime, timerPeriod) {
#Override
public void onFinish() {
pb.setProgress(timerIndex);
Bundle extras = new Bundle();
extras.putInt("SCORE", 16); // placeholder score
Intent i = new Intent(getApplicationContext(), GameOverActivity.class);
i.putExtras(extras);
// GAME OVER if timer bar empties
finish();
startActivity(i);
}
#Override
public void onTick(long msLeft) {
timerIndex--;
pb.setProgress(timerIndex);
}
}.start();
}
// cancel timer if user exits game
public void onBackPressed() {
super.onBackPressed();
timer.cancel();
}
}
GameView.java updated
package com.dbk.parallelreaction.util;
import java.util.ArrayList;
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.dbk.parallelreaction.R;
public class GameView extends SurfaceView {
// Temp ArrayList containing Circle objects
private ArrayList<Circle> circles;
// Paint object for colour info
private Paint paint;
// number of circles to draw depending on level
private int numCircles;
// Current score in the current level
private int levelScore;
public GameView(Context context, int numberCircles) {
super(context);
LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// replace custom_layout with the name of the .xml file that contains the `FrameLayout` with id R.id.GameContainer
View v = inflater.inflate(R.layout.activity_game, (ViewGroup) GameView.this.getParent(), true);
FrameLayout frame = (FrameLayout) v.findViewById(R.id.GameContainer);
// initialise
circles = new ArrayList<Circle>();
paint = new Paint();
levelScore = 0;
numCircles = numberCircles;
// Get the game container FrameView
int frameW = frame.getWidth();
int frameH = frame.getHeight();
int frameL = frame.getLeft();
int frameT = frame.getTop();
// fill arraylist with random circles
Random random = new Random();
for(int i=0; i<numCircles; i++) {
// generate coords within the frame
int x = random.nextInt((frameL+frameW)-frameL) + frameL;
int y = random.nextInt((frameT+frameH)-frameT) + frameT;
// random radius between 50 and 10
int r = random.nextInt(50-10) + 10;
// add them to the ArrayList
circles.add(new Circle(x, y, r, Color.WHITE));
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=0; i<numCircles; i++) {
Circle c = circles.get(i);
// set colour
paint.setColor(c.getColor());
// draw circle to canvas
canvas.drawCircle(c.getX(), c.getY(), c.getRadius(), paint);
}
}
}
If your custom SurfaceView will have a layout you need to inflate it. On your constructor you have
FrameLayout frame = (FrameLayout) findViewById(R.id.GameContainer);
You are trying to reference a FrameLayout that has not been inflated yet. To inflate the corresponding .xml you need to use a LayoutInflator. You can get a reference to the LayoutInflated via the Context passed in to your SurfaceView. For example like this:
public GameView(Context context, AttributeSet attrs, int numberCircles){
super(context,attrs);
LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//replace custom_layout with the name of the .xml file that contains the `FrameLayout` with id R.id.GameContainer
View v = inflater.inflate(R.layout.custom_layout, (ViewGroup) GameView.this.getParent(), true);
FrameLayout frame = (FrameLayout)v.findViewById(R.id.GameContainer);
//The rest of your code...
}
Also, If you are going to add your GameView to an .xml file you need to use the SurfaceView(Context context, AttributeSet attrs) constructor.
Please check your XML that whether you have supplied correct ID for Frame Layout in GameView.java
Related
I was making a code to create a show list by ListView{in content_main.xml} like contact view.
I build a database in the (SQLite Expert Professional) with a table(name: "contact") that was contained a few name and family and numbers, with ID,NAME,fAMILY and PHONE NUMBER columns.
ID was unique, auto increment and primary key...other were Text except number that was CHAR.
then I calling them to my ListView as you see in below.(before it I made a row_list activity to made my listview , custom) but there was an Error and I can't find it.
{I could find my database.db file with that's table in the source data files that means my mistake wasn't from creating database.}
plz help me.I wanna learn android (as fast as i can) to get a JOB and I need it..
Errors.Android Monitor.Logcat
09-08 05:27:32.005 5692-5692/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x94c4fb20)
09-08 05:27:32.005 5692-5692/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: mizco.phonebook, PID: 5692
java.lang.RuntimeException: Unable to start activity ComponentInfo{mizco.phonebook/mizco.phonebook.Main}: android.database
.CursorIndexOutOfBoundsException: Index 5 requested, with a size of 5
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2193)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2243)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5019)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.CursorIndexOutOfBoundsException: Index 5 requested, with a size of 5
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:426)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at mizco.phonebook.database.getfulllist(database.java:97)
at mizco.phonebook.Main.onCreate(Main.java:36)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2157)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2243)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5019)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Main.java
package mizco.phonebook;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class Main extends AppCompatActivity {
private database db;
private String [][] res ;
private ListView list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
list = (ListView) findViewById(R.id.main_list);
db = new database(this);
db.startusing();
db.open();
res = db.getfulllist();
db.close();
list.setAdapter(new AA());
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
class AA extends ArrayAdapter<String>{
public AA() {
super(Main.this, R.layout.row_list, res[0]);
}
#NonNull
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater in = getLayoutInflater();
View row = in.inflate(R.layout.row_list,parent,false);
TextView name = (TextView) row.findViewById(R.id.row_name);
TextView number = (TextView) row.findViewById(R.id.row_number);
name.setText(res[0][position]+" "+res[1][position]);
number.setText(res[2][position]);
return row;
}
}
}
Class : database.java
package mizco.phonebook;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by Mahdi on 9/2/2017.
*/
public class database extends SQLiteOpenHelper {
public static String dbname= "database";
public static String dbpath="";
private Context mctxt;
private SQLiteDatabase mydb;
public database(Context context) {
super(context, dbname, null, 1);
mctxt = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
private boolean existdatabase(){
File m312 = new File(dbpath+dbname);
return m312.exists();
}
private void copydatabase(){
try {
InputStream IS = mctxt.getAssets().open(dbname);
OutputStream OS = new FileOutputStream(dbpath+dbname);
byte[] buffer = new byte[1024];
int length;
while ((length = IS.read(buffer))>0){
OS.write(buffer,0,length);
}
OS.flush();
OS.close();
IS.close();
} catch (Exception e) {
}
}
public void open(){
mydb = SQLiteDatabase.openDatabase(dbpath+dbname, null, SQLiteDatabase.OPEN_READWRITE);
}
public void close(){
mydb.close();
}
public void startusing () {
dbpath = mctxt.getFilesDir().getParent() + "/databases/";
if (!existdatabase()) {
this.getWritableDatabase();
copydatabase();
}
}
public String[][] getfulllist(){
Cursor cu = mydb.rawQuery("select * from Contact",null);
String [][] r = new String[3][cu.getCount()];
for (int i= 0;i<=cu.getCount();i++){
cu.moveToPosition(i);
r[0][i]=cu.getString(1);
r[1][i]=cu.getString(2);
r[2][i]=cu.getString(3);
}
return r;
}
}
You're stepping off the end of the cursor. Your code should read
for (int i= 0;i < cu.getCount();i++){
cu.moveToPosition(i);
r[0][i]=cu.getString(1);
r[1][i]=cu.getString(2);
r[2][i]=cu.getString(3);
}
return r;
There is one button I set in Scene2.java.I want to use the button to get in other activities Scene3.java,GameOver.java Everything worked fine until its about to open the new activity,every time the app crashed there. I want to know if there're any mistake I made in the connection,which I mean the newIntent and getIntent inScene2.java GameOver.javaand Scene3.java
Scene2.java
package com.group5.littlered;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class Scene2 extends Activity {
MediaPlayer bird;
MediaPlayer bgm;
int position = 0;
String[] conversation;
TextView frame;
ImageView conframe;
final String[] ListStr = { "Wake up and ask her", "Peek her secretly" };
int plot = 0;
#Override
public void onBackPressed() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
// Remove notification bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_scene2);
Intent intent1 = getIntent();
conversation = getResources().getStringArray(R.array.scene2);
frame = (TextView) findViewById(R.id.textView1);
Button next = (Button) findViewById(R.id.wtf);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (position < 2) {
String sentence = conversation[position];
frame.setText(sentence + "");
position++;
} else {
if (plot < 1) {
AlertDialog choice = new AlertDialog.Builder(
Scene2.this).create();
choice.setTitle("Pick a choice");
choice.setMessage(" ");
choice.setButton("Get up and ask her what happened",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
plot = 1;
}
});
choice.setButton2("Peek her secretly",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
plot = 2;
position = 4;
}
});
choice.show();
} else {
if (plot < 2) {
if (position < 4) {
String sentence = conversation[position];
frame.setText(sentence + "");
position++;
} else {
Intent intent2 = new Intent(Scene2.this,
GameOver.class);
startActivity(intent2);
finish();
}
} else {
if (position < 6) {
String sentence = conversation[position];
frame.setText(sentence + "");
position++;
} else {
Intent intent3 = new Intent(Scene2.this,
Scene3.class);
startActivity(intent3);
finish();
}
}
}
}
}
});
// BGM
bgm = MediaPlayer.create(Scene2.this, R.raw.voyager);
bgm.setLooping(true);
bgm.start();
// bird
bird = MediaPlayer.create(Scene2.this, R.raw.bird);
bird.setLooping(false);
bird.start();
}
}
Scene3.java
package com.group5.littlered;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class Scene3 extends Activity {
int position = 0;
String[] conversation;
TextView frame;
ImageView conframe;
#Override
public void onBackPressed() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
// Remove notification bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_scene3);
Intent intent3 = getIntent();
conversation = getResources().getStringArray(R.array.scene1);
frame = (TextView) findViewById(R.id.textView1);
Button next = (Button) findViewById(R.id.wtf);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (position < 6) {
String sentence = conversation[position];
frame.setText(sentence + "");
position++;
} else {
{
}
}
}
});
}
}
Again sorry for my poor ENGLISH, plz tell me what I need to post more to help you understand my problem.
my logcat
04-30 09:37:39.497: E/AndroidRuntime(4862): FATAL EXCEPTION: main
04-30 09:37:39.497: E/AndroidRuntime(4862): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.group5.littlered/com.group5.littlered.Scene3}: java.lang.NullPointerException
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.os.Handler.dispatchMessage(Handler.java:99)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.os.Looper.loop(Looper.java:137)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.app.ActivityThread.main(ActivityThread.java:5103)
04-30 09:37:39.497: E/AndroidRuntime(4862): at java.lang.reflect.Method.invokeNative(Native Method)
04-30 09:37:39.497: E/AndroidRuntime(4862): at java.lang.reflect.Method.invoke(Method.java:525)
04-30 09:37:39.497: E/AndroidRuntime(4862): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
04-30 09:37:39.497: E/AndroidRuntime(4862): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-30 09:37:39.497: E/AndroidRuntime(4862): at dalvik.system.NativeStart.main(Native Method)
04-30 09:37:39.497: E/AndroidRuntime(4862): Caused by: java.lang.NullPointerException
04-30 09:37:39.497: E/AndroidRuntime(4862): at com.group5.littlered.Scene3.onCreate(Scene3.java:45)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.app.Activity.performCreate(Activity.java:5133)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-30 09:37:39.497: E/AndroidRuntime(4862): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
04-30 09:37:39.497: E/AndroidRuntime(4862): ... 11 more
The line that is crashing is the line 45 of Scene3:
Button next = (Button) findViewById(R.id.wtf);
next.setOnClickListener(new View.OnClickListener() { // <-- THIS ONE
...
});
The cause is a NullPointerException. This means that the identifier "wtf" exists in R (this wouldn't compile otherwise) but is not found in the layer activity_scene3, as we wave the following statement line 38 of Scene3.onCreate():
setContentView(R.layout.activity_scene3); // and later on findViewById() returns `null`
You have to revisit this layout to ensure that the Button you are willing to access to actually exists, with the ID wtf.
Generally speaking, this is the danger in using a same ID in different layouts. This is prone to hide errors that would easily be found otherwise as this would just not compile.
Check your manifest file and add Scene3.java in it
<activity
android:name=".Scene3" >
</activity>
Always post question with exception, second this is may be you have not mention your other activity in manifest file like:
<activity
android:name=".Scene3">
</activity>
<activity
android:name=".GameOver">
</activity>
i'm stuck on a problem trying to call a method from another class (when ever I call a method from this class I get a crash with NullPointerException except from when it's a static function. I currently call render.Update() and get a logcat output of -> http://pastebin.com/njjxDiQZ
11-26 17:14:40.532: E/MediaPlayer(29755): Should have subtitle controller already set
11-26 17:14:40.752: E/AndroidRuntime(29755): FATAL EXCEPTION: main
11-26 17:14:40.752: E/AndroidRuntime(29755): Process: com.coursework.courseworkapp, PID: 29755
11-26 17:14:40.752: E/AndroidRuntime(29755): java.lang.NullPointerException
11-26 17:14:40.752: E/AndroidRuntime(29755): at com.coursework.courseworkapp.Visual.updateVisualizer(Visual.java:73)
11-26 17:14:40.752: E/AndroidRuntime(29755): at com.coursework.courseworkapp.Visual$1.onWaveFormDataCapture(Visual.java:48)
11-26 17:14:40.752: E/AndroidRuntime(29755): at android.media.audiofx.Visualizer$NativeEventHandler.handleCaptureMessage(Visualizer.java:669)
11-26 17:14:40.752: E/AndroidRuntime(29755): at android.media.audiofx.Visualizer$NativeEventHandler.handleMessage(Visualizer.java:700)
11-26 17:14:40.752: E/AndroidRuntime(29755): at android.os.Handler.dispatchMessage(Handler.java:102)
11-26 17:14:40.752: E/AndroidRuntime(29755): at android.os.Looper.loop(Looper.java:137)
11-26 17:14:40.752: E/AndroidRuntime(29755): at android.app.ActivityThread.main(ActivityThread.java:4998)
11-26 17:14:40.752: E/AndroidRuntime(29755): at java.lang.reflect.Method.invokeNative(Native Method)
11-26 17:14:40.752: E/AndroidRuntime(29755): at java.lang.reflect.Method.invoke(Method.java:515)
11-26 17:14:40.752: E/AndroidRuntime(29755): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
11-26 17:14:40.752: E/AndroidRuntime(29755): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
11-26 17:14:40.752: E/AndroidRuntime(29755): at dalvik.system.NativeStart.main(Native Method)
Any help would be appreciated i'm really stumped here.
First Class
package com.coursework.courseworkapp;
import java.util.Set;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Bitmap.Config;
import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
public class Visual{
byte[] fft;
byte[] mFFTBytes;
byte[] mBytes;
private Visualizer mVisualizer;
Render render;
private Rect mRect = new Rect();
private Paint mFlashPaint = new Paint();
private Paint mFadePaint = new Paint();
Bitmap mCanvasBitmap;
Canvas mCanvas;
public int Test(MediaPlayer player){
mVisualizer = new Visualizer(player.getAudioSessionId());
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
Visualizer.OnDataCaptureListener captureListener = new Visualizer.OnDataCaptureListener()
{
#Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate)
{
updateVisualizer(bytes);
}
#Override
public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate)
{
updateVisualizerFFT(bytes);
}
};
mVisualizer.setDataCaptureListener(captureListener, Visualizer.getMaxCaptureRate() / 2, true, true);
mVisualizer.setEnabled(true);
return player.getAudioSessionId();
}
public void updateVisualizer(byte[] bytes) {
mBytes = bytes;
}
public void updateVisualizerFFT(byte[] bytes) {
mFFTBytes = bytes;
render.Update();
//render.invalidate()
}
public byte[] getFFT(){
return mFFTBytes;
}
}
The Render Class
package com.coursework.courseworkapp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.media.audiofx.Visualizer;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
public class Render extends View {
public Render(Context context) {
super(context);
setMinimumWidth(800);
setMinimumHeight(1000);
setFocusable(true);
}
public void Update(){
//Will have code here after fix crash.
}
protected void onDraw(Canvas canvas){
canvas.drawColor(Color.RED);
//Will add more code here.
}
}
MainActivity.Java - How I start Visualise.java
public class MainActivity extends Activity {
private MediaPlayer mPlayer;
Visual visualize = new Visual();
Render render;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
render = new Render(this);
((LinearLayout) findViewById(R.id.root)).addView(render, 0);
//Log.d("Freq", "test");
mPlayer = MediaPlayer.create(this, R.raw.test2);
mPlayer.setLooping(true);
mPlayer.start();
//Log.d("Freq", "test");
Handler handler = new Handler();
Runnable runnable = new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
int i = visualize.Test(mPlayer);
//render.invalidate();
}
};
handler.postDelayed(runnable, 100);
/*byte[] fft = visualize.getFFT();
if(fft != null){
Toast.makeText(this,"yey",Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(this,"nope",Toast.LENGTH_LONG).show();
}*/
/* THis part didn't work, Why? Check the other example */
//Log.w("Freq", String.valueOf(fft.length));
/*for(int i = 0; i < fft.length; i++){
String s = new String();
Log.w("Freq", String.valueOf(fft[i]));
}*/
}
#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;
}
public void tryDraw(){
//render.Update();
}
}
Your visual class does not extend Activtiy. But you have
render = new Render(this);
this does not refer to Activity Context.
Also you are not inflating any layoutin visual class ((LinearLayout) findViewById(R.id.root)).addView(render, 0); will give you NullPointerException.
findViewById looks for a view with the id mentioned in the current inflated layout.
You declare Render render; but don't initialize it
You can do this only if render is static so fix that
VISUAL:
public class Visual {
Context mContext;
// constructor
public Visual(Context context){
this.mContext = context;
}
....
public void updateVisualizerFFT(byte[] bytes) {
mFFTBytes = bytes;
//Don't forget to initialize redender
Render render = new Render(this.mContext);
render.Update();
//render.invalidate()
}
}
RENDER:
public class Render extends View {
public Render(Context context) {
super(context);
setMinimumWidth(800);
setMinimumHeight(1000);
setFocusable(true);
}
}
MainActivity :
You should be able to run
int i = visualize.Test(mPlayer);
Read up on context
I'm trying to take an RGB value (not hexadecimal, the actual constant value, such as -16711936) from a textfield and display it in a new activity (to use it as an integer). I attempted to do this by converting the string to an integer, but it still ends up crashing the program. Here's the code:
FULL SOURCE:issue occurs in testvalue function
package com.example.seniordesign;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity { //1
//public final static String RGB_VALUE = "com.example.seniordesign.RGB_VALUE_USE";
TextView pixelcord, rgbvals, rgbnumvals, red, green, blue, RGB;
ImageView iv;
Button btn;
#Override
public void onCreate(Bundle savedInstanceState) { //2
/* GATHER THE INFORMATION FROM THE LAYOUT TO ORGANIZE APP*/
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* SET ON CLICK LISTENER TO GET CLICK REPSONSE -- LAUNCH CAMERA AND TAKE PHOTO */
/* SET VARIABLES FOR USE FROM EACH VIEW */
iv = (ImageView) findViewById(R.id.imageView); /* USE IMAGE VIEW FIELD*/
pixelcord = (TextView)findViewById(R.id.pixelcord); /* USE TEXT FIELD FOR PIXEL */
rgbvals = (TextView)findViewById(R.id.rgbvals); /* USE TEXT FIELD FOR RGB VALUES*/
btn = (Button) findViewById(R.id.takePhoto);
/* SET INFORMATION OF WHAT TO DO UPON EACH CLIK*/
iv.setOnTouchListener(imgSourceOnTouchListener);
red = (TextView)findViewById(R.id.red);
blue = (TextView)findViewById(R.id.blue);
green = (TextView)findViewById(R.id.green);
RGB = (TextView)findViewById(R.id.RGB);
/* =====================================CAMERA BUTTON=====================================*/
btn.setOnClickListener(new OnClickListener() { //3
#Override
public void onClick(View v) { //4
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
} //*4
}); //*3
/* =======================================================================================*/
} /* END OF ON CREATE*/ //*2
/* DECLARATION OF IMG TOUCH FUNCTION*/
OnTouchListener imgSourceOnTouchListener = new OnTouchListener() { //5
#Override
public boolean onTouch(View view, MotionEvent event) { //6
float eventX = event.getX();
float eventY = event.getY();
float[] eventXY = new float[] { eventX, eventY};
Matrix invertMatrix = new Matrix();
((ImageView)view).getImageMatrix().invert(invertMatrix);
invertMatrix.mapPoints(eventXY);
int x = Integer.valueOf((int)eventXY[0]); /* POTENTIALLY REDUNDANT*/
int y = Integer.valueOf((int)eventXY[1]);
/* CHECK TO MAKE SURE VALUES ARE WITHIN BITMAP RANGE*/
/* SET TEXT FUNCTION TO THE FIELD USING SET TEXT METHOD*/
pixelcord.setText("X:" + String.valueOf(eventX) + "/ Y:" + String.valueOf(eventY) );
Bitmap bitmap = ((BitmapDrawable)iv.getDrawable()).getBitmap();
int touchedRGB = bitmap.getPixel(x,y);
rgbvals.setText("Color Value" + "#" + Integer.toHexString(touchedRGB));
rgbvals.setTextColor(touchedRGB);
int rval = Color.red(touchedRGB);
int bval = Color.blue(touchedRGB);
int gval = Color.green(touchedRGB);
red.setText(String.valueOf(rval));
blue.setText(String.valueOf(bval));
green.setText(String.valueOf(gval));
RGB.setText(String.valueOf(touchedRGB));
return true;
} //*6
}; //*5
public void testvalue(View view) {
Intent intent = new Intent(this, TestValue.class);
TextView RGBval = (TextView) findViewById(R.id.RGB);
int rgb_val_use = Integer.parseInt((String) RGBval.getText().toString());
intent.putExtra("RGB_VALUE", (int)rgb_val_use);
startActivity(intent);
}
#Override
public void onActivityResult( int requestCode, int resultCode, Intent data)
{ //7
if(requestCode == 0)
{ //8
Bitmap theImage = (Bitmap) data.getExtras().get("data");
iv.setImageBitmap(theImage);
} //*8
} //*7
} //*1
and here is my logCat:
10-31 07:27:44.334: E/AndroidRuntime(9915): FATAL EXCEPTION: main
10-31 07:27:44.334: E/AndroidRuntime(9915): java.lang.IllegalStateException: Could not execute method of the activity
10-31 07:27:44.334: E/AndroidRuntime(9915): at android.view.View$1.onClick(View.java:2144)
10-31 07:27:44.334: E/AndroidRuntime(9915): at android.view.View.performClick(View.java:2485)
10-31 07:27:44.334: E/AndroidRuntime(9915): at android.view.View$PerformClick.run(View.java:9089)
10-31 07:27:44.334: E/AndroidRuntime(9915): at android.os.Handler.handleCallback(Handler.java:587)
10-31 07:27:44.334: E/AndroidRuntime(9915): at android.os.Handler.dispatchMessage(Handler.java:92)
10-31 07:27:44.334: E/AndroidRuntime(9915): at android.os.Looper.loop(Looper.java:123)
10-31 07:27:44.334: E/AndroidRuntime(9915): at android.app.ActivityThread.main(ActivityThread.java:3806)
10-31 07:27:44.334: E/AndroidRuntime(9915): at java.lang.reflect.Method.invokeNative(Native Method)
10-31 07:27:44.334: E/AndroidRuntime(9915): at java.lang.reflect.Method.invoke(Method.java:507)
10-31 07:27:44.334: E/AndroidRuntime(9915): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
10-31 07:27:44.334: E/AndroidRuntime(9915): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
10-31 07:27:44.334: E/AndroidRuntime(9915): at dalvik.system.NativeStart.main(Native Method)
10-31 07:27:44.334: E/AndroidRuntime(9915): Caused by: java.lang.reflect.InvocationTargetException
10-31 07:27:44.334: E/AndroidRuntime(9915): at java.lang.reflect.Method.invokeNative(Native Method)
10-31 07:27:44.334: E/AndroidRuntime(9915): at java.lang.reflect.Method.invoke(Method.java:507)
10-31 07:27:44.334: E/AndroidRuntime(9915): at android.view.View$1.onClick(View.java:2139)
10-31 07:27:44.334: E/AndroidRuntime(9915): ... 11 more
10-31 07:27:44.334: E/AndroidRuntime(9915): Caused by: java.lang.NumberFormatException: unable to parse 'RGB' as integer
10-31 07:27:44.334: E/AndroidRuntime(9915): at java.lang.Integer.parse(Integer.java:383)
10-31 07:27:44.334: E/AndroidRuntime(9915): at java.lang.Integer.parseInt(Integer.java:372)
10-31 07:27:44.334: E/AndroidRuntime(9915): at java.lang.Integer.parseInt(Integer.java:332)
10-31 07:27:44.334: E/AndroidRuntime(9915): at com.example.seniordesign.MainActivity.testvalue(MainActivity.java:125)
10-31 07:27:44.334: E/AndroidRuntime(9915): ... 14 more
Is it just a syntax error or am I going about this incorrectly? I appreciate the help
NOTE: The value in the textfield is techinically a string I guess, this is the code I used to place it in the field (touchedRGB is an integer value).
RGB.setText(String.valueOf(touchedRGB));
If it makes a difference, this is the XML from this particular section
<TextView
android:id="#+id/RGB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/green"
android:layout_alignBottom="#+id/green"
android:layout_marginLeft="40dp"
android:layout_toRightOf="#+id/green"
android:text="RGB" />
The problem is, you have a string("RGB") in your textView. So you got a NumberFormatException.
Set an integet value in your textView and try again.
java.lang.NumberFormatException: unable to parse 'RGB' as integer
Edit: Could you try code below?
public void testvalue(View view) {
try{
TextView RGBval = (TextView) findViewById(R.id.RGB);
String valueStoredInRGBvalTextView = RGBval.getText().toString();
int rgb_val_use = Integer.parseInt(valueStoredInRGBvalTextView);
Intent intent = new Intent(this, TestValue.class);
intent.putExtra("RGB_VALUE", (int)rgb_val_use);
startActivity(intent);
} catch (Exception e) {
// Not touched yet
}
}
Edit2:
You are setting the integer touch value to RGB textView after first touch occurs. If you invoke your testvalue method before touching anywhere, you'll get this exception. Change your testvalue method as I wrote above. Your problem will be solved.
try this you cannot cast the int value to String like this -> (int)(rgb_val_use)
change it into new Integer.toString(rgb_val_use);
intent.putExtra("RGB_VALUE",new Integer.toString(rgb_val_use));
Integer rgb = Integer.getInteger((String) RGBval.getText(), null);
if (rgb == null) {
// input string is not integer
} else {
// use rgb to start new activity
}
I am working on a drawing app and following the online tutorial here:
http://mobile.tutsplus.com/tutorials/android/android-sdk-create-a-drawing-app-essential-functionality/
There are no problem until the last part (as above). Then, I have tried to Clean and import the project again (virtual device was restarted everytime), but the problem still exists.
Would you mind help me to take a look at this?
Thanks in advance!!
P.S. I am using Eclipse ADT
Here is the error log:
09-01 03:27:25.144: E/AndroidRuntime(788): FATAL EXCEPTION: main
09-01 03:27:25.144: E/AndroidRuntime(788): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.earth0102.luckydraw/com.earth0102.luckydraw.MainActivity}: java.lang.ClassCastException: com.earth0102.luckydraw.MainActivity cannot be cast to android.view.View$OnClickListener
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.access$600(ActivityThread.java:141)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.os.Handler.dispatchMessage(Handler.java:99)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.os.Looper.loop(Looper.java:137)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.main(ActivityThread.java:5041)
09-01 03:27:25.144: E/AndroidRuntime(788): at java.lang.reflect.Method.invokeNative(Native Method)
09-01 03:27:25.144: E/AndroidRuntime(788): at java.lang.reflect.Method.invoke(Method.java:511)
09-01 03:27:25.144: E/AndroidRuntime(788): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-01 03:27:25.144: E/AndroidRuntime(788): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-01 03:27:25.144: E/AndroidRuntime(788): at dalvik.system.NativeStart.main(Native Method)
09-01 03:27:25.144: E/AndroidRuntime(788): Caused by: java.lang.ClassCastException: com.earth0102.luckydraw.MainActivity cannot be cast to android.view.View$OnClickListener
09-01 03:27:25.144: E/AndroidRuntime(788): at com.earth0102.luckydraw.MainActivity.onCreate(MainActivity.java:56)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.Activity.performCreate(Activity.java:5104)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
09-01 03:27:25.144: E/AndroidRuntime(788): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
09-01 03:27:25.144: E/AndroidRuntime(788): ... 11 more
AndroidManifest.xml :
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/CustomTheme" >
<activity
android:name="com.earth0102.luckydraw.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
MainActivity.java
package com.earth0102.luckydraw;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.view.Menu;
//implement the ability for the user to choose colors
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
//other features
import java.util.UUID;
import android.provider.MediaStore;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements onClickListener
{
//let user to choose colors from the palette
private DrawingView drawView;
//variable to represent the paint color button in the palette
private ImageButton currPaint, drawBtn, eraseBtn, newBtn, saveBtn;
//variable in three dimension
private float smallBrush,mediumBrush,largeBrush;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawView=(DrawingView)findViewById(R.id.drawing);
//1. retrieve the first paint color button in the palette area, which is initially going to be selected.
LinearLayout paintLayout = (LinearLayout) findViewById(R.id.paint_colors);
//2. get the first button and store it as the instance variable.
currPaint = (ImageButton) paintLayout.getChildAt(0);
//3. we use a different drawable image on the button to show that it is currently selected:
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
smallBrush=getResources().getInteger(R.integer.small_size);
mediumBrush=getResources().getInteger(R.integer.medium_size);
largeBrush=getResources().getInteger(R.integer.large_size);
//draw button
drawBtn = (ImageButton)findViewById(R.id.draw_btn);
drawBtn.setOnClickListener((OnClickListener)this);
//erase button
eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
eraseBtn.setOnClickListener((OnClickListener)this);
//new painting
newBtn = (ImageButton)findViewById(R.id.new_btn);
newBtn.setOnClickListener((OnClickListener)this);
//new painting
saveBtn = (ImageButton)findViewById(R.id.save_btn);
saveBtn.setOnClickListener((OnClickListener)this);
}
#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;
}
public void paintClicked(View view)
{
drawView.setBrushSize(drawView.getLastBrushSize());
//use chosen color
//1. check that the user has clicked a paint color
if(view!=currPaint)
{
//update color
ImageButton imgView = (ImageButton)view;
String color = view.getTag().toString();
drawView.setColor(color);
//update the UI to reflect the new chosen paint and set the previous one back to normal
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currPaint=(ImageButton)view;
}
}
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
if(view.getId()==R.id.draw_btn)
{
//draw button clicked
final Dialog brushDialog = new Dialog(this);
brushDialog.setTitle("Brush size");
brushDialog.setContentView(R.layout.brush_chooser);
//listen for clicks on size buttons - small, medium, large
ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
smallBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
drawView.setBrushSize(smallBrush);
drawView.setLastBrushSize(smallBrush);
brushDialog.dismiss();
}
});
ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
mediumBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
drawView.setBrushSize(mediumBrush);
drawView.setLastBrushSize(mediumBrush);
brushDialog.dismiss();
}
});
ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
largeBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
drawView.setBrushSize(largeBrush);
drawView.setLastBrushSize(largeBrush);
brushDialog.dismiss();
}
});
brushDialog.show();
}//end of draw button
else if (view.getId()==R.id.erase_btn)
{
//switch to erase - choose size
final Dialog brushDialog = new Dialog(this);
brushDialog.setTitle("Eraser size:");
brushDialog.setContentView(R.layout.brush_chooser);
//cancel - listen for clicks on size buttons
ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
smallBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
drawView.setBrushSize(smallBrush);
drawView.setLastBrushSize(smallBrush);
drawView.setErase(false);
brushDialog.dismiss();
}
});
ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
mediumBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
drawView.setBrushSize(mediumBrush);
drawView.setLastBrushSize(mediumBrush);
drawView.setErase(false);
brushDialog.dismiss();
}
});
//listen for clicks on size buttons
ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
largeBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
drawView.setBrushSize(largeBrush);
drawView.setLastBrushSize(largeBrush);
drawView.setErase(false);
brushDialog.dismiss();
}
});
brushDialog.show();
}//end of erase button
else if (view.getId()==R.id.new_btn)
{
String cancel = "Cancel";
//new button
AlertDialog.Builder newDialog = new AlertDialog.Builder(this);
newDialog.setTitle("New drawing");
newDialog.setMessage("Start new drawing (you will lose the current drawing)?");
newDialog.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
drawView.startNew();
dialog.dismiss();
}
});
newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
newDialog.show();
}//end of new button
else if (view.getId()==R.id.save_btn)
{
AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
saveDialog.setTitle("Save drawing");
saveDialog.setMessage("Save drawing to device Gallery?");
saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which)
{
//save drawing-use insertImage to attempt to write the image to the media store
//for images on the device, which should save it to the user gallery.
//We pass the content resolver, drawing cache for the displayed View, a randomly generated
//UUID string for the filename with JPG extension and a short description.
drawView.setDrawingCacheEnabled(true);
String imgSaved=MediaStore.Images.Media.insertImage(
getContentResolver(),drawView.getDrawingCache(),
UUID.randomUUID().toString()+".jpg","drawing");
if(imgSaved!=null)
{
Toast savedToast = Toast.makeText(getApplicationContext(),
"Drawing saved to Gallery!", Toast.LENGTH_SHORT);
savedToast.show();
}
else
{
Toast unsavedToast = Toast.makeText(getApplicationContext(), "Oops! Image could not be saved.",
Toast.LENGTH_SHORT);
unsavedToast.show();
}
drawView.destroyDrawingCache();
}
});
saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
saveDialog.show();
}//end of save button
}//onClick method
}
DrawingView.java
package com.earth0102.luckydraw;
import android.content.Context;
import android.view.View;
import android.util.AttributeSet;
//for drawing
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
//other features
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.TypedValue;
public class DrawingView extends View
{
private float brushSize, lastBrushSize;
//eraser flag
private boolean erase=false;
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF000000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
public DrawingView(Context context, AttributeSet attrs)
{
super(context, attrs);
setupDrawing();
}
private void setupDrawing()
{
//get drawing area setup for interaction
brushSize=getResources().getInteger(R.integer.medium_size);
lastBrushSize=brushSize;
//initial objects
drawPath=new Path();
drawPaint =new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
//instantiating a canvas paint object
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
public void setBrushSize(float newSize)
{
//update size for each brush
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
public void setLastBrushSize(float lastSize)
{
lastBrushSize=lastSize;
}
public float getLastBrushSize()
{
return lastBrushSize;
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
// override a couple of methods to make
//the custom View function as a drawing View
//view given size
super.onSizeChanged(w,h,oldw,oldh);
canvasBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
#Override
protected void onDraw(Canvas canvas)
{
//To allow the class to function as a custom drawing View,
//we also need to override the onDraw method
//draw view
canvas.drawBitmap(canvasBitmap, 0,0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
//detect user touch
float touchX=event.getX();
float touchY=event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
//redraw - Calling invalidate will cause the onDraw method to execute.
invalidate();
return true;
}
public void setColor(String newColor)
{
//set color and start by invalidating the view
invalidate();
//parse and set the color for drawing
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}
public void setErase (Boolean isErase)
{
//set erase true or false
erase=isErase;
if(erase)
drawPaint.setXfermode(new PorterDuffXfermode (PorterDuff.Mode.CLEAR));
else
drawPaint.setXfermode(null);
}
public void startNew()
{
//set a new draw
drawCanvas.drawColor(0,PorterDuff.Mode.CLEAR);
invalidate();
}
}
OnClickListener.java - it's requested to add another class to implement onClickListener in MainActivity, and so on.
package com.earth0102.luckydraw;
import android.view.View;
public interface onClickListener
{
public void onClick(View view);
}
In MainActivity, you should implement View.OnClickListener.
in this case, you don't need your own interface OnClickListener.java, just use View.OnClickListener
I mean, change
public class MainActivity extends Activity implements onClickListener
to
public class MainActivity extends Activity implements View.OnClickListener
In the MainActivity onCreate function, you are doing:
drawBtn.setOnClickListener((OnClickListener)this);
Here you are casing this to OnClickListener which is giving error. this gives you the activity context. You can trying to cast the activity context to OnClickListener, which is creating the casting exception. You can try just passing in the Activity's context like:
drawBtn.setOnClickListener(this);
Do the same for all the other buttons and don't cast it to OnClickListener. See if this changes something.
You are casting your activity to on click listener.Do like this:
Button.setonclicklistener(commonclicklistener);
Onclicklistener commonclicklistener = new view.onclicklistener{
//add a switch case based on your buttons and perform the code here like
Switch(v.getid)
Case (draw button):
//code
Case(imagebuttpn):
//code
}
This is an rough idea .you can find code in net.I am typing through mobile otherwise would have provided with the code.