[Q] Drawable not visible when camera preview is present - Java for Android App Development

First of all, this is my first post here so hello everyone.
I'm writing an app that requires displaying a semi-transparent PNG layer over a camera preview. Everything was fine until I wanted to publish it and make sure it works also on Android 2.x. It seems that on older versions of Android, the camera preview causes the drawable (in my case, a subclass of ImageView) to not show. The whole screen is white, but the buttons are visible. When I get rid of the preview, it works just fine - the drawable is visible as it should. It works like this both on the emulator and on real devices.
Here is my code (the whole project is in the attachment). The most interesting and probably guilty class is CameraPreview. The code doesn't crash, there's also no exceptions or other behavior like this.
MainActivity.java
Code:
public class MainActivity extends Activity
{
CameraPreview mPreview;
[user=439709]@override[/user]
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
mPreview = (CameraPreview)this.findViewById(R.id.cameraPreview);
}
[user=439709]@override[/user]
protected void onResume()
{
super.onResume();
mPreview.resume();
}
[user=439709]@override[/user]
protected void onPause()
{
super.onPause();
mPreview.pause();
}
}
CameraPreview.java
Code:
class CameraPreview extends ViewGroup implements SurfaceHolder.Callback
{
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
Context mContext;
int currentCamera = 0;
int noOfCameras = 0;
public CameraPreview(Context context)
{
super(context);
}
[user=1299008]@supp[/user]ressLint("NewApi")
[user=1299008]@supp[/user]ressWarnings("deprecation")
public CameraPreview(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
mContext = context;
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// checking what cameras we have
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO)
{
noOfCameras = Camera.getNumberOfCameras();
CameraInfo cameraInfo = new CameraInfo();
for(int i=0; i<noOfCameras; i++)
{
Camera.getCameraInfo(i, cameraInfo);
if(cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK)
{
currentCamera = i;
break;
}
}
}
}
public CameraPreview(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public void setCamera(Camera camera)
{
if(mCamera != null && camera == null)
mCamera.release();
mCamera = camera;
if(mCamera != null)
{
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
}
}
[user=439709]@override[/user]
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if(mSupportedPreviewSizes != null)
mPreviewSize = getOptimalPreviewSize(width, height);
}
[user=439709]@override[/user]
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
if(changed && getChildCount() > 0)
{
final View child = mSurfaceView;
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if(mPreviewSize != null)
{
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight)/2, width, (height + scaledChildHeight) / 2);
}
}
public void surfaceCreated(SurfaceHolder holder)
{
try
{
if(mCamera != null)
mCamera.setPreviewDisplay(holder);
}
catch(IOException exception)
{
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
if(mCamera != null)
mCamera.stopPreview();
}
// Chooses such preview's size that it just one "step" wider
// than needed. This ensures sharpness of the preview.
private Size getOptimalPreviewSize(int w, int h)
{
Size optimalSize = null;
int optimalWidth = 0;
for(Size size : mSupportedPreviewSizes)
{
if(size.width > optimalWidth)
{
optimalSize = size;
if(size.width >= w)
break;
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
public void resume()
{
setCamera(Camera.open());
}
public void pause()
{
setCamera(null);
}
}
CustomImageView.java
Code:
// aligns the content image to the top
public class CustomImageView extends ImageView
{
public CustomImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
setScaleType(ScaleType.MATRIX);
}
[user=439709]@override[/user]
protected boolean setFrame(int l, int t, int r, int b)
{
Matrix matrix = getImageMatrix();
float scaleFactor = getWidth()/(float)getDrawable().getIntrinsicWidth();
matrix.setScale(scaleFactor, scaleFactor, 0, 0);
setImageMatrix(matrix);
return super.setFrame(l, t, r, b);
}
}
activity_main.xml
Code:
<FrameLayout xmlns:android="h t t p:// schemas.android.com /apk/res/android"
xmlns:tools="h t t p:/ /schemas.android.com /tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity"
android:background="#ffe9eaed" >
<com.example.drawabletest.CameraPreview
android:id="@+id/cameraPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FFFF" />
<com.example.drawabletest.CustomImageView
android:id="@+id/fbTemplate"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:src="@drawable/template2" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
</FrameLayout>
Also, I'm not sure why the preview itself doesn't work. I've read that on Android 2.x emulators, the test image from the emulated camera is just this plain white by design, so I assumed it's ok. However, my friend tested the app on his phone with Android 2.3 and the preview appeared to be plain black. I guess it's a subject for a separate question, but maybe you'll notice something in the code.
I've spent a few days now to solve these two problems, so any clues would be really helpful. Thank you!

First of all, welcome to the forum.
Please do it as described here: http://forum.xda-developers.com/showthread.php?t=2439748
Post the code within
Code:
tags in the thread. Makes it easier for us. ;)
That way you'd get much more help (maybe from me ;)).

Could you provide at least a working example of camera preview for Android 2.x? I don't believe it can't be done. Does it need some kind of deprecated API to work correctly?

Related

[Q] Item separator in ListView fails! Why?

i have a problem with ListView, i don't view line separator for each item, why ? see where is mouse pointer:
h_t_t_p://tinyurl.com/2vqg52n
and this is source code:
Java Class:
Code:
public class ScienzeInfoNewsActivity extends Activity {
private class Link {
private String title;
private String href;
public Link(String title, String href) {
this.title = title;
this.href = href;
}
public String toString() {
return title;
}
public String getHref() {
return href;
}
}
private FeedReader feedReader;
private ArrayAdapter<Link> adapter;
private ListView list;
public void initialize() {
adapter = new ArrayAdapter<Link>(this, R.layout.textview);
list = (ListView) findViewById(R.id.ListView01);
list.setAdapter(adapter);
}
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initialize();
loadFeeds(adapter);
setAllListener();
}
private void setAllListener() {
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position,
long id) {
String link = adapter.getItem((int) id).getHref();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
startActivity(intent);
}
});
Button exit = (Button) findViewById(R.id.Button02);
exit.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
ScienzeInfoNewsActivity.this.finish();
}
});
Button refresh = (Button) findViewById(R.id.Button01);
refresh.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
loadFeeds(adapter);
}
});
}
private void loadFeeds(ArrayAdapter<Link> adapter) {
if (adapter != null)
adapter.clear();
try {
feedReader = new FeedReader(new URL(
"rss.php"));
String feeds[][] = feedReader.getFeeds();
for (int i = 0; i < feeds.length; i++) {
adapter.add(new Link(feeds[i][0], feeds[i][1]));
}
} catch (Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
R.layout.textview:
Code:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="h_t_t_p://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="16sp" >
</TextView>
I load entry item with this function loadFeeds()
If i select one of the items without a separator, it just one item.
Thanks for any reply.

[Q] ExpandableView inside another ExpandableView won't inflate children

I've been struggling for a couple of weeks to solve this problem. I have two expandable views, one inside another. Whenever i click on the second level expandable view items, it won't inflate its children. All i see when i click is a small scroll bar that appears on the right side on the expandable view item itself. Using a simple layout with a fixed textview results in the same behaviour, meaning that the problem isn't within the ShiftListItem object/s.
Also, getChildView() is never been called.
YearListAdapter:
Code:
public class YearListAdapter extends BaseExpandableListAdapter {
private Context _context;
private SparseArray<SparseArray<ArrayList<Salary>>> _shiftYears;
public YearListAdapter(
SparseArray<SparseArray<ArrayList<Salary>>> shiftYears,
Context context) {
super();
_context = context;
_shiftYears = shiftYears;
}
public Object getChild(int arg0, int arg1) {
return (null == _shiftYears.get(_shiftYears.keyAt(arg0))) ? null
: _shiftYears.get(_shiftYears.keyAt(arg0)).get(
_shiftYears.get(_shiftYears.keyAt(arg0)).keyAt(arg1));
}
public long getChildId(int arg0, int arg1) {
return arg1;
}
public View getChildView(int arg0, int arg1, boolean arg2,
View convertView, ViewGroup arg4) {
MonthsListView monthLevelExpandable = new MonthsListView(_context);
MonthListAdapter adapter = new MonthListAdapter(_context,
_shiftYears.get(_shiftYears.keyAt(arg0)));
monthLevelExpandable.setAdapter(adapter);
adapter.forceReload();
monthLevelExpandable.setGroupIndicator(null);
return monthLevelExpandable;
}
public int getChildrenCount(int arg0) {
if (null == _shiftYears.get(_shiftYears.keyAt(arg0)))
return 0;
return _shiftYears.get(_shiftYears.keyAt(arg0)).size();
}
public Object getGroup(int arg0) {
return (null == _shiftYears) ? null : _shiftYears.get(_shiftYears
.keyAt(arg0));
}
public int getGroupCount() {
return _shiftYears.size();
}
public long getGroupId(int arg0) {
return arg0;
}
public View getGroupView(int arg0, boolean isExpanded, View convertView,
ViewGroup arg3) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) _context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.year_list_view_item, null);
}
TextView title = (TextView) convertView.findViewById(R.id.yearTitle);
title.setText("" + _shiftYears.keyAt(arg0));
return convertView;
}
public boolean hasStableIds() {
return true;
}
public boolean isChildSelectable(int arg0, int arg1) {
return true;
}
public void forceReload() {
notifyDataSetChanged();
}
}
MonthListAdapter:
Code:
public class MonthListAdapter extends BaseExpandableListAdapter {
private Context _context;
private SparseArray<ArrayList<Salary>> _shiftMonths;
public MonthListAdapter(Context context,
SparseArray<ArrayList<Salary>> shiftMonths) {
super();
_context = context;
_shiftMonths = shiftMonths;
}
public Object getChild(int groupPosition, int childPosition) {
return (null == _shiftMonths) ? null : _shiftMonths.get(
_shiftMonths.keyAt(groupPosition)).get(childPosition);
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
ShiftListItem sli;
if (null == convertView) {
sli = (ShiftListItem) View.inflate(_context,
R.layout.shift_list_item, null);
} else {
sli = (ShiftListItem) convertView;
}
sli.setSalary(_shiftMonths.get(_shiftMonths.keyAt(groupPosition)).get(
childPosition));
return sli;
}
public int getChildrenCount(int groupPosition) {
if (null == _shiftMonths
|| null == _shiftMonths.get(_shiftMonths.keyAt(groupPosition)))
return 0;
return _shiftMonths.get(_shiftMonths.keyAt(groupPosition)).size();
}
public Object getGroup(int groupPosition) {
return (null == _shiftMonths) ? null : _shiftMonths.get(_shiftMonths
.keyAt(groupPosition));
}
public int getGroupCount() {
return _shiftMonths.size();
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) _context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.month_list_view_item, null);
}
TextView title = (TextView) convertView.findViewById(R.id.monthTitle);
title.setText("" + _shiftMonths.keyAt(groupPosition));
return convertView;
}
public boolean hasStableIds() {
return true;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public void forceReload() {
notifyDataSetChanged();
}
}
ShiftListItem:
Code:
public class ShiftListItem extends LinearLayout {
private Salary salary;
private TextView itemTimeAndDate;
private TextView itemCashView;
public ShiftListItem(Context context, AttributeSet attrs) {
super(context, attrs);
salary = new Salary();
}
[user=439709]@override[/user]
protected void onFinishInflate() {
super.onFinishInflate();
itemTimeAndDate = (TextView) findViewById(R.id.itemTimeAndDate);
itemCashView = (TextView) findViewById(R.id.itemCashView);
}
public void setSalary(Salary salary) {
this.salary = salary;
Calendar start = salary.getShiftTime().getStart();
Calendar end = salary.getShiftTime().getEnd();
int tHour;
int tMinute;
int tSec;
tSec = salary.getShiftTime().getDifference(
salary.getShiftTime().getStart(),
salary.getShiftTime().getEnd());
tHour = tSec / 3600;
tSec -= tHour * 3600;
tMinute = tSec / 60;
tSec -= tMinute * 60;
itemTimeAndDate.setText("Time: (Start) "
+ returnTwoDigitString(start.get(Calendar.HOUR_OF_DAY)) + ":"
+ returnTwoDigitString(start.get(Calendar.MINUTE)) + " (End)"
+ returnTwoDigitString(end.get(Calendar.HOUR_OF_DAY)) + ":"
+ returnTwoDigitString(end.get(Calendar.MINUTE)) + "\n"
+ (start.get(Calendar.DAY_OF_MONTH)) + "-"
+ (end.get(Calendar.DAY_OF_MONTH)) + "/"
+ (start.get(Calendar.MONTH) + 1) + "-"
+ (end.get(Calendar.MONTH) + 1) + "/"
+ start.get(Calendar.YEAR) + "-" + end.get(Calendar.YEAR));
itemCashView.setText(salary.getCash() + " " + salary.getCurrency()
+ " Total Time Of: " + returnTwoDigitString(tHour) + ":"
+ returnTwoDigitString(tMinute) + ":"
+ returnTwoDigitString(tSec));
}
public Salary getSalary() {
return salary;
}
private String returnTwoDigitString(int time) {
if (time < 10) {
return "0" + time;
}
return "" + time;
}
}
shift_list_item.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<com...ShiftListItem xmlns:android="....."
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/itemTimeAndDate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false" />
<TextView
android:id="@+id/itemCashView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false" />
</com.....ShiftListItem>

