I'm still new to development, and I was wondering if someone can guide me towards the right direction in my situation because I'm not sure where to begin:
Scheme:
After pressing a capture_button to capture an image (capture_button and imagePreview is in same activity), I would like to remove the capture_buttonand have an ACCEPT or DECLINE button. These buttons are supposed to be accept the image and then save, or decline the image and go back to the imagePreview.
Now, I'm not sure if I'm supposed to create another activity when capture_button is pressed,
PhotoActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photo);
mCamera = getCameraInstant();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(id.camera_preview);
preview.addView(mCameraPreview);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
PictureCallback mPicture = new PictureCallback(){
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.e("photo","pictureCallback");
// TODO Auto-generated method stub
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if(pictureFile==null){
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e){
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
private File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "Photo");
if (!mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("Photo", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
return mediaFile;
}
Now, am I supposed to do some kind of Intent after the capture_button click, or after
PictureCallback mPicture = new PictureCallback(){
and then have the onPictureTaken at the other activity? Or is my thinking all wrong?
Please help?
Thank you in advance.
try this it will help you
final LinearLayout accept_deciline = new LinearLayout(getApplicationContext());
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
accept_deciline.setOrientation(LinearLayout.HORIZONTAL);
Button accept = new Button(getApplicationContext());
accept.setText("Accept");
Button decline = new Button(getApplicationContext());
decline.setText("Decline");
accept_deciline.addView(accept);
accept_deciline.addView(decline);
addContentView(accept_deciline, lp);
accept_deciline.setVisibility(View.INVISIBLE);
accept.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// SAVE YOUR IMAGE.
}
});
decline.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
//KEEP THIS LINE IN YOUR PICTURE CALLBACK NOT HERE.
accept_deciline.setVisibility(View.VISIBLE);
IT WILL BE BETTER IF YOU WILL CREATE YOUR ACCEPT DECLINE LAYOUT IN XML FILE AND MAKE IT INVISIBLE WHEN YOUR ON PICTURE TAKEN WILL BE CALLED JUST MAKE IT VISIBLE.
One thing that I have done is to use an alertdialog that pops up after you take a picture. You can set the onclick listeners to perform any actions you need depending on what you want to happen(accept or decline). This would avoid the need to make any changes to your layouts and add buttons and take them away. You could launch the alertdialog by placing the alertdialog.show() method at the end of your onPictureTaken method.
If you do this youll have to have the filepath of the image you just took so you can allow a user to destroy it if they decline it and on some devices it may take the mediaservice a couple of seconds to update the images filepath so if you go to destroy an image it doesnt see you can get a force close. There are a couple ways to do this and I cant remember at the moment but one of them is way faster than the rest.
You wouldnt need an intent unless you plan on launching some other kind of action, activity, service, ect. For instance if you want to pass the filepath of the image to another activity where you can make changes to it, upload it, or what have you, you can add the filepath of the image to an intent like this:
intent.putExtra("imagepath",imagepath);
Related
First, I created a simple program that playes media when you click on a button.
In my Main Activity class I have:
MediaPlayer mySound;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySound = MediaPlayer.create(this, R.raw.sleepnk);
}
Then I created the following:
public void playMusic(View view)
{
mySound.start();
}
Then in my XML file I created a button and added:
android:onClick="playMusic"
Now I am trying to add media to an app but it doesn't have something like:
<Button
android:id="#+id/button"
.
My goal is to add a media file to this "Tap to Start" invisible button in this new app but since there are no buttons in the xml file, I don't know where to attach my playMusic method to the Tap to Start button. I am including instances of Tap to Start button so you can see how it is acting as a button-
There is a strings.xml under values folder that contains:
<?xml version="1.0" encoding="utf-8"?>
<string name="app_name">Panoramik</string>
<string name="instruction_tap_start">Tap to start</string>
Then in the MainActivity.java file we have:
private View.OnClickListener mCameraOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mIsCapturing) {
//clear the flag to prevent the screen of being on
getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (mDMDCapture.finishShooting()) {
mIsStitching = true;
mTextViewInstruction.setVisibility(View.INVISIBLE);
}
mIsCapturing = false;
setInstructionMessage(R.string.instruction_tap_start);
I am also including the code for "setInstructionMessage" method:
private void setInstructionMessage(int msgID)
{
if (mCurrentInstructionMessageID == msgID)
return;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mDisplayMetrics.widthPixels, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_HORIZONTAL);
if (msgID == R.string.instruction_empty || msgID == R.string.instruction_hold_vertically || msgID == R.string.instruction_tap_start
|| msgID == R.string.instruction_focusing) {
params.addRule(RelativeLayout.CENTER_VERTICAL);
} else {
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
}
mTextViewInstruction.setLayoutParams(params);
mTextViewInstruction.setText(msgID);
mCurrentInstructionMessageID = msgID;
}
Can anyone tell me how I can attach my media file sleepnk to the Tap to Start invisible button?
EDIT: I basically want the app to say "Tap to Start" because the app is being created for the visually impaired. So if there is any other suggestion for the app to talk back to the user, feel free to comment
You should let the OS and TalkBack read the "android:contentDescription" attribute by assigning the string "Tap to Start" to whatever it is you want the user to touch. (Remembering to use a string resource so it can be translated/localized.)
I want to make a slideshow of numbers starting from 0 to 9 in pictures. When i click next button , show the picture of 1 and play sound as 'one' and so on.I want previous button to properly work.. like when I click previous button then go to previous pic and play sound which is related to that pic.
public class Numbers extends Activity {
int i = 1;
private ImageView iv;
Button next;
Button previous;
MediaPlayer ourSong;
private int currentImage = 0;
public int currentAudio = 0;
int[] images = { R.drawable.p1, R.drawable.p2, R.drawable.p3,
R.drawable.p4, R.drawable.p5, R.drawable.p6, R.drawable.p7,
R.drawable.p8, R.drawable.p9, R.drawable.p10};
int[] audios = { R.raw.a1, R.raw.a2, R.raw.a3, R.raw.a4, R.raw.a5,
R.raw.a6, R.raw.a7, R.raw.a8, R.raw.a9, R.raw.a10};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nextpre);
iv = (ImageView) findViewById(R.id.ivn);
next = (Button) findViewById(R.id.buttonn);
previous = (Button) findViewById(R.id.buttonp);
// Just set one Click listener for the image
next.setOnClickListener(iButtonChangeImageListener);
previous.setOnClickListener(gButtonChangeImageListener);
}
View.OnClickListener iButtonChangeImageListener = new View.OnClickListener() {
public void onClick(View v) {
try {
// Increase Counter to move to next Image
currentImage++;
currentImage = currentImage % images.length;
iv.setImageResource(images[currentImage]);
ourSong = MediaPlayer.create(Numbers.this,
audios[currentAudio+1]);
ourSong.start();
currentAudio++;
} catch (Exception e) {
}
}
};
View.OnClickListener gButtonChangeImageListener = new View.OnClickListener() {
public void onClick(View v) {
try {
// Decrease Counter to move to previous Image
currentImage--;
currentImage = (currentImage + images.length) % images.length;
iv.setImageResource(images[currentImage]);
MediaPlayer.create(Numbers.this, audios[currentAudio]);
ourSong.start();
currentAudio--;
} catch (Exception e) {
}
}
};
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
ourSong.release();
finish();
}
#Override
protected void onStart() {
super.onStart();
ourSong = MediaPlayer.create(Numbers.this,
audios[0]);
ourSong.start();
}
}
Hmm if you're trying to make a slide show, you might want to look into view pagers they look like this:
View pagers are highly customizable, You can add buttons and images and pretty much almost anything a fragment can hold on each screen. Not sure what your skill level is but ill tell you whats involved in getting this to work.
Create a layout with a view pager in it.
Create a class that extends the FragmentPagerAdapter
Override getItem() method in the adapter (this is where you define your different "screens"
Create a class that extends fragment for each screen you want to show your users.
Doing it this way in order to switch screens u just have to call setCurrentItem to change pages (when user clicks next or prev)
--edit--
Apparently theres also a something called an ImageSwitcher.
They look like this:
This is actually better for your case since you only want images. It looks a lot easier to implement than a view pager. This describes how to implement it: http://www.tutorialspoint.com/android/android_imageswitcher.htm
I have a piece of code where a function opens a popup window to later return an integer based on what happened inside that window. But when I run it, it directly returns the integer without opening any popup window.
How do I tell that function to wait to return until a user has done a certain action?
Here's the code in case you need it:
public int initPopup(String monsterName, String monsterHP){
final int monsterHPInt = Integer.parseInt(monsterHP);
PopupWindow popup;
TextView popupText;
Button closePopupButton;
final SeekBar monsterHPChanger;
LinearLayout popupLayout;
popupText = new TextView(this);
popupText.setText(monsterName);
monsterHPChanger = new SeekBar(this);
monsterHPChanger.setMax(monsterHPInt);
/** Will only use if necessary
* monsterHPChanger.setProgress(monsterHPChanger.getMax());
*/
popupLayout = new LinearLayout(this);
popupLayout.setOrientation(LinearLayout.VERTICAL);
popupLayout.addView(popupText);
popupLayout.addView(monsterHPChanger);
//TODO: Create the layout of the popup and the popup itself
popup = new PopupWindow(popupLayout, LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
popup.setContentView(popupLayout);
//Creating encapsulation class to edit the monsterHP with the value of the SeekBar
final MonsterHP monsterHPObject = new MonsterHP(monsterHPInt, monsterHPChanger.getProgress());
closePopupButton = new Button(this);
closePopupButton.setId(R.id.closePopup);
closePopupButton.setText("Ok");
closePopupButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
monsterHPObject.update(monsterHPChanger.getProgress());
}
});
Log.println(1, "Method", "Returns " + monsterHPObject.getHP());
// TODO: reactivate when debug is done return monsterHPObject.getHP();
//Returning 0 for debug reasons
return 0;
}
I'm looking your code and I dont see the call "popup.show()" anywhere. Also, if you want to wait some time to perform an operation you can use the following code.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// your operations (open popup?)
}
}, **your_delay_time**);
Hope it helps you!!
Use a callback interface that you pass to your method.
When the user performs the action, call the appropriate callback method.
I've gotten my app to download content from a website but the intent asks you to open the link in the browser and downloads it from there. I wish to change that so when i tap the download button, instead of the intent directing to the browser it opens a popup in my app and shows the download progress.
How am I able to achieve this?
I have searched around stackoverflow and have only found ways that don't work for me. Here is my code -
txtLink = (EditText) findViewById(R.id.input_package);
btnOpenLink = (ImageButton) findViewById(R.id.download);
btnOpenLink.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String page = txtLink.getText().toString();
if (!TextUtils.isEmpty(page)) {
Uri uri = Uri.parse(defaultLink + page);
// Success Toast
LayoutInflater inflater = getLayoutInflater();
// Inflate the Layout
View layout = inflater.inflate(R.layout.custom_toast, null);
TextView text = (TextView) layout.findViewById(R.id.textToShow);
// Set the Text to show in TextView
text.setText("Your download should start shortly");
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.FILL_HORIZONTAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
} else {
// Fail Toast
LayoutInflater inflater = getLayoutInflater();
// Inflate the Layout
View layout = inflater.inflate(R.layout.custom_toast, null);
TextView text = (TextView) layout.findViewById(R.id.textToShow);
// Set the Text to show in TextView
text.setText("Please enter a package name");
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.FILL_HORIZONTAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
}
}
});
Could someone explain what is the best way to create a popup download progress?
Because i have an input field where one can enter the second part of the url and it downloads that. Eg- download.com/ but the user enters "download" so when he taps the button it changes to download.com/download and it downloads from that url.
Thanks
You can do something like this..
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private ProgressDialog mProgressDialog;
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("waiting 5 minutes..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
Then write an async task to update progress..
private class DownloadZipFileTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... urls) {
//Copy you logic to calculate progress and call
publishProgress("" + progress);
}
protected void onProgressUpdate(String... progress) {
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String result) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
Write your download logic under the doInBackground method of Asynctask.This should solve your purpose and it wont even block UI tread..
I have a listview in my android app which does two functions with the listview itself.
Fist, I can delete an item from the listview.
Second, I can rename something in the listview.
Anytime any of the above happens,
How do I display a different XML layout if the last item on the listview is deleted?
adapter = new SetRowsCustomAdapter(getActivity(), R.layout.customlist, rowsArray);
dataList = (ListView) mFrame3.findViewById(R.id.lvFiles); //lvfiles from xml layout
dataList.setAdapter(adapter);
dataList.setEmptyView(noFilesDisplayed); //not working
Second, once I rename anything within the listview, how do I update the listview to reflect the changes?
adapter.notifyDataSetChanged(); //not working
I have two choices in my ContextMenu, Delete and Rename.
If Delete is chosen, the following code executes:
if (menuItemIndex == 0) {
if (folder.exists()) {
//File flEachFile = new File(folder.toString() + "/" + currentFileName + ".tp");
flEachFile = new File(folder.toString() + "/" + txt + ".tp");
flEachFile2 = new File(folder.toString() + "/." + txt + ".tp");
if (flEachFile.exists()) {
flEachFile.delete();
}
if (flEachFile2.exists()) {
flEachFile2.delete();
}
adapter.remove(adapter.getItem(info.position)); //updated the list
//adapter.notifyDataSetChanged();
dataList.invalidate();
dataList.setEmptyView(noFilesDisplayed);//should display the noFilesDisplayed layout but it's not.
//getActivity().getActionBar().setSelectedNavigationItem(1);
}
}
This works fine as in the list updates itself as I delete a list. So if I have two lists in the view and I delete one the list updates to show one:
adapter.remove(adapter.getItem(info.position)); //updated the list
But if I delete the last item on the list and I want to display another xml layout as in this line:
dataList.setEmptyView(noFilesDisplayed);//should display the noFilesDisplayed layout but it's not.
It doesn't work.
======================================================
If Rename is chosen the following code executes:
if (menuItemIndex == 1) {
// custom dialog
final Dialog dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.renamefile);
dialog.setTitle("Rename Existing Trip");
currTrip = (TextView) dialog.findViewById(R.id.tvCurrentFileName);
currTrip.setText(txt);
etRT = (EditText) dialog.findViewById(R.id.etRenameTo);
Button btnCancel = (Button) dialog.findViewById(R.id.btnCancel);
Button btnApply = (Button) dialog.findViewById(R.id.btnApply);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
btnApply.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(folder.exists()) {
flEachFile = new File(folder.toString() + "/" + currTrip.getText().toString() + ".tp");
flEachFile2 = new File(folder.toString() + "/." + currTrip.getText().toString() + ".tp");
if (flEachFile.exists()) {
if (etRT.getText().toString().matches("")) {
rTo = (TextView) dialog.findViewById(R.id.tvRenameTo);
rTo.setTextColor(Color.parseColor("#A60000"));
}
else {
File toFile = new File(folder.toString() + "/" + etRT.getText().toString() + ".tp");
flEachFile.renameTo(toFile);
if (flEachFile2.exists()) {
File toFile2 = new File(folder.toString() + "/." + etRT.getText().toString() + ".tp");
flEachFile2.renameTo(toFile2);
}
//adapter.notifyDataSetChanged();
dataList.invalidate();
dialog.dismiss();
//getActivity().getActionBar().setSelectedNavigationItem(1);
}
}
else {
Toast.makeText(getActivity(), "File does not exist", Toast.LENGTH_SHORT).show();
}
}
}
});
// if cancel is clicked, close the custom dialog
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
I can only see the changes if I switch tab and come back to this tab.
It's best to interact with a ListView through its associated adapter, in this case your SetRowCustomAdapter. To remove items you should do adapter.remove(position), which will automatically handle the notifyDataSetChanged() function and internally remove it from whatever data structure it's in. As for renaming something, it depends on how your modeled the data behind the scenes in your adapter. Could you provide some more code for your customer adapter? Are you using an array internally?
UPDATE
Regarding setEmptyView(noFilesDisplayed) not working, is noFilesDisplayed in the same the layout hierarchy where the ListView is? In my experience, which has also been verified by other people, the empty view (in this case noFilesDisplayed) must be in the same layout XML file and, more specifically, must be in the same hierarchy. I personally don't know why it has to be this way, but it seems like that's the only way it works. Here's the example of what I mean...
<ListView
android:id="#+id/list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<View
android:id="#+id/empty_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone" />
Then in code, you can point noFilesDisplayed to the resource ID empty_view. I'm not entirely sure if setting the visibility to gone is necessary, try playing around with that. I hope that answers your question about the empty view.
call adpater.notifyDataSetChanged(); after you have made changes to your ListView, if notifyDataChanged() is still not working, you can set the adapter and pass the new updated data to the adapter constructor in onResume method. So whenever you delete/rename data in your listView, it will be updated automatically. (This second method will work only if you are starting a new activity for deleting or renaming listView items.)
#Override
protected void onResume() {
super.onResume();
SetRowsCustomAdapter adapter = new SetRowsCustomAdapter(getActivity(), R.layout.customlist, rowsArray);
dataList.setAdapter(adapter);
}