I've been playing around with this code and I'm obviously trying to make a soundboard that will save ringtones on longclicks and etc.
Though, this is the basic code for one button. I've been duplicating the same code on top of each other, trying to make arrays, just everything.. I can't get this code to work the way I want it to.
When they are multiple buttons and more codes.
I can get the sounds to all play for the buttons. I can get the menu to pop up for each button. Tho, the first button is always the one that gets saved, and the rest just fall off the map.
I assume that my data flow on the following code is not getting cut off and being picked up by the other sound buttons. Either way, it doesn't work. Please help me.
public class Soundboard extends Activity {
private SoundManager mSoundManager;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSoundManager = new SoundManager();
mSoundManager.initSounds(getBaseContext());
mSoundManager.addSound(1, R.raw.sound1);
Button SB = (Button)findViewById(R.id.sound1);
SB.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mSoundManager.playSound(1);
}
});
Button btn = (Button) findViewById(R.id.sound1);
registerForContextMenu(btn);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Save as...");
menu.add(0, v.getId(), 0, "Ringtone");
menu.add(0, v.getId(), 0, "Notification");
}
#Override
public boolean onContextItemSelected(MenuItem item) {
if(item.getTitle()=="Ringtone"){function1(item.getItemId());}
else if(item.getTitle()=="Notification"){function2(item.getItemId());}
else {return false;}
return true;
}
public void function1(int id){
if (savering(R.raw.sound1)) {
// Code if successful
Toast.makeText(this, "Saved as Ringtone", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
}
public void function2(int id){
if (savenot(R.raw.sound1)) {
// Code if successful
Toast.makeText(this, "Saved as Notification", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
}
//Save into Ring tone Folder
public boolean savering(int ressound){
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=50;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path="/sdcard/media/audio/ringtones/";
String filename="ohhh"+".ogg";
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(path+filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)
));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "Ohhh Ringtone");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
values.put(MediaStore.Audio.Media.ARTIST, "weee");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
this.getContentResolver().insert(
MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
return true;
}
//Save in Notification Folder
public boolean savenot(int ressound){
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path="/sdcard/media/audio/notifications/";
String filename="ohhh"+".ogg";
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(path+filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)
));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "Ohhh Notification");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
values.put(MediaStore.Audio.Media.ARTIST, "weee");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
this.getContentResolver().insert(
MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
return true;
}
}
I'm just learning Android programming myself, but it seems like this is why you're always saving the first sound:
savering(R.raw.sound1)
and
savenot(R.raw.sound1)
Both of those are explicitly saving the first sound. Unless you've written a separate function1 and function2 for each button. But there's got to be a better way to manage saving than that.
Related
Here is my code, it says no such file or directory. Can anyone help me with this? I want to save image from URL into storage.
if (imageLoaded) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
if (imageBitmap == null) {
Toast.makeText(getActivity(), "Looks like images didn't load.", Toast.LENGTH_SHORT).show();
} else {
imageBitmap.compress(Bitmap.CompressFormat.JPEG,100,bytes);
File directory = null;
if (Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED)) {
directory = new File(Environment.getExternalStorageDirectory(),"COC");
if (!directory.isDirectory()) {
directory.mkdirs();
}
}
File f = new File(directory,ImageName+".jpg");
try {
f.createNewFile();
FileOutputStream fo = null;
fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
Toast.makeText(getActivity(),"saved",Toast.LENGTH_SHORT).show();
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
For this sort of situation choosing a network library like Retrofit would be good . Otherwise you have to create a HTTP url connection , download the image as bitmap and then save it to file . All work needs to be done off the main thread . So lots of thread pooling is needed . So lets solve the problem with retrofit
first add retrofit as dependency to your app level gradle file
compile 'com.squareup.retrofit:retrofit:2.0.0'
compile 'com.squareup.retrofit:converter-gson:2.0.0'
then create a demo layout file with a image view in it , in this image view we are going to show the downloaded image
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageViewId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxWidth="1420px"
android:maxHeight="700px"
android:scaleType="fitCenter" />
</RelativeLayout>
after that lets create a network API interface like this
public interface RetrofitImageAPI {
#GET("retrofit/images/uploads/android.jpg")
Call<ResponseBody> getImageDetails();
}
This is a good practice using retrofit as sigleton pattern (see this)
But for demonstration purpose I am showing everything in a single activity
public class MainActivity extends AppCompatActivity {
String url = "http://www.delaroystudios.com/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Button ButtonArray= (Button) findViewById(R.id.RetrofitImage);
ButtonArray.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View VisibleImage = findViewById(R.id.RetrofitImage);
VisibleImage.setVisibility(View.GONE);
getRetrofitImage();
}
});
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
void getRetrofitImage() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitImageAPI service = retrofit.create(RetrofitImageAPI.class);
Call<ResponseBody> call = service.getImageDetails();
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
try {
Log.d("onResponse", "Response came from server");
boolean FileDownloaded = DownloadImage(response.body());
Log.d("onResponse", "Image is downloaded and saved ? " + FileDownloaded);
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
private boolean DownloadImage(ResponseBody body) {
try {
Log.d("DownloadImage", "Reading and writing file");
InputStream in = null;
FileOutputStream out = null;
try {
in = body.byteStream();
out = new FileOutputStream(getExternalFilesDir(null) + File.separator + "Android.jpg");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
}
catch (IOException e) {
Log.d("DownloadImage",e.toString());
return false;
}
finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
int width, height;
ImageView image = (ImageView) findViewById(R.id.imageViewId);
Bitmap bMap = BitmapFactory.decodeFile(getExternalFilesDir(null) + File.separator + "Android.jpg");
width = 2*bMap.getWidth();
height = 3*bMap.getHeight();
Bitmap bMap2 = Bitmap.createScaledBitmap(bMap, width, height, false);
image.setImageBitmap(bMap2);
return true;
} catch (IOException e) {
Log.d("DownloadImage",e.toString());
return false;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item)
}
}
if it helps please don't forget to like and click the accept button . it means a lot to the person who answers .
have a good day
using Picasso:
Picasso.with(mContext)
.load(ImageUrl)
.into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
try {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/yourDirectory");
if (!myDir.exists()) {
myDir.mkdirs();
}
String name = new Date().toString() + ".jpg";
myDir = new File(myDir, name);
FileOutputStream out = new FileOutputStream(myDir);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch(Exception e){
// some action
}
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
}
);
Very simple code to save bitmap to file of your choice of directory:
final File myImageFile = new File(FILE_DIRECTORY, IMAGE_NAME); // Create image file
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myImageFile);
IMAGE_BITMAP.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.i("image", "image saved to >>>" + Uri.parse("file://" + myImageFile.toString()).toString());
If you want to use volley then you can do following:
ImageRequest ir = new ImageRequest(url,
new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap response) {
final File myImageFile = new File(fileDirectory, imageName); // Create image file
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myImageFile);
response.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.i("image", "image saved to >>>" + Uri.parse("file://" + myImageFile.toString()).toString()); downloadedFileUris.add(FileProvider.getUriForFile(ViewReportsActivity.this.getBaseContext(), BuildConfig.APPLICATION_ID + ".provider", myImageFile));
}
}, 0, 0, null, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
You complain that a file can not be created. But you try to write a file in a directory that does not exist. After mkdirs() you do not check if the directory is indeed created. Well it is not.
From Android 6 you should at runtime ask the user to confirm the permissions you requested in manifest.
Google for runtime permissions.
I am beginner android developer and trying to implement one function for overflow menu.
My menu code is like this
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if(id==android.R.id.home) {
finish();
}else if (id == R.id.image) {
takeScreenshot(); // getting error like The method takeScreenshot(Context, View) in the type QuoteViewActivity is not applicable for the arguments ()
return true;
}
and
function code is like
public static void takeScreenshot(Context context, View view) {
String path = Environment.getExternalStorageDirectory().toString()
+ "/" + "test.png";
View v = view.findViewById(android.R.id.content).getRootView();
v.setDrawingCacheEnabled(true);
v.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
OutputStream out = null;
File imageFile = new File(path);
try {
out = new FileOutputStream(imageFile);
// choose JPEG format
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
} catch (FileNotFoundException e) {
// manage exception
} catch (IOException e) {
// manage exception
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception exc) {
}
}
// onPauseVideo();
Intent share = new Intent(Intent.ACTION_SEND);
share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
share.setType("image/png");
((Activity) context).startActivityForResult(
Intent.createChooser(share, "Share Drawing"), 111);
}
How can I call it on menu click ?
Sorry for stupid question for developer
Thanks
private void takeScreenshot() {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
// create bitmap screen capture
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
openScreenshot(imageFile);
} catch (Throwable e) {
// Several error may come out with file handling or OOM
e.printStackTrace();
}
}
don't forget this
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
The way you handle the click on a Menu Item is like this:
First, setup your Options Menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater mnuInflater = getSupportMenuInflater();
mnuInflater.inflate(R.menu.your_menu_xml, menu);
return true;
}
Handle the clicks here:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings:
// EITHER CALL THE METHOD HERE OR DO THE FUNCTION DIRECTLY
yourMethod();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
And do the function in the yourMethod() here:
private void yourMethod() {
// TODO Auto-generated method stub
}
From what I see, it should be the following:
takeScreenshot(this, findViewById(R.id.your_root_layout));
However, you can call takeScreenshot(); if takeScreenshot is not static and inside your activity.
So I'm implementing audio Playlist app that imports audios from Parse.com, and when I retrieve them by streaming them directly from their URls, it took maybe one minute to play after clicking play button.
So I don't want to use streaming from URL methods to play my audio from server because it makes it so slow. Instead I want to download list of audios from server (Parse.com) at once and then playing them by retrieving from sdcard.
I have the class that downloads single audio from single URL .. I want to edit the code to make it downloads more than one audio at once.
here is the class I have to download audio from URL.
class DownloadMusicfromInternet extends AsyncTask<String, String, String> {
private Context mContext;
private MediaPlayer mPlayer;
public DownloadMusicfromInternet(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
// Download Music File from Internet
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// Get Music file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 10 * 1024);
// Output stream to write file in SD card
OutputStream output = new
Also if you could help me in how to set a name for the audios, I don't want to write static name because I'm downloading more than one audio at a time .
FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/"+"how to put unique name for each audio here ?"+".mp3");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// Write data to file
output.write(data, 0, count);
}
// Flush output
output.flush();
// Close streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
// While Downloading Music File
// Once Music File is downloaded
#Override
protected void onPostExecute(String file_url) {
// Play the music
playMusic();
}
// Play Music
protected void playMusic() {
// Read Mp3 file present under SD card
Uri myUri1 = Uri.parse("file:///sdcard/"+"the same unique name that was set previously ! "+".mp3");
mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mPlayer.setDataSource(mContext.getApplicationContext(), myUri1);
mPlayer.prepare();
// Start playing the Music file
mPlayer.start();
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
// Once Music is completed playing, enable the button
// btnPlayMusic.setEnabled(true);
Toast.makeText(mContext.getApplicationContext(), "Music completed playing", Toast.LENGTH_LONG).show();
}
});
} catch (IllegalArgumentException e) {
Toast.makeText(mContext.getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
} catch (SecurityException e) {
Toast.makeText(mContext.getApplicationContext(), "URI cannot be accessed, permissed needed", Toast.LENGTH_LONG).show();
} catch (IllegalStateException e) {
Toast.makeText(mContext.getApplicationContext(), "Media Player is not in correct state", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(mContext.getApplicationContext(), "IO Error occured", Toast.LENGTH_LONG).show();
}
}
}
and this is my adapter, and here is where my problem occurs and crashes my app. I don't know how to call ( DownloadMusicfromInternet ) more than once from the following adapter .
public class mAdapter extends ParseQueryAdapter<ParseObject> {
public mAdapter (Context context) {
super(context, new ParseQueryAdapter.QueryFactory<ParseObject>() {
public ParseQuery create() {
ParseQuery query = new ParseQuery("MusicPlaylist");
return query;
}
});
}
#Override
public View getItemView(final ParseObject object, View v, ViewGroup parent) {
if (v == null) {
v = View.inflate(getContext(), R.layout.list_music, null);
}
super.getItemView(object, v, parent);
//Audio retrieving
final ImageButton btn = (ImageButton) v.findViewById(R.id.play_btn);
final ParseFile fileObject = object.getParseFile("music");
**// here I put a loop because I want it to download a list of audios at once and I think here is the problem**
if (fileObject != null) {
for (int i = 10; i >= j; j++) {
new DownloadMusicfromInternet().execute(fileObject.getUrl());
}
fileObject.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] bytes, com.parse.ParseException e) {
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
}//end on click
}//end listener
);
}//end done
});//end get data
}//end if
return v;
}//end getItem View
}//end mAdapter
Any help would be appreciated ..
With a lot of help (on here) I've managed to nearly get my app up and running but I've got a problem. I'm basically a beginner in Java so this is a little deep for me, but I would still like some help. Basically the app displays a list of tones and lets you play them, if you touch and hold it inflates a context menu with an option to copy that selected tone to SD card.
The issue I know lies on the fourth-to-last line: boolean saved = saveas(sound.getSoundResourceId(),"filename"); because the variablesaved is not used.
I'm not too sure how to fix this,or what i should put in place of saved, just wondering if anyone on here has a clue?
Here's the full code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerForContextMenu(getListView());
this.getListView().setSelector(R.drawable.selector);
//create a simple list
mSounds = new ArrayList<Sound>();
Sound s = new Sound();
s.setDescription("Affirmative");
s.setSoundResourceId(R.raw.affirmative);
mSounds.add(s);
s = new Sound();
s.setDescription("Anjels");
s.setSoundResourceId(R.raw.anjels);
mSounds.add(s);
s = new Sound();
s.setDescription("Aggro");
s.setSoundResourceId(R.raw.aggro);
mSounds.add(s);
mSounds.add(s);
mAdapter = new SoundAdapter(this, R.layout.list_row, mSounds);
setListAdapter(mAdapter);
}
#Override
public void onListItemClick(ListView parent, View v, int position, long id){
Sound s = (Sound) mSounds.get(position);
MediaPlayer mp = MediaPlayer.create(this, s.getSoundResourceId());
mp.start();
}#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
public boolean saveas(int ressound, String fName){
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path="notifications/halon/";
String filename=fName+".ogg";
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String completePath = baseDir + File.separator + "music" + File.separator + "halon" + File.separator + filename;
boolean exists = (new File(completePath)).exists();
if (!exists){new File(completePath).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(completePath);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "exampletitle");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
return true;
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
Sound sound = (Sound) getListAdapter().getItem(info.position);
int length = mSounds.size(); // get the length of mSounds object
String[] names = new String[length]; // creates a fixed array with strings
for(int i = 0; i < length; i++) {
// add sound name to string array
names[i] = mSounds.get(i).getDescription(); // returns the string name
}
switch(item.getItemId()) {
case R.id.copytosd:
Toast.makeText(this, "Applying " + getResources().getString(R.string.copy) +
" for " + names[(int)info.id],
Toast.LENGTH_SHORT).show();
boolean saved = saveas(sound.getSoundResourceId(),"filename");
return true;
default:
return super.onContextItemSelected(item);
}
}}
If you are not going to use saved, delete the boolean saved = from that statement and just have saveas(sound.getSoundResourceId(),"filename");.
What I have here real simple activity with two buttons. When you press each of them it plays a sound.
When i press and hold the first button it brings up a context menu asking the user if they want to save the sound as a ringtone or notification. This works perfectly on the first button.
The second button's sound plays when pressed. When long pressed it brings up the context menu....BUT it saves the first sound file as ringtone/notification NOT the second...
Would someone be able to shed some insight on why the second context menu isn't working properly?
package com.my.app;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;import android.view.ContextMenu.ContextMenuInfo;
import android.widget.Button;
import android.widget.Toast;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
public class One extends Activity implements OnClickListener{
private SoundManager mSoundManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.one);
mSoundManager = new SoundManager();
mSoundManager.initSounds(getBaseContext());
mSoundManager.addSound(1, R.raw.blah);
mSoundManager.addSound(2, R.raw.rofl);
//BUTTONS PLAY SOUND WHEN PRESSED
View SoundButton1 = findViewById(R.id.Sound1);
SoundButton1.setOnClickListener(this);
View SoundButton2 = findViewById(R.id.Sound2);
SoundButton2.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.Sound1:
mSoundManager.playSound(1);
break;
case R.id.Sound2:
mSoundManager.playSound(2);
break;
}
//WHEN LONG PRESSED BUTTONS BRING UP CONTEXT MENU FOR SAVE AS RINGTONE OR NOTIFICATION
Button SoundButton11 = (Button) findViewById(R.id.Sound1);
registerForContextMenu(SoundButton11);
Button SoundButton22 = (Button) findViewById(R.id.Sound2);
registerForContextMenu(SoundButton22);
}
//CONTEXT MENU FOR BUTTON 1
#Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Save as...");
menu.add(0, v.getId(), 0, "Ringtone");
menu.add(0, v.getId(), 0, "Notification");
}
#Override
public boolean onContextItemSelected(MenuItem item) {
if(item.getTitle()=="Ringtone"){function1(item.getItemId());}
else if(item.getTitle()=="Notification"){function2(item.getItemId());}
else {return false;}
return true;
}
public void function1(int id){
if (savering(R.raw.blah)){
// Code if successful
Toast.makeText(this, "Saved as Ringtone", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
}
public void function2(int id){
if (savenot(R.raw.blah)){
// Code if successful
Toast.makeText(this, "Saved as Notification", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
//CONTEXT MENU FOR BUTTON 2
}
public void onCreateContextMenu1(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Save as...");
menu.add(0, v.getId(), 0, "Ringtone");
menu.add(0, v.getId(), 0, "Notification");
}
public boolean onContextItemSelected1(MenuItem item) {
if(item.getTitle()=="Ringtone"){function11(item.getItemId());}
else if(item.getTitle()=="Notification"){function21(item.getItemId());}
else {return false;}
return true;
}
public void function11(int id){
if (savering(R.raw.rofl)){
// Code if successful
Toast.makeText(this, "Saved as Ringtone", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
}
public void function21(int id){
if (savenot(R.raw.rofl)){
// Code if successful
Toast.makeText(this, "Saved as Notification", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
}
public boolean savering(int ressound){
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path="/sdcard/media/audio/ringtones/";
String filename="HahaSound"+".ogg";
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(path+filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "HahaSound");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
return true;
}
public boolean savenot(int ressound){
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path="/sdcard/media/audio/notifications/";
String filename="HahaSound"+".ogg";
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(path+filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "HahaSoundSound");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
return true;
}
}
UPDATED SINCE STOLE'S RESPONSE-
//BUTTON 1
View SoundButton1 = findViewById(R.id.Sound1);
SoundButton1.setOnClickListener(this);
View SoundButton2 = findViewById(R.id.Sound2);
SoundButton2.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.Sound1:
mSoundManager.playSound(1);
break;
case R.id.Sound2:
mSoundManager.playSound(2);
break;
}
Button SoundButton11 = (Button) findViewById(R.id.Sound1);
registerForContextMenu(SoundButton11);
Button SoundButton22 = (Button) findViewById(R.id.Sound2);
registerForContextMenu(SoundButton22);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Save as...");
menu.add(0, MENU_RINGTONE, 0, "Ringtone");
menu.add(0, MENU_NOTIFICATION, 0, "Notification");
}
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
long SoundButton11 = info.id;
switch (item.getItemId()) {
case MENU_RINGTONE:
if (savering(R.raw.schwing)){
// Code if successful
Toast.makeText(this, "Saved as Ringtone", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
break;
case MENU_NOTIFICATION:
if (savenot(R.raw.schwing)){
// Code if successful
Toast.makeText(this, "Saved as Notification", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
break;
}
return false;
}
This is what 've got since reading your last response. I'm just trying to get it working on the first button before i try moving onto the next. But with your code i'm getting a warning under SoundButton11 "The local variable SoundButton11 is never read"
I'm confused because I have...
Button SoundButton11 = (Button) findViewById(R.id.Sound1);
registerForContextMenu(SoundButton11);
I also tried Sound1 and that did not work either. Any suggestions?
2 Things about your code....
1) There's no function called onCreateContextMenu1 so you're not overriding it...So the first onCreateContextMenu is called.
2)
menu.add(0, v.getId(), 0, "Ringtone");
menu.add(0, v.getId(), 0, "Notification");
You're assigning both menu item (Context) the same id...they ideally have to be different. how else would you identify them. I'm suprised its actually working for you, using titles.
here's what you should be doing...
final int MENU_RINGTONE = 0;
final int MENU_NOTIFICATION = 1;
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, MENU_RINGTONE, 0, "Ringtone");
menu.add(0, MENU_NOTIFICATION, 0, "Notification");
}
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
long buttonId = info.id;
switch (item.getItemId()) {
case MENU_RINGTONE:
function1(buttonId);
break;
case MENU_NOTIFICATION:
function2(buttonId);
break;
}
}
you don't need the additional function12,funtion11,function21,function22...you can generalize them...but i leave that upto you.
Check the comments, i left below...
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
long SoundButton11 = info.id; //THIS IS THE UNUSED VARIABLE!
switch (item.getItemId()) {
case MENU_RINGTONE:
if (savering(R.raw.schwing)){ //this should change based on what button was pressed...
// Code if successful
Toast.makeText(this, "Saved as Ringtone", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
break;
case MENU_NOTIFICATION:
if (savenot(R.raw.schwing)){ //this should change based on what button was pressed...
// Code if successful
Toast.makeText(this, "Saved as Notification", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
break;
}
return false;
}
I suppose this is something on the lines that you want...before you do this make sure SoundButton1(& 2) are Instance Variables so they can be accessible in all the functions of your Activity.
//UNTESTED CODE!
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
long SoundButton11 = info.id; //THIS IS THE UNUSED VARIABLE!
int resId = (SoundButton11 == SoundButton1.getId() )? R.raw.schwing : R.raw.rolf;
switch (item.getItemId()) {
case MENU_RINGTONE:
if (savering(resId)){ //use resId instead...
// Code if successful
Toast.makeText(this, "Saved as Ringtone", Toast.LENGTH_SHORT).show();
}
else
.....