Memory leak error while running in emulator - android

i am trying to build small soundboard. I am getting memory leak error and app is crashing. Could anyone tell me if my code has some problems or inefficient. I have 10 activities similar like Activity1. Is there any way i can make code more efficient and fast. I am not sure which part of the code is causing memory leak error
Sound.java
public class Sound
implements OnClickListener,OnCreateContextMenuListener, OnMenuItemClickListener{
static final private int MENU_RINGTONE = Menu.FIRST;
static final private int MENU_NOTIFICATION = MENU_RINGTONE + 1;
static final private int MENU_MUSIC = MENU_NOTIFICATION + 1;
static final private int MENU_SET = MENU_MUSIC + 1;
private Activity mParent;
private int mResourceId;
private String mName;
private int mButtonID;
private static Player mPlayer;
public static Player getPlayer() { return mPlayer; }
public static void setPlayer(Player value) {
mPlayer = value;
}
private static boolean mDoSet;
public static boolean getmDoSet() { return mDoSet; }
public static void setmDoSet(boolean value) { mDoSet = value; }
enum Action {Ringtone, Notification, Music};
private boolean doSet;
private Action mAction;
Sound(Activity Parent, int RawResId, int ButtonID, String Name){
mParent = Parent;
mResourceId = RawResId;
mName = Name;
mButtonID = ButtonID;
}
public void Initialize() {
mParent.findViewById(mButtonID).setOnClickListener(this);
mParent.findViewById(mButtonID).setOnCreateContextMenuListener(this);
}
#Override
public void onClick(View v) {
if (mPlayer != null){
mPlayer.play(mParent.getBaseContext(), mResourceId);
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
mParent.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Context Menu");
menu.add(0, MENU_RINGTONE, 0, R.string.SaveRingtone).setOnMenuItemClickListener(this);
menu.add(0, MENU_NOTIFICATION, 0, R.string.SaveNotification).setOnMenuItemClickListener(this);
menu.add(0, MENU_MUSIC, 0, R.string.SaveMusic).setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId())
{
case MENU_RINGTONE:
mAction = Action.Ringtone;
break;
case MENU_NOTIFICATION:
mAction = Action.Notification;
break;
case MENU_MUSIC:
mAction = Action.Music;
break;
}
String name = mName.toLowerCase().replace(' ', '_');
return SaveSound(mParent,name, mName, mResourceId);
}
public boolean SaveSound(Activity Parent, String filename, String Title, int ressound) {
byte[] buffer = null;
InputStream fIn = Parent.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 path1 = android.os.Environment.getExternalStorageDirectory().getPath() + "/media/audio/ringtones/";
String path2 = android.os.Environment.getExternalStorageDirectory().getPath() + "/media/audio/notifications/";
boolean saved = false;
switch (mAction){
case Ringtone:
saved = save(Parent, filename, Title, buffer,path1);
case Notification:
saved = save(Parent, filename, Title, buffer, path2);
case Music:
};
if (saved) {
return true;
} else {
return false;
}
}
public boolean save(Activity Parent, String filename, String Title,
byte[] buffer, String path) {
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;
}
Parent.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, Title);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
values.put(MediaStore.Audio.Media.ARTIST, " ");
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, true);
//Insert it into the database
Uri uri = MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath());
Uri newUri = Parent.getContentResolver().insert(uri, values);
// set the ringtone
if (doSet == true && mAction == Action.Ringtone
|| mAction == Action.Notification) {
int type = RingtoneManager.TYPE_RINGTONE;
switch (mAction) {
case Ringtone:
type = RingtoneManager.TYPE_RINGTONE;
break;
case Notification:
type = RingtoneManager.TYPE_NOTIFICATION;
}
RingtoneManager.setActualDefaultRingtoneUri(mParent, type, newUri);
}
return true;
}
}
Player.java
public class Player {
private MediaPlayer mp;
public Player(){
mp = new MediaPlayer();
}
public void play(Context c, int r) {
if (mp==null)
return;
if (mp.isPlaying()){
mp.stop();
mp.release();
}else{
mp = MediaPlayer.create(c, r);
mp.start();
}
}
public void stop() {
if (mp==null)
return;
if (mp.isPlaying()){
mp.stop();
mp.release();
}
}
}
Activity1.java
public class Activity1
extends Activity {
private Player p;
Sound Sounds[] = {
new Sound(this, R.raw.baboon, R.id.Animal1, "")
, new Sound(this, R.raw.baligator, R.id.Animal2, "")
, new Sound(this, R.raw.bat, R.id.Animal3, "")
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animals);
p = new Player();
Sound.setPlayer(p);
for (int i = 0; i < Sounds.length; i++) {
Sounds[i].Initialize();
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public void onBackPressed() {
super.onBackPressed();
p.stop();
}
#Override
protected void onPause()
{
super.onPause();
p.stop();
}
}

In your Sound class you are holding a reference to the Activity in mParent and you never let the Activity go by setting it to null and so the Activity can never be garbage collected.
Honestly it looks like you've tried to extract out all of the Activity code into a different class to make a type of 'template' but didn't get the Android lifecycle implications.

Related

How to view and change saved data inside a listview item?

I am working on an app where the user creates an form in the MainActivity. By clicking on the add button a listview appears (QuestionActivity). In this activity some questions appear. By clicking on, let's say question 1 (Question1 activity), an edittext appears where users can set the name for this form which appears in the MainActivity, also in a listview.
The one thing I am struggling with is the fact that when I open an already saved form, I arrive at the questionlist in QuestionActivity. But when I click on Question 1, the data I already saved here is gone. So I want the users to be able to view and change the data they already saved. But I am not sure how to do this.
I should probably be using an onResume method in the QuestionActivity but I hope someone can help me to do this in a proper way.
Here are my codes:
public class MainActivity extends AppCompatActivity {
private ListView mListViewNotes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListViewNotes = findViewById(R.id.main_listview_notes);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_main_new_note:
Intent newActivity = new Intent(this, QuestionsActivity.class);
startActivity(newActivity);
break;
}
return true;
}
#Override
protected void onResume() {
super.onResume();
mListViewNotes.setAdapter(null);
ArrayList<Note> notes = Utilities.getAllSavedNotes(this);
if (notes ==null || notes.size() == 0) {
Toast.makeText(this, "no saved notes", Toast.LENGTH_SHORT).show();
return;
}else {
NoteAdapter na = new NoteAdapter(this, R.layout.item_note, notes);
mListViewNotes.setAdapter(na);
mListViewNotes.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String fileName = ((Note)mListViewNotes.getItemAtPosition(position)).getDateTime()
+ Utilities.FILE_EXTENSION;
Intent viewNoteIntent = new Intent(getApplicationContext(),QuestionsActivity.class);
viewNoteIntent.putExtra("NOTE_FILE", fileName);
startActivity(viewNoteIntent);
}
});
}
}
}
public class QuestionsActivity extends AppCompatActivity {
ListView lv;
String[] charactersDC = {"Question 1", "Question 2", "Question 3", "Question 4", "Question 5"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_questions);
lv = (ListView) findViewById(R.id.idListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, charactersDC);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if(position == 0)
{
String stringFromQuestion1Result = ((Note)lv.getItemAtPosition(position)).getDateTime()
+ Utilities.FILE_EXTENSION;
Intent myIntent = new Intent(QuestionsActivity.this, Question1.class);
myIntent.putExtra("SAVED_FILE", stringFromQuestion1Result);
startActivityForResult(myIntent,0);
}
if(position == 1)
{
Intent myIntent = new Intent(QuestionsActivity.this, Question2.class);
startActivityForResult(myIntent, 0);
}
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == request_Code) {
if (resultCode == RESULT_OK) {
String stringFromQuestion1Result = data.getData().toString();
}
}
}
}
public class Question1 extends AppCompatActivity {
private EditText mEtTitle;
private String mNoteFileName;
private Note mLoadedNote;
private String mShowSavedData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question1);
mEtTitle = (EditText) findViewById(R.id.note_et_title);
mNoteFileName = getIntent().getStringExtra("NOTE_FILE");
if(mNoteFileName !=null && !mNoteFileName.isEmpty()) {
mLoadedNote = Utilities.getNoteByName(this, mNoteFileName);
if(mLoadedNote !=null) {
mEtTitle.setText(mLoadedNote.getTitle());
}
}
mShowSavedData = getIntent().getStringExtra("SAVED_FILE");
if(mShowSavedData !=null && !mShowSavedData.isEmpty()) {
mLoadedNote = Utilities.getNoteByName(this, mShowSavedData);
if (mLoadedNote !=null) {
mEtTitle.setText(mLoadedNote.getTitle());
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_note_new, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_note_save:
saveNote();
break;
}
return true;
}
private void saveNote() {
Note note;
if(mLoadedNote ==null) {
note = new Note(System.currentTimeMillis(), mEtTitle.getText().toString());
}else {
note = new Note(mLoadedNote.getDateTime(), mEtTitle.getText().toString());
}
if (Utilities.saveNote(this, note)){
Toast.makeText(this, "saved", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "not enough space", Toast.LENGTH_SHORT).show();
}
setResult (Activity.RESULT_OK, mEtTitle.getText().toString());
finish();
}
}
public class Utilities {
public static final String FILE_EXTENSION = ".bin";
public static boolean saveNote(Context context, Note note) {
// DELETED -> String fileName = String.valueOf(note.getDateTime()) + FILE_EXTENSION;
String stringFromQuestion1Result = String.valueOf(note.getDateTime()) + FILE_EXTENSION;
FileOutputStream fos;
ObjectOutputStream oos;
try {
fos = context.openFileOutput(stringFromQuestion1Result, context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(note);
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return false; //tell user something went wrong
}
return true;
}
public static ArrayList<Note> getAllSavedNotes(Context context){
ArrayList<Note> notes = new ArrayList<>();
File filesDir = context.getFilesDir();
ArrayList<String> noteFiles = new ArrayList<>();
for(String file : filesDir.list()) {
if(file.endsWith(FILE_EXTENSION)) {
noteFiles.add(file);
}
}
FileInputStream fis;
ObjectInputStream ois;
for(int i = 0; i < noteFiles.size(); i++) {
try{
fis = context.openFileInput(noteFiles.get(i));
ois = new ObjectInputStream(fis);
notes.add((Note) ois.readObject());
fis.close();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
return notes;
}
public static Note getNoteByName(Context context, String fileName) {
File file = new File(context.getFilesDir(), fileName);
Note note;
if(file.exists()) {
FileInputStream fis;
ObjectInputStream ois;
try{
fis = context.openFileInput(fileName);
ois = new ObjectInputStream(fis);
note = (Note) ois.readObject();
fis.close();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
return note;
}
return null;
}
}
Capture the result value of the startActivityForResult for the Question activity. Ie., add the onActivityResult to your QuestionActivity, as described here:
Android: how to make an activity return results to the activity which calls it?
In your Question1 activity, before you call finish(), set the result value:
setResult(Activity.RESULT_OK, mEtTitle.getText().toString());
finish();
In your QuestionActivity, add the method
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == request_Code) {
if (resultCode == RESULT_OK) {
String stringFromQuestion1Result = data.getData().toString();
}
}
}
Store the result in your QuestionActivity and pass it back using the activity Intent. Similar to how you passed the "NOTE_FILE" data to your QuestionActivity you need to pass the data you want to show up in each Question1 activity to it and load the values if provided.
Intent myIntent = new Intent(QuestionsActivity.this, Question1.class);
myIntent.putExtra("Question1String", stringFromQuestion1Result);
startActivityForResult(myIntent, 0);

How to play online radio streaming url in Android. How to play .pls radio streaming url in android

I created a XML file in my server. It contains title and link tags. I fetch the tags and display them as links in ListView. From there when the user clicks the link, then I'd like play the .pls file in the Radio Station app.
Here is my XML file:
<item>
<title> Kushi FM </title>
<link>http://108.163.197.114:8071/listen.pls</link>
</item>
I don't know how to play the link in next activity.
MainActivity:
public class MainActivity extends AppCompatActivity {
// All static variables
static final String URL1 = "http://servernmae.com/stations";
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_TITLE = "title";
static final String KEY_LINK = "link";
URL url;
URLConnection urlConnection;
//Context context;
ListView listview;
int images=R.drawable.radio;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// isNetworkAvailable(this);
listview = (ListView) findViewById(R.id.list);
if(isNetworkAvailable(this))
{
new GetData().execute();
}else {
Toast.makeText(getApplicationContext(), "Please Connect to Internet and Check Again ! Thanks)",
Toast.LENGTH_LONG).show();
}
}
private boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
Log.w("INTERNET:",String.valueOf(i));
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
Log.w("INTERNET:", "connected!");
return true;
}
}
}
}
return false;
}
class GetData extends AsyncTask<String, String, String> {
String xml = "error";
#Override
protected String doInBackground(String... params) {
try {
url = new URL(URL1);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader isw = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isw);
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
xml = sb.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return xml;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
final ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
ArrayList<String> title= new ArrayList<>();
//title.add("");
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
for (int i = 0; i < nl.getLength(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
Log.e("TAg1", getValue(e, KEY_TITLE));
//Log.e("TAg2", getValue(e, KEY_LINK));
map.put(KEY_TITLE, getValue(e, KEY_TITLE));
map.put(KEY_LINK, getValue(e, KEY_LINK));
menuItems.add(map);
title.add(getValue(e, KEY_TITLE));
}
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
}
String[] dataArr = new String[title.size()];
dataArr = title.toArray(dataArr );
CustomAdapter adapter = new CustomAdapter(getApplicationContext(), dataArr );
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//HashMap<String, String> selectedMap = menuItems.get(position);
HashMap<String,String> selectedMap= menuItems.get(position);
String urls = selectedMap.get(KEY_LINK);
Intent intent = new Intent(MainActivity.this, Service_Player.class);
intent.putExtra("url",urls);
startActivity(intent);
}
});
}
public final String getElementValue(Node elem) {
Node child;
if (elem != null) {
if (elem.hasChildNodes()) {
for (child = elem.getFirstChild(); child != null; child = child.getNextSibling()) {
if (child.getNodeType() == Node.TEXT_NODE) {
return child.getNodeValue();
}
}
}
}
return "";
}
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
}
Service_player.java
public class Service_Player extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service__player);
startService(new Intent(this, MediaPlayerService.class));
String url = getIntent().getStringExtra("url");
if (!TextUtils.isEmpty(url))
startMediaPlayer(url);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiverFromservice, new IntentFilter(MediaPlayerService.SERVICE_TO_ACTIVITY));
}
private String currentPlayerStatus = "N/A";
private BroadcastReceiver receiverFromservice = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (MediaPlayerService.SERVICE_TO_ACTIVITY.equalsIgnoreCase(action)) {
/*
* To get current status of player
* */
currentPlayerStatus = intent.getStringExtra(MediaPlayerService.PLAYER_STATUS_KEY);
Log.e("Player Mode", "" + currentPlayerStatus);
}
}
};
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiverFromservice);
}
public void startMediaPlayer(String url) {
Intent intent = new Intent();
intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.PLAY_MEDIA_PLAYER);
intent.putExtra(MediaPlayerService.PLAYER_TRACK_URL, url);
sendBroadcast(intent);
}
MediaPlayerService.java
public class MediaPlayerService extends Service {
public static final String BROADCAST_TO_SERVICE = "com.mediaplayer.playerfunction";
public static final String SERVICE_TO_ACTIVITY = "com.mediaplayer.currentPlayerStatus";
public static final String PLAYER_FUNCTION_TYPE = "playerfunction";
public static final String PLAYER_TRACK_URL = "trackURL";
public static final int PLAY_MEDIA_PLAYER = 1;
public static final int PAUSE_MEDIA_PLAYER = 2;
public static final int RESUME_MEDIA_PLAYER = 3;
public static final int STOP_MEDIA_PLAYER = 4;
public static final int CHANGE_PLAYER_TRACK = 5;
public static final String PLAYER_STATUS_KEY = "PlayerCurrentStatus";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter intentFilter = new IntentFilter(BROADCAST_TO_SERVICE);
registerReceiver(playerReceiver, intentFilter);
if (mPlayer != null && mPlayer.isPlaying()) {
sendPlayerStatus("playing");
}
return START_STICKY;
}
private BroadcastReceiver playerReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BROADCAST_TO_SERVICE.equalsIgnoreCase(action)) {
String trackURL = intent.hasExtra(PLAYER_TRACK_URL) ? intent.getStringExtra(PLAYER_TRACK_URL) : "";
int function = intent.getIntExtra(PLAYER_FUNCTION_TYPE, 0);
switch (function) {
case CHANGE_PLAYER_TRACK:
changeTrack(trackURL);
break;
case STOP_MEDIA_PLAYER:
stopPlayer();
break;
case PLAY_MEDIA_PLAYER:
startMediaPlayer(trackURL);
break;
case PAUSE_MEDIA_PLAYER:
pausePlayer();
break;
case RESUME_MEDIA_PLAYER:
resumePlayer();
break;
}
}
}
};
private MediaPlayer mPlayer;
private void pausePlayer() {
if (mPlayer != null && mPlayer.isPlaying()) {
mPlayer.pause();
sendPlayerStatus("pause");
}
}
private void resumePlayer() {
if (mPlayer != null && !mPlayer.isPlaying()) {
mPlayer.start();
sendPlayerStatus("playing");
}
}
private void changeTrack(String url) {
stopPlayer();
startMediaPlayer(url);
}
private void stopPlayer() {
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
sendPlayerStatus("stopped");
}
}
public void startMediaPlayer(String url) {
if (TextUtils.isEmpty(url))
return;
if (mPlayer == null)
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(url);
mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
if (extra == MediaPlayer.MEDIA_ERROR_SERVER_DIED
|| extra == MediaPlayer.MEDIA_ERROR_MALFORMED) {
sendPlayerStatus("erroronplaying");
} else if (extra == MediaPlayer.MEDIA_ERROR_IO) {
sendPlayerStatus("erroronplaying");
return false;
}
return false;
}
});
mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.e("onBufferingUpdate", "" + percent);
}
});
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mPlayer.start();
sendPlayerStatus("playing");
}
});
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Log.e("onCompletion", "Yes");
sendPlayerStatus("completed");
}
});
mPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
});
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendPlayerStatus(String status) {
Intent intent = new Intent();
intent.setAction(SERVICE_TO_ACTIVITY);
intent.putExtra(PLAYER_STATUS_KEY, status);
sendBroadcast(intent);
}
Manifest.xml
<!-- Internet Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Service_Player"
android:label="#string/title_activity_service__player" >
</activity>
<service android:name=".MediaPlayerService"></service>
</application>
I'll suggest you to use Service if you are creating app with MediaPlayer streaming or normal MediaPlayer. It will be easy to handle player background & centrally.
To use media player in Service you can use it with BroadCastReceiver or Bound Service as per your requirement.It would be good if MediaPlayer related service if you keep it running in foreground here in below code I have not handle for that please check the given link.
Here in sample code i have used BroadCast Receiver to send command from Activity to Service for MediaPlayer(like play ,pause, change track etc) and vice versa.
Now to get url which you are sending from Activity onItemClickListner ,you need to get from Intent.
String url = getIntent().getStringExtra("url");
PlayerScreen
public class PlayerScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
startService(new Intent(this, MediaPlayerService.class));
findViewById(R.id.btnChangeTrack).setOnClickListener(clickListener);
findViewById(R.id.btnStartMediaPlayer).setOnClickListener(clickListener);
findViewById(R.id.btnStopMediaPlayer).setOnClickListener(clickListener);
ToggleButton toggleButton = (ToggleButton) findViewById(R.id.togglePauseResume);
toggleButton.setOnCheckedChangeListener(checkedChangeListener);
/*
* To get url which is passing from the previous activity listitem click.
* If url which is pass from listitem click is not empty it will start player
* */
String url = getIntent().getStringExtra("url");
if (!TextUtils.isEmpty(url))
startMediaPlayer(url);
}
private ToggleButton.OnCheckedChangeListener checkedChangeListener = new ToggleButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!isChecked) {
Intent intent = new Intent();
intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.PAUSE_MEDIA_PLAYER);
sendBroadcast(intent);
} else {
Intent intent = new Intent();
intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.RESUME_MEDIA_PLAYER);
sendBroadcast(intent);
}
}
};
private View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.btnChangeTrack:
intent = new Intent();
intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.CHANGE_PLAYER_TRACK);
intent.putExtra(MediaPlayerService.PLAYER_TRACK_URL, "http://69.64.41.64:9938");
sendBroadcast(intent);
break;
case R.id.btnStartMediaPlayer:
startMediaPlayer("http://108.163.197.114:8071/listen.pls");
break;
case R.id.btnStopMediaPlayer:
intent = new Intent();
intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.STOP_MEDIA_PLAYER);
sendBroadcast(intent);
break;
}
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiverFromservice, new IntentFilter(MediaPlayerService.SERVICE_TO_ACTIVITY));
}
private String currentPlayerStatus = "N/A";
private BroadcastReceiver receiverFromservice = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (MediaPlayerService.SERVICE_TO_ACTIVITY.equalsIgnoreCase(action)) {
/*
* To get current status of player
* */
currentPlayerStatus = intent.getStringExtra(MediaPlayerService.PLAYER_STATUS_KEY);
Log.e("Player Mode", "" + currentPlayerStatus);
}
}
};
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiverFromservice);
}
/**
* TO start media player.It will send broadcast to Service & from service player will start
*
* #param url
*/
public void startMediaPlayer(String url) {
Intent intent = new Intent();
intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.PLAY_MEDIA_PLAYER);
intent.putExtra(MediaPlayerService.PLAYER_TRACK_URL, url);
sendBroadcast(intent);
}
}
MediaPlayerService
public class MediaPlayerService extends Service {
public static final String BROADCAST_TO_SERVICE = "com.mediaplayer.playerfunction";
public static final String SERVICE_TO_ACTIVITY = "com.mediaplayer.currentPlayerStatus";
public static final String PLAYER_FUNCTION_TYPE = "playerfunction";
public static final String PLAYER_TRACK_URL = "trackURL";
public static final int PLAY_MEDIA_PLAYER = 1;
public static final int PAUSE_MEDIA_PLAYER = 2;
public static final int RESUME_MEDIA_PLAYER = 3;
public static final int STOP_MEDIA_PLAYER = 4;
public static final int CHANGE_PLAYER_TRACK = 5;
public static final String PLAYER_STATUS_KEY = "PlayerCurrentStatus";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter intentFilter = new IntentFilter(BROADCAST_TO_SERVICE);
registerReceiver(playerReceiver, intentFilter);
if (mPlayer != null && mPlayer.isPlaying()) {
sendPlayerStatus("playing");
}
return START_STICKY;
}
private BroadcastReceiver playerReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BROADCAST_TO_SERVICE.equalsIgnoreCase(action)) {
String trackURL = intent.hasExtra(PLAYER_TRACK_URL) ? intent.getStringExtra(PLAYER_TRACK_URL) : "";
int function = intent.getIntExtra(PLAYER_FUNCTION_TYPE, 0);
switch (function) {
case CHANGE_PLAYER_TRACK:
changeTrack(trackURL);
break;
case STOP_MEDIA_PLAYER:
stopPlayer();
break;
case PLAY_MEDIA_PLAYER:
startMediaPlayer(trackURL);
break;
case PAUSE_MEDIA_PLAYER:
pausePlayer();
break;
case RESUME_MEDIA_PLAYER:
resumePlayer();
break;
}
}
}
};
private MediaPlayer mPlayer;
private void pausePlayer() {
if (mPlayer != null && mPlayer.isPlaying()) {
mPlayer.pause();
sendPlayerStatus("pause");
}
}
private void resumePlayer() {
if (mPlayer != null && !mPlayer.isPlaying()) {
mPlayer.start();
sendPlayerStatus("playing");
}
}
private void changeTrack(String url) {
stopPlayer();
startMediaPlayer(url);
}
private void stopPlayer() {
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
sendPlayerStatus("stopped");
}
}
public void startMediaPlayer(String url) {
if (TextUtils.isEmpty(url))
return;
if (mPlayer == null)
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(url);
mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
if (extra == MediaPlayer.MEDIA_ERROR_SERVER_DIED
|| extra == MediaPlayer.MEDIA_ERROR_MALFORMED) {
sendPlayerStatus("erroronplaying");
} else if (extra == MediaPlayer.MEDIA_ERROR_IO) {
sendPlayerStatus("erroronplaying");
return false;
}
return false;
}
});
mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.e("onBufferingUpdate", "" + percent);
}
});
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mPlayer.start();
sendPlayerStatus("playing");
}
});
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Log.e("onCompletion", "Yes");
sendPlayerStatus("completed");
}
});
mPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
});
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendPlayerStatus(String status) {
Intent intent = new Intent();
intent.setAction(SERVICE_TO_ACTIVITY);
intent.putExtra(PLAYER_STATUS_KEY, status);
sendBroadcast(intent);
}
}
player.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ab_tool"
android:text="Home" />
<Button
android:id="#+id/btnStartMediaPlayer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/section_label"
android:text="Start Player" />
<ToggleButton
android:id="#+id/togglePauseResume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/btnStartMediaPlayer"
android:checked="true"
android:textOff="Resume"
android:textOn="Pause" />
<Button
android:id="#+id/btnChangeTrack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/togglePauseResume"
android:text="Chanage Track" />
<Button
android:id="#+id/btnStopMediaPlayer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/btnChangeTrack"
android:text="STOP" />
</RelativeLayout>
Manifest
<activity android:name=".PlayerScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MediaPlayerService"></service>
To get data from streaming url header data you can check this answer
For testing purpose here i have used two urls
UPDATE
PlayerActivity
public class PlayerScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
startService(new Intent(this, MediaPlayerService.class));
/*
* To get url which is passing from the previous activity listitem click.
* If url which is pass from listitem click is not empty it will start player
* */
String url = getIntent().getStringExtra("url");
if (!TextUtils.isEmpty(url))
startMediaPlayer(url);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiverFromservice, new IntentFilter(MediaPlayerService.SERVICE_TO_ACTIVITY));
}
private String currentPlayerStatus = "N/A";
private BroadcastReceiver receiverFromservice = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (MediaPlayerService.SERVICE_TO_ACTIVITY.equalsIgnoreCase(action)) {
/*
* To get current status of player
* */
currentPlayerStatus = intent.getStringExtra(MediaPlayerService.PLAYER_STATUS_KEY);
Log.e("Player Mode", "" + currentPlayerStatus);
}
}
};
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiverFromservice);
}
/**
* TO start media player.It will send broadcast to Service & from service player will start
*
* #param url
*/
public void startMediaPlayer(String url) {
Intent intent = new Intent();
intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.PLAY_MEDIA_PLAYER);
intent.putExtra(MediaPlayerService.PLAYER_TRACK_URL, url);
sendBroadcast(intent);
}
}
let me know if anything.
MediaPlayer mp;
mp=MediaPlayer.create(getApplicationContext(),Uri.parse(url))
//Example url of .pls file http://50.xx.xxx.xx:xx40/)
mp.start();
mp.pause();
mp.release() (or mp.reset() as applicable)