[Q] Animation with surfaceview cant capture screenshot

Hello,
I have a project in which an object moves by tapping it on a scrolling background, I can not despite my best efforts to resolve a problem, the screen remains blank after the screenshot
this is my xml
Code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LayoutRoot"
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=".MainActivity" >
</RelativeLayout>
java
Code:
public class MainActivity extends Activity {
BallBounces ball;
File imageFile;
public RelativeLayout CamView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CamView =(RelativeLayout) findViewById(R.id.LayoutRoot);
ball = new BallBounces(this);
setContentView(ball);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.Menu:
//newGame();
case R.id.screenshot:
//showHelp();
TakeScreenshot();
// ScreenshotCapture();
Context context=getApplicationContext();
CharSequence text="screenshot";
int duration=Toast.LENGTH_LONG;
Toast toast=Toast.makeText(context, text, duration);
toast.show();
return true;
case R.id.About:
//showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void TakeScreenshot()
{
Random num = new Random();
int nu=num.nextInt(1000);
CamView.setDrawingCacheEnabled(true);
CamView.buildDrawingCache(true);
Bitmap bmp = Bitmap.createBitmap(CamView.getDrawingCache()); // Here i have null!
CamView.setDrawingCacheEnabled(false); // clear drawing cache
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 70, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
String picId=String.valueOf(nu);
String myfile="Ghost"+picId+".jpeg";
File dir_image = new File(Environment.getExternalStorageDirectory()+File.separator+"ImageTouch");
dir_image.mkdirs();
try {
File tmpFile = new File(dir_image,myfile);
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) > 0)
{
fos.write(buf, 0, len);
}
fis.close();
fos.close();
Toast.makeText(getApplicationContext(),
"Saved",Toast.LENGTH_LONG).show();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
I tried in every way but I can not get out
Someone can give me a hand?
Thanks
The problem is that with a surface view, the getDrawingCache() method always returns null or a black bitmap...
I got it working in my app by creating a new Canvas with the same size as your surface view and then call surfaceView.onDraw(canvas), passing the new one. You can then write it to a file via its bitmap.
And remember, depending on how intense your onDraw method is you may need to do the saving in an Async task.

[Q] nullpointer and wrap_content problems

Hello there
I got 2 problems:
Firstly, if I launch the following code on my device, I'm getting a nullpointer, and I got no idea why. ( I know it's sorta basic stuff)
Secondly, I want toset the screen height and lenght to wrap_content, it's red marked in the code...that is also not working..
Could you maybe help out a noob?
Code:
public class Game extends Activity implements OnClickListener{
Button start_time;
Button sec;
int i = 0;
TextView textview1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
start_time = (Button) findViewById(R.id.start_time);
start_time.setOnClickListener(this);
textview1 = (TextView) findViewById(R.id.textView1);
/*
sec = (Button) findViewById(R.id.sec);
sec.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
long totalTime = SystemClock.elapsedRealtimeNanos()- startTime;
Intent intent = new Intent(Game.this, MainScreen.class);
intent.putExtra("time",totalTime);
startActivity(intent);
}
});
*/
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.game, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onClick(View v) {
Random r = new Random();
int x = r.nextInt([COLOR="Red"]wrap_content[/COLOR]);
int y = r.nextInt([COLOR="Red"]wrap_content[/COLOR]);
long startTime = SystemClock.elapsedRealtime();
i++;
View b = findViewById(R.id.start_time);
b.setX(x);
b.setY(y);
if (i == 1 ) {
b.setX(+9);
b.setY(+5);
}
if (i == 2 ) {
b.setX(x);
b.setY(y);
}
if (i == 3 ) {
b.setX(x);
b.setY(y);
}
else if (i == 4) {
long difference = SystemClock.elapsedRealtime() - startTime;
Intent intent = new Intent(Game.this, MainScreen.class);
intent.putExtra("time",difference);
// Toast.makeText(getApplicationContext(), getIntent().getStringExtra("time"), Toast.LENGTH_LONG).show();
textview1.setText(getIntent().getStringExtra("time"));
finish();
}
}
}
For the wrap_content one, you need to set that property to the view that holds the integer text, you can't set a height and width properties to an integer, only a view or other widgets such as buttons. So for you you should set the properties of the view with ID start_time to wrap_content for width and height - recommend doing this in the layout XML instead of java code.
I'm guessing that if you sort that out your null pointer will disappear.
Additionally in your public onClick(View v) method you should check the ID of the view before doing any function code, this means you can have multiple objects using the same listener.
So this:
Code:
@Override
public void onClick(View v) {
Random r = new Random();
... etc
Should become this:
Code:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_time:
Random r = new Random();
... etc
tahnks @Jonny for your answer, I changed the code, but now, my button isn't placed randomly on each click anymore, and I'm getting the nullpointer again. have a look:
Code:
public class Game extends Activity implements OnClickListener{
Button start_time;
Button sec;
int i = 0;
TextView textview1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
start_time = (Button) findViewById(R.id.start_time);
start_time.setOnClickListener(this);
textview1 = (TextView) findViewById(R.id.textView1);
/*
sec = (Button) findViewById(R.id.sec);
sec.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
long totalTime = SystemClock.elapsedRealtimeNanos()- startTime;
Intent intent = new Intent(Game.this, MainScreen.class);
intent.putExtra("time",totalTime);
startActivity(intent);
}
});
*/
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.game, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onClick(View v) {
Random r = new Random();
int x = r.nextInt(+1);
int y = r.nextInt(+1);
long startTime = SystemClock.elapsedRealtime();
i++;
View b = findViewById(R.id.wrap_content);
b.setX(x);
b.setY(y);
if (i == 1 ) {
b.setX(+9);
b.setY(+5);
}
if (i == 2 ) {
b.setX(x);
b.setY(y);
}
if (i == 3 ) {
b.setX(x);
b.setY(y);
}
else if (i == 4) {
long difference = SystemClock.elapsedRealtime() - startTime;
Intent intent = new Intent(Game.this, MainScreen.class);
intent.putExtra("time",difference);
// Toast.makeText(getApplicationContext(), getIntent().getStringExtra("time"), Toast.LENGTH_LONG).show();
textview1.setText(getIntent().getStringExtra("time"));
finish();
}
}
}
and the xml
Code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
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="ch.asddd.af.Game" >
<Button
android:id="@+id/start_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="139dp"
android:text="Button" />
<Button
android:id="@+id/sec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/start_time"
android:layout_below="@+id/start_time"
android:layout_marginLeft="17dp"
android:layout_marginTop="89dp"
android:text="Button"
android:visibility="gone"/>
<View
android:id="@+id/wrap_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
thank you. I'm really happy, there exists such great help
i have now changed the view start_time to a button...because it actually IS a button (im stupid) but now, when I click on the button, it moves completely out of the screen, and if not, instead of getting the time, the app stopps again with nullpointer. It should stay in the screen, placed randomly on click and after some clicks, I want to recieve the elapsed time. what is this?
code:
Code:
public class Game extends Activity implements OnClickListener{
Button start_time;
Button sec;
int i = 0;
TextView textview1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
start_time = (Button) findViewById(R.id.start_time);
start_time.setOnClickListener(this);
textview1 = (TextView) findViewById(R.id.textView1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.game, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onClick(View v) {
Random r = new Random();
int x = r.nextInt(R.id.wrap_content);
int y = r.nextInt(R.id.wrap_content);
long startTime = SystemClock.elapsedRealtime();
i++;
Button b = (Button) findViewById(R.id.start_time);
b.setX(x);
b.setY(y);
if (i == 1 ) {
b.setX(+9);
b.setY(+5);
}
if (i == 2 ) {
b.setX(x);
b.setY(y);
}
if (i == 3 ) {
b.setX(x);
b.setY(y);
}
else if (i == 4) {
long difference = SystemClock.elapsedRealtime() - startTime;
Intent intent = new Intent(Game.this, MainScreen.class);
intent.putExtra("time",difference);
// Toast.makeText(getApplicationContext(), getIntent().getStringExtra("time"), Toast.LENGTH_LONG).show();
textview1.setText(getIntent().getStringExtra("time"));
finish();
}
}
}
and the xml:
Code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
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="chdfss.dsfwegg.trhhGame" >
<Button
android:id="@+id/start_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="139dp"
android:text="Button" />
<Button
android:id="@+id/sec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/start_time"
android:layout_below="@+id/start_time"
android:layout_marginLeft="17dp"
android:layout_marginTop="89dp"
android:text="Button"
android:visibility="gone"/>
<View
android:id="@+id/wrap_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</View>
</RelativeLayout>
I'm not familiar with the nextInt() function (I can look it upp later when I'm home) but I'm pretty sure you shouldn't be parsing a views ID as one of its conditions - eg you're doing nextInt(R.id.wrap_content), are you sure that's right?

How to draw or erase on a photo loaded onto a Imageview?

As what was stated on the header I want to implement either a "paint" function for user to edit paint/censor unwanted parts of a photo displayed on a imageview before uploading it to a server in the edited format and a redo function if user makes a mistake while editing?
How do I come about doing it, I've read relevant topics on Canvas, or FingerPaint but still puzzled on how to implement it based on my project here? Tried referencing to the links here and here but without success in implementing the codes into my project code due to my lack of programming skills.
Thanks for any help rendered!
Tried integrating the codes below into my code above (image preview after taking a photo with the camera) for user to start editing via painting but still not working? Thanks for any help rendered!
Code:
public class Drawing extends View {
private Paint mPaint, mBitmapPaint;
Intent intent = getIntent();
Bitmap mBitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
private Canvas mCanvas;
private Path mPath;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private int color, size, state;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
private ArrayList<Integer> colors = new ArrayList<Integer>();
private ArrayList<Integer> sizes = new ArrayList<Integer>();
public Drawing(Context c) {
super(c);
}
public Drawing(Context c,int width, int height, int size, int color, int state) {
super(c);
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
// mBitmapPaint = new Paint(Paint.DITHER_FLAG);
// mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
setColor(color);
setSize(size);
setState(state);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
// canvas.drawColor(Color.TRANSPARENT);
// canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
//
// if (state == 0)
// mBitmap.eraseColor(Color.TRANSPARENT);
for (int i = 0; i < paths.size(); i++) {
mPaint.setColor(colors.get(i));
mPaint.setStrokeWidth(sizes.get(i));
canvas.drawPath(paths.get(i), mPaint);
}
mPaint.setColor(color);
mPaint.setStrokeWidth(size);
canvas.drawPath(mPath, mPaint);
}
public void setColor(int color) {
this.color = color;
}
public void setSize(int size) {
this.size = size;
}
public void setState(int state) {
this.state = state;
// if (state == 0)
// mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
// else
// mPaint.setXfermode(null);
}
public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
sizes.remove(sizes.size() - 1);
colors.remove(colors.size() - 1);
invalidate();
}
}
private void touch_start(float x, float y) {
undonePaths.clear();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
colors.add(color);
sizes.add(size);
paths.add(mPath);
mPath = new Path();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}

Categories

Resources