how can i play list view item when click context menu item on that list view item in android

I am developing one application in that am recording incoming and outgoing calls and am displaying in one list view. when i click on list view items it will display one context menu items(play, delete)
options. when i click play item in context menu list view item will play with media player. I will try but it does not play with media player.how can i do this please please help me.am new to android development. I am posting my code.
*public class CallLog
extends Activity
{
private final String TAG = "CallRecorder";
private ListView fileList = null;
public static ArrayAdapter<String> fAdapter = null;
private ArrayList<String> recordingNames = null;
private SeekBar seekbar;
private MediaPlayer mediaPlayer=new MediaPlayer();
private ImageButton pauseButton;
public TextView startTimeField,endTimeField;
AudioManager audioManager;
private double startTime = 0;
private double finalTime = 0;
private Handler myHandler = new Handler();
int oneTimeOnly = 0;
private void loadRecordingsFromProvider()
{
//fAdapter.clear();
fAdapter.clear();
ContentResolver cr = getContentResolver();
Cursor c = cr.query(RecordingProvider.CONTENT_URI, null, null, null, null);
String[] names = new String[c.getCount()];
int i = 0;
if (c.moveToFirst()) {
do {
// Extract the recording names
fAdapter.add(c.getString(RecordingProvider.DETAILS_COLUMN));
i++;
} while (c.moveToNext());
}
fAdapter.notifyDataSetChanged();
}
#SuppressLint("ShowToast")
private void loadRecordingsFromDir()
{
fAdapter.clear();
File dir = new File(RecordService.DEFAULT_STORAGE_LOCATION);
String[] dlist = dir.list();
Log.v("fille", "recording file" +dlist);
for (int i=0; i<dlist.length; i++) {
fAdapter.add(dlist[i]);
}
fAdapter.notifyDataSetChanged();
}
private class CallItemClickListener implements AdapterView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
view.showContextMenu();
CharSequence s = (CharSequence)parent.getItemAtPosition(position);
Log.w(TAG, "CallLog just got an item clicked: " + s);
File f = new File(RecordService.DEFAULT_STORAGE_LOCATION + "/" + s.toString());
/*boolean useMediaController = true;
if (useMediaController) {
Intent playIntent = new Intent(getApplicationContext(), CallPlayer.class); //Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(f);
playIntent.setData(uri);
startActivity(playIntent);
} else {
playFile(s.toString());
}*/
}
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
setContentView(R.layout.call_log);
//recordingNames = new String[0];
fileList = (ListView)findViewById(R.id.play_file_list);
Context context = getApplicationContext();
setVolumeControlStream(AudioManager.STREAM_MUSIC);
fAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1);
fileList.setAdapter(fAdapter);
fileList.setOnItemClickListener(new CallItemClickListener());
registerForContextMenu(fileList);
}
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater m = getMenuInflater();
m.inflate(R.menu.nn, menu);
}
#SuppressLint("ShowToast")
#Override
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
int index=info.position;
switch(item.getItemId()){
case R.id.play:
final Dialog seekDialog = new Dialog(this);
seekDialog.setTitle("paly");
seekDialog.setContentView(R.layout.dialog);
//final Button butt=(Button)levelDialog.findViewById(R.id.but);
startTimeField=(TextView)seekDialog.findViewById(R.id.textView1);
endTimeField=(TextView)seekDialog.findViewById(R.id.textView2);
pauseButton = (ImageButton)seekDialog.findViewById(R.id.imageButton2);
seekbar = (SeekBar)findViewById(R.id.seek);
seekDialog.show();
fileList.getItemAtPosition(index);
Log.v("playyyyyyyy", "id" +fileList.getItemAtPosition(index));
String path=fAdapter.getItem(index);
try {
mediaPlayer.setDataSource(path);
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
mediaPlayer.start();
//Toast.makeText(getApplicationContext(), "play", 1000).show();
return true;
case R.id.delete:
Toast.makeText(getApplicationContext(), "delete", 1000).show();
return true;
}
return super.onContextItemSelected(item);
}
public void onStart()
{
super.onStart();
Log.i(TAG, "CallLog onStart");
}
public void onRestart()
{
super.onRestart();
Log.i(TAG, "CallLog onRestart");
}
public void onResume()
{
super.onResume();
//Log.i(TAG, "CallLog onResume about to load recording list again, does this work?");
loadRecordingsFromDir();
}
/*private void playFile(String fName) {
Log.i(TAG, "playFile: " + fName);
Context context = getApplicationContext();
Intent playIntent = new Intent(context, PlayService.class);
playIntent.putExtra(PlayService.EXTRA_FILENAME, RecordService.DEFAULT_STORAGE_LOCATION + "/" + fName);
ComponentName name = context.startService(playIntent);
if (null == name) {
Log.w(TAG, "CallLog unable to start PlayService with intent: " + playIntent.toString());
} else {
Log.i(TAG, "CallLog started service: " + name);
}
}*/
protected void onDestroy() {
/*if(null!=mediaPlayer){
mediaPlayer.release();
}*/
super.onDestroy();
if(mediaPlayer!=null){
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
/*public void onDestroy() {
Context context = getApplicationContext();
Intent playIntent = new Intent(context, PlayService.class);
context.stopService(playIntent);
super.onDestroy();
}*/
}*

Google Download Manager immediately stops with STATE_COMPLETED

I'm trying to use the google download manager for downloading main and patch expansion files which are both uploaded with the apk. I'm pretty much following the google example. The download process starts but immediately stops with 'STATE_COMPLETED'. No error but the files are still missing. The App only works if I manually copy the files to the device.
This is my Download Activity:
public class DownloadActivity extends Activity implements IDownloaderClient {
private IStub mDownloaderClientStub;
private IDownloaderService mRemoteService;
private boolean downloadDoneRegistered = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
startDownload();
}
#Override
protected void onResume() {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.connect(this);
}
super.onResume();
}
#Override
protected void onStop() {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.disconnect(this);
}
super.onStop();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.download, menu);
return true;
}
// IDownloaderClient
#Override
public void onServiceConnected(Messenger m) {
mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
}
#Override
public void onDownloadStateChanged(int newState) { //todo
switch (newState) {
case IDownloaderClient.STATE_IDLE:
case IDownloaderClient.STATE_CONNECTING:
case IDownloaderClient.STATE_FETCHING_URL:
case IDownloaderClient.STATE_DOWNLOADING:
break;
case IDownloaderClient.STATE_FAILED_CANCELED:
case IDownloaderClient.STATE_FAILED:
case IDownloaderClient.STATE_FAILED_FETCHING_URL:
case IDownloaderClient.STATE_FAILED_UNLICENSED:
downloadFailed();
break;
case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
case IDownloaderClient.STATE_PAUSED_ROAMING:
case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
break;
case IDownloaderClient.STATE_COMPLETED:
downloadDone();
return;
default:
break;
}
}
#Override
public void onDownloadProgress(DownloadProgressInfo progress) {
float p = (float)progress.mOverallProgress;
if (progress.mOverallTotal>0) {
p /= (float)progress.mOverallTotal;
} else {
p = 0.0f;
}
String s = String.format(getString(R.string.download_progress).replace("#","%"),100.0f*p);
D.L(this,s);
setProgressBar(p);
setText(s);
}
//
private void startDownload() {
D.L(this,getString(R.string.download_checkfiles));
setProgressBar(0.0f);
setText(getString(R.string.download_checkfiles));
if (!expansionFilesDelivered()) {
D.L(this,"expansion files not downloaded so far");
setProgressBar(0.0f);
setText(String.format(getString(R.string.download_progress).replace("#","%"),0.0f));
try {
Intent launchIntent = DownloadActivity.this.getIntent();
Intent intentToLaunchThisActivityFromNotification = new Intent(DownloadActivity.this,DownloadActivity.this.getClass());
intentToLaunchThisActivityFromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentToLaunchThisActivityFromNotification.setAction(launchIntent.getAction());
PendingIntent pendingIntent = PendingIntent.getActivity(DownloadActivity.this,0,intentToLaunchThisActivityFromNotification,PendingIntent.FLAG_UPDATE_CURRENT);
D.L(this,"start download service");
int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this,pendingIntent,DownloadService.class);
D.L(this,""+startResult+" <-compare-> "+DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED+"=NO_DOWNLOAD_REQUIRED");
if (startResult!=DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
D.L(this,"-> download required, create stub");
setText(String.format(getString(R.string.download_progress).replace("#","%"),0.0f));
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,DownloadService.class);
return;
} else {
D.L(this,"no download required");
downloadDone();
}
} catch (NameNotFoundException e) {
D.L(this,e.getMessage());
downloadFailed();
}
} else {
// validate apk zip files(?)
D.L(this,"expansion files valid, no download required");
downloadDone();
}
}
boolean expansionFilesDelivered() {
if ((Download.MAIN_EXISTS) &&
(!Helpers.doesFileExist(this,Helpers.getExpansionAPKFileName(this,true,Download.MAIN_VERSION),Download.MAIN_SIZE,false))) {
return false;
}
if ((Download.PATCH_EXISTS) &&
(!Helpers.doesFileExist(this,Helpers.getExpansionAPKFileName(this,false,Download.PATCH_VERSION),Download.PATCH_SIZE,false))) {
return false;
}
return true;
}
private void setProgressBar(float value) {
((ProgressBar)findViewById(R.id.progressBar)).setProgress((int)(1000.0f*value));
}
private void setText(String text) {
((TextView)findViewById(R.id.textView)).setText(text);
}
private void downloadDone() {
if (!downloadDoneRegistered) {
downloadDoneRegistered = true;
D.L(this,"downloadDone(): download terminated");
setProgressBar(1.0f);
setText(getString(R.string.download_completed));
boolean fileAccess = true;
if (Download.MAIN_EXISTS) {
Download.SetMainFile(safeFileAccess(Helpers.getExpansionAPKFileName(this,true,Download.MAIN_VERSION)));
fileAccess = fileAccess && (Download.GetMainFile()!=null);
} else {
D.L(this,"no main expansion file");
}
if (Download.PATCH_EXISTS) {
Download.SetPatchFile(safeFileAccess(Helpers.getExpansionAPKFileName(this,false,Download.PATCH_VERSION)));
fileAccess = fileAccess && (Download.GetPatchFile()!=null);
} else {
D.L(this,"no patch expansion file");
}
if (fileAccess) {
D.L(this,"file access passed");
T.StartActivity(this,SplashActivity.class,true);
} else {
fileAccessFailed();
}
}
}
private File safeFileAccess(String fileName) {
D.L(this,"try to access file...");
File r = new File(
Environment.getExternalStorageDirectory()+File.separator+
"Android"+File.separator+
"obb"+File.separator+
getPackageName() ,
fileName);
D.L(this," "+r);
if (r.exists()) {
D.L(this," passed");
} else {
D.L(this," failed");
r = null;
}
return r;
}
private void downloadFailed() {
D.L(this,getString(R.string.download_failed));
setText(getString(R.string.download_failed));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.download_failed_dialogtext));
builder.setPositiveButton(getString(R.string.download_dialog_okay),new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
});
builder.create().show();
}
private void fileAccessFailed() {
D.L(this,getString(R.string.download_accessfailed));
setText(getString(R.string.download_accessfailed));
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.download_accessfailed_dialogtext));
builder.setPositiveButton(getString(R.string.download_dialog_okay),new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
});
builder.create().show();
}
}
My Alarm Receiver:
public class DownloadAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
DownloaderClientMarshaller.startDownloadServiceIfRequired(context,intent,DownloadService.class);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
}
My Download Service:
public class DownloadService extends DownloaderService {
#Override
public String getPublicKey() {
return Download.BASE64_PUBLIC_KEY;
}
#Override
public byte[] getSALT() {
return Download.SALT;
}
#Override
public String getAlarmReceiverClassName() {
return DownloadAlarmReceiver.class.getName();
}
}
Some data stuff:
public class Download {
private static Download Instance = new Download();
public static Download GetInstance() { return Instance; }
//todo
public static final String BASE64_PUBLIC_KEY = "..actual key..";
public static final byte[] SALT = new byte[] {..numbers..};
public static final boolean MAIN_EXISTS = true;
public static final int MAIN_VERSION = 2;
public static final long MAIN_SIZE = 20971520L;
public static final boolean PATCH_EXISTS = true;
public static final int PATCH_VERSION = 2;
public static final long PATCH_SIZE = 10485760L;
…
Any ideas?

When running my Android App in the Eclipse Debugger, I have a service that notifies. Outside of the debugger it does not send a notification

I'm making an app that sends a notification to the status bar, it sends the notification when stepping through the code in the debugger, however it never sends the notification when run in realtime.
Here is my runnable that generates the notification, again when stepping through this code in the debugger the notification runs however in realtime nothing happens.
public class NewsEvents_Service extends Service {
private static final String NEWSEVENTS = "newsevents";
private static final String KEYWORDS = "keywords";
private NotificationManager mNM;
private ArrayList<NewsEvent> neList;
private int count;
#Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
neList = new ArrayList<NewsEvent>();
getKeywords();
//getNewsEvents();
Thread thr = new Thread(null, mTask, "NewsEvents_Service");
thr.start();
Log.d("Thread", "IT STARTED!!!!!!????!!!!!!!!!!!!!!!?!!?");
}
#Override
public void onDestroy() {
// Cancel the notification -- we use the same ID that we had used to start it
mNM.cancel(R.string.ECS);
// Tell the user we stopped.
Toast.makeText(this, "Service Done", Toast.LENGTH_SHORT).show();
}
/**
* The function that runs in our worker thread
*/
Runnable mTask = new Runnable() {
public void run() {
getNewsEventsFromWeb();
for(NewsEvent ne : neList){
Log.d("Thread Running", "Service Code running!!!!!!!!!!!!!!!");
String body = ne.getBody().replaceAll("\\<.*?>", "");
String title = ne.getTitle();
for(String s : keyWordList){
if(body.contains(s) || body.contains(s.toLowerCase()) ||
title.contains(s) || title.contains(s.toLowerCase())){
ne.setInterested(true);
}
}
if(ne.isInterested() == true ){
Notification note = new Notification(R.drawable.icon,
"New ECS News Event", System.currentTimeMillis());
Intent i = new Intent(NewsEvents_Service.this, FullNewsEvent.class);
i.putExtra("ne", ne);
PendingIntent pi = PendingIntent.getActivity(NewsEvents_Service.this, 0,
i, 0);
note.setLatestEventInfo(NewsEvents_Service.this, "New Event", ne.getTitle(), pi);
note.flags = Notification.FLAG_AUTO_CANCEL;
mNM.notify(R.string.ECS, note);
}
}
}
};
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* Show a notification while this service is running.
*/
private void getNewsEventsFromWeb() {
HttpClient client = new DefaultHttpClient();
HttpGet get;
try {
get = new HttpGet(getString(R.string.jsonnewsevents));
ResponseHandler<String> response = new BasicResponseHandler();
String responseBody = client.execute(get, response);
String page = responseBody;
Bundle data = new Bundle();
data.putString("page",page);
Message msg = new Message();
msg.setData(data);
handler.sendMessage(msg);
}
catch (Throwable t) {
Log.d("UpdateNews", "PROBLEMS");
}
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
String page = msg.getData().getString("page");
try {
JSONArray parseArray = new JSONArray(page);
for (int i = 0; i < parseArray.length(); i++) {
JSONObject jo = parseArray.getJSONObject(i);
String title = jo.getString("title");
String body =jo.getString("body");
String pd = jo.getString("postDate");
String id = jo.getString("id");
NewsEvent ne = new NewsEvent(title, pd , body, id);
boolean unique = true;
for(NewsEvent ne0 : neList){
if(ne.getId().equals(ne0.getId())){
unique = false;
}else{
unique = true;
}
}
if(unique == true){
neList.add(ne);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private ArrayList<String> keyWordList;
public void getNewsEvents(){
try {
InputStream fi = openFileInput(NEWSEVENTS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
neList = (ArrayList<NewsEvent>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(neList == null){
neList = new ArrayList<NewsEvent>();
}
}
public ArrayList<String> getKeywords(){
try {
InputStream fi = openFileInput(KEYWORDS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
keyWordList = (ArrayList<String>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(keyWordList == null){
keyWordList = new ArrayList<String>();
return keyWordList;
}
return keyWordList;
}
/**
* This is the object that receives interactions from clients. See RemoteService
* for a more complete example.
*/
private final IBinder mBinder = new Binder() {
#Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
return super.onTransact(code, data, reply, flags);
}
};
}
Here is my activity that schedules the service to run
public class NewsEvents extends ListActivity{
private URL JSONNewsEvents;
private ArrayList<NewsEvent> neList;
private ArrayList<String> keyWordList;
private Worker worker;
private NewsEvents ne;
public static final String KEYWORDS = "keywords";
private static final String NEWSEVENTS = "newsevents";
public static final int ONE_ID = Menu.FIRST+1;
private PendingIntent newsAlarm;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newsevents);
ne = this;
neList = new ArrayList<NewsEvent>();
try {
JSONNewsEvents = new URL(getString(R.string.jsonnewsevents));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
worker = new Worker(handler, this);
setListAdapter(new IconicAdapter());
getKeywords();
worker.execute(JSONNewsEvents);
}
#Override
protected void onStop() {
super.onStop();
writeNewsEvents() ;
}
#Override
protected void onPause(){
super.onPause();
writeNewsEvents();
}
private void writeNewsEvents() {
try {
OutputStream fi = openFileOutput(NEWSEVENTS, 0);
if (fi!=null) {
ObjectOutputStream out = new ObjectOutputStream(fi);
out.writeObject(neList);
out.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
}
/**
* #return
*/
public ArrayList<String> getKeywords(){
try {
InputStream fi = openFileInput(KEYWORDS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
keyWordList = (ArrayList<String>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(keyWordList == null){
keyWordList = new ArrayList<String>();
return keyWordList;
}
return keyWordList;
}
public void onListItemClick(ListView parent, View v,
int position, long id) {
startFullNewsEvent(neList.get(position));
}
/**
* #param newsEvent
*/
public void startFullNewsEvent(NewsEvent ne) {
Intent intent = new Intent(this, FullNewsEvent.class);
intent.putExtra("ne", ne);
this.startActivity(intent);
finish();
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
String page = msg.getData().getString("page");
try {
JSONArray parseArray = new JSONArray(page);
for (int i = 0; i < parseArray.length(); i++) {
JSONObject jo = parseArray.getJSONObject(i);
String title = jo.getString("title");
String body =jo.getString("body");
String pd = jo.getString("postDate");
String id = jo.getString("id");
NewsEvent ne = new NewsEvent(title, pd , body, id);
boolean unique = true;
for(NewsEvent ne0 : neList){
if(ne.getId().equals(ne0.getId())){
unique = false;
}else{
unique = true;
}
}
if(unique == true){
neList.add(ne);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ne.setListAdapter(new IconicAdapter());
}
};
public class IconicAdapter extends ArrayAdapter<NewsEvent> {
IconicAdapter() {
super(NewsEvents.this, R.layout.rownews, neList);
}
public View getView(int position, View convertView,ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.rownews, parent, false);
TextView label=(TextView)row.findViewById(R.id.label);
ImageView image= (ImageView)row.findViewById(R.id.icon);
String body = neList.get(position).getBody();
body.replaceAll("\\<.*?>", "");
String title = neList.get(position).getTitle();
for(String s : keyWordList){
if(body.contains(s) || body.contains(s.toLowerCase()) ||
title.contains(s) || title.contains(s.toLowerCase())){
neList.get(position).setInterested(true);
}
}
if(neList.get(position).isInterested() == true){
image.setImageResource(R.drawable.star);
}
label.setText(neList.get(position).getTitle());
return(row);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
populateMenu(menu);
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return(applyMenuChoice(item) || super.onOptionsItemSelected(item));
}
//Creates our activity to menus
private void populateMenu(Menu menu) {
menu.add(Menu.NONE, ONE_ID, Menu.NONE, "Home");
}
private boolean applyMenuChoice(MenuItem item) {
switch (item.getItemId()) {
case ONE_ID: startHome(); return(true);
}
return(false);
}
public void startHome() {
Intent intent = new Intent(this, ECS.class);
this.startActivity(intent);
finish();
}
}
Race conditions, I'm making an HTTP Request and then handing it off to a handler, immediately following that I iterator through the array list, which at full speed is empty because the HTTP hasn't completed. In debugging it all slows down so the HTTP is complete and all works well.
Threads and Network Connections, a deadly combination.

Categories

Resources