In my App's MainActivity I am playing some sounds using MediaPlayers and in The onPause() in that activity I realease the players and I am starting a service to continue playing these sounds by creating them again and I send the resourcesNames and the Volume of every player from the activity to the service , I am using setLooping() to make these sounds loop and I am running the service in a new thread (outside the main thread) uding Handler and HandlerThread.
when the activity gets paused the service starts and the sounds are playing but the problem is that they just loop for 3 times and then the service is getting destroyed without stopService() or stopSelf() are being called and also without exiting from the app(the app still in the recent apps)?
Here the sevice's code :
package com.example.naturesounds;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.util.Log;
import androidx.annotation.NonNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
public class SoundSPlayingService extends Service implements MediaPlayer.OnPreparedListener
{
private static final String PACKAGE_NAME = "com.example.naturesounds";
private float playerVolume = 0.0f;
serviceHandler serviceHandler;
Looper serviceLooper;
HandlerThread thread;
Intent intent;
Bundle playersVolume = new Bundle() ;
ArrayList<String> runningResourceNames = new ArrayList<>();
HashMap<String, MediaPlayer> playersMap = new HashMap<>();
#Override
public void onCreate() {
thread = new HandlerThread("ServiceThread", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
serviceLooper = thread.getLooper();
serviceHandler = new serviceHandler(serviceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message message = serviceHandler.obtainMessage();
message.obj = intent;
serviceHandler.sendMessage(message);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onDestroy() {
releasePlayers();
Log.d("serviceLifeCycle","onDestroy() is running");
}
public void createPlayer(String resourceName)
{
playersMap.put(resourceName,new MediaPlayer());
try {
playersMap.get(resourceName).setDataSource(getApplicationContext(),
Uri.parse("android.resource://com.example.naturesounds/raw/" + resourceName));
playersMap.get(resourceName).setOnPreparedListener(this);
playersMap.get(resourceName).prepareAsync();
playersMap.get(resourceName).setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
setPlayerLooping(resourceName);
setPlayerVolume(resourceName);
}
catch (IOException e1)
{
e1.printStackTrace();
}
catch (IllegalArgumentException e2)
{
e2.printStackTrace();
}
}
public void releasePlayers()
{
for(int i=0 ; i<runningResourceNames.size(); i++)
{
String resourceName = runningResourceNames.get(i);
if(playersMap.get(resourceName) != null)
{
playersMap.get(resourceName).release();
playersMap.put(resourceName,null);
}
}
}
public void setPlayerVolume(String resourceName)
{
playerVolume = playersVolume.getFloat(resourceName);
Log.d("playerVolume",String.valueOf(playerVolume));
playersMap.get(resourceName).setVolume(playerVolume,playerVolume);
}
public void setPlayerLooping(String resourceName)
{
playersMap.get(resourceName).setLooping(true);
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
class serviceHandler extends Handler
{
public serviceHandler(Looper looper)
{
super(looper);
}
#Override
public void handleMessage(#NonNull Message msg) {
Log.d("serviceHandlerChecking","handleMessage() is executing");
intent = (Intent) msg.obj;
runningResourceNames = intent.getStringArrayListExtra(PACKAGE_NAME + ".MainActivity.runningResourceNames");
playersVolume = intent.getBundleExtra(PACKAGE_NAME + ".MainActivity.playersVolume");
for(int i=0; i<runningResourceNames.size(); i++)
{
String resourceName = runningResourceNames.get(i);
createPlayer(resourceName);
}
}
}
}
I am getting the following error when building my project using a Room Database.
C:\Users\russelg1\AndroidStudioProjects\CheckingIn\app\src\main\java\com\grgsolutions\checkingin\CheckInTableDao.java:19: error: Unused parameter: checkInTablePrimaryKey
List findCheckIn(int checkInTablePrimaryKey);
This is the DAO for the table in question
package com.grgsolutions.checkingin;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import java.util.List;
#Dao
public interface CheckInTableDao {
#Insert
void insertCheckIn(CheckInTable... checkInTable);
#Query("DELETE FROM check_in_table WHERE checkInTablePrimaryKey = :checkInTablePrimaryKey")
void deleteCheckIn(int checkInTablePrimaryKey);
#Query("SELECT * FROM check_in_table")
LiveData<List<CheckInTable>> getAllCheckIn();
#Query("SELECT * FROM check_in_table where checkInTablePrimaryKey = checkInTablePrimaryKey")
List<CheckInTable> findCheckIn(int checkInTablePrimaryKey);
#Query("DELETE FROM check_in_table")
void deleteAllCheckIn();
}
This is the Room Repository for the table.
package com.grgsolutions.checkingin;
import android.content.Context;
import android.os.AsyncTask;
import android.text.PrecomputedText;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import java.util.List;
import static androidx.constraintlayout.widget.Constraints.TAG;
public class CheckInTableRepository {
private MutableLiveData<List<CheckInTable>> searchCheckInResults =
new MutableLiveData<>();
private LiveData<List<CheckInTable>> allCheckIn;
private List<CheckInTable> foundCheckIn;
private CheckInTableDao checkInTableDao;
public CheckInTableRepository(Context appContext) {
CheckingInRoomDatabase db;
db = CheckingInRoomDatabase.getDatabase(appContext);
checkInTableDao = db.checkInTableDao();
allCheckIn = checkInTableDao.getAllCheckIn();
foundCheckIn = checkInTableDao.findCheckIn(0);
}
public LiveData<List<CheckInTable>> getAllCheckIn() {
Log.i(TAG, "getAllCheckIn: creating allCheckIn ");
return allCheckIn;
}
public void insertCheckIn(CheckInTable newcheckin) {
CheckInTableRepository.InsertAsyncTask task = new
CheckInTableRepository.InsertAsyncTask(checkInTableDao);
task.execute(newcheckin);
}
public void deleteCheckIn(int checkInTablePrimaryKey) {
CheckInTableRepository.DeleteAsyncTask task = new
CheckInTableRepository.DeleteAsyncTask(checkInTableDao);
task.execute();
}
public CheckInTable findCheckIn(int checkInTablePrimaryKey) {
CheckInTableRepository.QueryAsyncTask task = new
CheckInTableRepository.QueryAsyncTask(checkInTableDao);
task.delegate = this;
task.execute(checkInTablePrimaryKey);
}
private void asyncFinished(List<CheckInTable> result) {
foundCheckIn = result;
}
private static class QueryAsyncTask extends
AsyncTask<Integer, Void, List<CheckInTable>> {
private CheckInTableDao asyncTaskDao;
private CheckInTableRepository delegate = null;
QueryAsyncTask(CheckInTableDao dao) {
asyncTaskDao = dao;
}
#Override
protected List<CheckInTable> doInBackground(final Integer... params) {
return asyncTaskDao.findCheckIn(params[0]);
}
protected void onPostExecute(List<CheckInTable> result) {
delegate.asyncFinished(result);
}
}
private static class InsertAsyncTask extends AsyncTask<CheckInTable, Void, Void> {
private CheckInTableDao asyncTaskDao;
InsertAsyncTask(CheckInTableDao dao) {
asyncTaskDao = dao;
}
#Override
protected Void doInBackground(final CheckInTable... params) {
asyncTaskDao.insertCheckIn(params[0]);
return null;
}
}
private static class DeleteAsyncTask extends AsyncTask<Integer, Void, Void> {
private CheckInTableDao asyncTaskDao;
DeleteAsyncTask(CheckInTableDao dao) {
asyncTaskDao = dao;
}
#Override
protected Void doInBackground(final Integer... params) {
asyncTaskDao.deleteCheckIn(params[0]);
return null;
}
}
}
This is the View Model
package com.grgsolutions.checkingin;
import android.content.Context;
import android.util.Log;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import java.util.List;
import static androidx.constraintlayout.widget.Constraints.TAG;
public class MainViewModel extends ViewModel {
private CheckInRecipientsTableRepository checkInRecipientsTableRepository;
private LiveData<List<CheckInRecipientsTable>> allRecipients;
private ContactGroupsTableRepository contactGroupsTableRepository;
private LiveData<List<ContactGroupsTable>> allContactGroups;
private ContactTableRepository contactTableRepository;
private LiveData<List<ContactTable>> allContacts;
private CheckInTableRepository checkInTableRepository;
private LiveData<List<CheckInTable>> allCheckIn;
private List<CheckInTable> foundCheckIn;
public MainViewModel (Context appContext) {
//super(appContext);
Log.i(TAG, "MainViewModel: In the Main View Model");
checkInRecipientsTableRepository = new CheckInRecipientsTableRepository(appContext);
allRecipients = checkInRecipientsTableRepository.getAllCheckInRecipients();
Log.i(TAG, "MainViewModel: In the Main View Model");
checkInTableRepository = new CheckInTableRepository(appContext);
allCheckIn = checkInTableRepository.getAllCheckIn();
//checkInTableRepository = new CheckInTableRepository(appContext);
//foundCheckIn = checkInTableRepository.findCheckIn();
Log.i(TAG, "MainViewModel: In the Main View Model");
contactGroupsTableRepository = new ContactGroupsTableRepository(appContext);
allContactGroups = contactGroupsTableRepository.getAllContactGroups();
Log.i(TAG, "MainViewModel: In the Main View Model");
contactTableRepository = new ContactTableRepository(appContext);
allContacts = contactTableRepository.getAllContact();
}
LiveData<List<CheckInTable>> getAllCheckIn() {
Log.i(TAG, "getAllCheckIn: in main view model");
return allCheckIn;
}
public void findCheckIn(int checkInTablePrimaryKey) {
checkInTableRepository.findCheckIn(checkInTablePrimaryKey);
}
public void insertCheckIn(CheckInTable checkInTable) {
checkInTableRepository.insertCheckIn(checkInTable);
}
public void deleteCheckIn(int checkInTablePrimaryKey) {
checkInTableRepository.deleteCheckIn(checkInTablePrimaryKey);
}
LiveData<List<CheckInRecipientsTable>> getAllCheckInRecipients() {
return allRecipients;
}
public void insertCheckInRecipientsTable(CheckInRecipientsTable checkInRecipientsTable) {
checkInRecipientsTableRepository.insertCheckInRecipientsTable(checkInRecipientsTable);
}
public void deleteCheckInRecipient(int checkInPrimaryKey) {
checkInRecipientsTableRepository.deleteCheckInRecipient(checkInPrimaryKey);
}
public void deleteCheckInRecipientForCheckIn(int checkInPrimaryKey) {
checkInRecipientsTableRepository.deleteCheckInRecipientForCheckIn(checkInPrimaryKey);
}
public void findCheckInRecipient(int checkInPrimaryKey) {
checkInRecipientsTableRepository.findCheckInRecipient(checkInPrimaryKey);
}
LiveData<List<ContactGroupsTable>> getAllContactGroups() {
return allContactGroups;
}
public void insertContactGroupsTable(ContactGroupsTable contactGroupsTable) {
contactGroupsTableRepository.insertContactGroups(contactGroupsTable);
}
public void deleteContactGroups(int contactGroupsTablePrimaryKey) {
contactGroupsTableRepository.deleteContactGroups(contactGroupsTablePrimaryKey);
}
public void findContactGroups(int contactGroupsTablePrimaryKey) {
contactGroupsTableRepository.findContactGroups(contactGroupsTablePrimaryKey);
}
LiveData<List<ContactTable>> getAllContact() {
return allContacts;
}
public void insertContactTable(ContactTable contactTable) {
contactTableRepository.insertContact(contactTable);
}
public void deleteContact(int contactTablePrimaryKey) {
contactTableRepository.deleteContact(contactTablePrimaryKey);
}
public void findContact(int contactTablePrimaryKey) {
contactTableRepository.findContact(contactTablePrimaryKey);
}
}
Whenever I want to start my "NotenActivity", it Shows me this error:
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:209)
at androidx.room.RoomDatabase.query(RoomDatabase.java:237)
at com.example.mykolproject.persistance.dao.NoteDao_Impl.getnAll(NoteDao_Impl.java:121)
at com.example.mykolproject.NoteRepository.<init>(NoteRepository.java:23)
at com.example.mykolproject.NoteViewModel.<init>(NoteViewModel.java:20)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:200)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:135)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:103)
at com.example.mykolproject.NotenActivity.onCreate(NotenActivity.java:130)
at android.app.Activity.performCreate(Activity.java:7458)
at android.app.Activity.performCreate(Activity.java:7448)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
Here are my affected Activitys:
package com.example.mykolproject.persistance.dao;
import android.database.Cursor;
import androidx.room.EntityDeletionOrUpdateAdapter;
import androidx.room.EntityInsertionAdapter;
import androidx.room.RoomDatabase;
import androidx.room.RoomSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteStatement;
import com.example.mykolproject.persistance.entities.Note;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.ArrayList;
import java.util.List;
#SuppressWarnings("unchecked")
public final class NoteDao_Impl implements NoteDao {
private final RoomDatabase __db;
private final EntityInsertionAdapter __insertionAdapterOfNote;
private final EntityDeletionOrUpdateAdapter __deletionAdapterOfNote;
private final EntityDeletionOrUpdateAdapter __updateAdapterOfNote;
public NoteDao_Impl(RoomDatabase __db) {
this.__db = __db;
this.__insertionAdapterOfNote = new EntityInsertionAdapter<Note>(__db) {
#Override
public String createQuery() {
return "INSERT OR ABORT INTO `note_table`(`id`,`titlefach`,`noten`) VALUES (nullif(?, 0),?,?)";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
if (value.titlefach == null) {
stmt.bindNull(2);
} else {
stmt.bindString(2, value.titlefach);
}
if (value.getNoten() == null) {
stmt.bindNull(3);
} else {
stmt.bindString(3, value.getNoten());
}
}
};
this.__deletionAdapterOfNote = new EntityDeletionOrUpdateAdapter<Note>(__db) {
#Override
public String createQuery() {
return "DELETE FROM `note_table` WHERE `id` = ?";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
}
};
this.__updateAdapterOfNote = new EntityDeletionOrUpdateAdapter<Note>(__db) {
#Override
public String createQuery() {
return "UPDATE OR ABORT `note_table` SET `id` = ?,`titlefach` = ?,`noten` = ? WHERE `id` = ?";
}
#Override
public void bind(SupportSQLiteStatement stmt, Note value) {
stmt.bindLong(1, value.getId());
if (value.titlefach == null) {
stmt.bindNull(2);
} else {
stmt.bindString(2, value.titlefach);
}
if (value.getNoten() == null) {
stmt.bindNull(3);
} else {
stmt.bindString(3, value.getNoten());
}
stmt.bindLong(4, value.getId());
}
};
}
#Override
public void insert(Note note) {
__db.beginTransaction();
try {
__insertionAdapterOfNote.insert(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public void delete(Note note) {
__db.beginTransaction();
try {
__deletionAdapterOfNote.handle(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public void update(Note note) {
__db.beginTransaction();
try {
__updateAdapterOfNote.handle(note);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
#Override
public List<Note> getnAll() {
final String _sql = "SELECT * FROM note_table";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
final Cursor _cursor = __db.query(_statement);
try {
final int _cursorIndexOfId = _cursor.getColumnIndexOrThrow("id");
final int _cursorIndexOfTitlefach = _cursor.getColumnIndexOrThrow("titlefach");
final int _cursorIndexOfNoten = _cursor.getColumnIndexOrThrow("noten");
final List<Note> _result = new ArrayList<Note>(_cursor.getCount());
while(_cursor.moveToNext()) {
final Note _item;
final String _tmpTitlefach;
_tmpTitlefach = _cursor.getString(_cursorIndexOfTitlefach);
final String _tmpNoten;
_tmpNoten = _cursor.getString(_cursorIndexOfNoten);
_item = new Note(_tmpTitlefach,_tmpNoten);
final int _tmpId;
_tmpId = _cursor.getInt(_cursorIndexOfId);
_item.setId(_tmpId);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
_statement.release();
}
}
}
package com.example.mykolproject;
import android.app.Application;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import com.example.mykolproject.persistance.dao.NoteDao;
import com.example.mykolproject.persistance.entities.AppDatabase;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NoteRepository {
private NoteDao notenDao;
private LiveData<List<Note>> allNoten;
public NoteRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
notenDao = database.NoteDao();
allNoten = (LiveData<List<Note>>) notenDao.getnAll();
}
public void insert(LiveData<List<Note>> note) {
new InsertNoteAsyncTask(notenDao).execute((Runnable) note);
}
public void update(LiveData<List<Note>> note) {
new UpdateNoteAsyncTask(notenDao).execute((Runnable) note);
}
public void delete(LiveData<List<Note>> note) {
new DeleteNoteAsyncTask(notenDao).execute((Runnable) note);
}
public LiveData<List<Note>> getAllNoten() {
return getAllNoten();
}
private static class InsertNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private InsertNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.insert(noten[0]);
return null;
}
}
private static class UpdateNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private UpdateNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.update(noten[0]);
return null;
}
}
private static class DeleteNoteAsyncTask extends AsyncTask<Note, Void, Void> {
private NoteDao noteDao;
private DeleteNoteAsyncTask(NoteDao noteDao) {
this.noteDao = noteDao;
}
#Override
protected Void doInBackground(Note... noten) {
noteDao.delete(noten[0]);
return null;
}
}
}
package com.example.mykolproject;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NoteViewModel extends AndroidViewModel {
private NoteRepository repository;
private LiveData<List<Note>> allNoten;
public NoteViewModel(#NonNull Application application) {
super(application);
repository = new NoteRepository(application);
allNoten = repository.getAllNoten();
}
public void insert(Note note) {
repository.insert(allNoten);
}
public void update(Note note) {
repository.update(allNoten);
}
public void delete(Note note) {
repository.delete(allNoten);
}
public LiveData<List<Note>> getAllNotes() {
return allNoten;
}
}
package com.example.mykolproject;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.mykolproject.persistance.entities.Note;
import java.util.List;
public class NotenActivity extends AppCompatActivity {
public String TAG = "NotenActivity";
public static final String NOTEN_MESSAGE = "com.example.MyOLProject.NOTEN";
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
public static final int ADD_NOTE_REQUEST = 1;
public static final int EDIT_NOTE_REQUEST = 2;
private NoteViewModel noteViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_noten);
// final EditText editFach = findViewById(R.id.edit_fach);
recyclerView = (RecyclerView) findViewById(R.id.notenList);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
Button btnAddNoten = findViewById(R.id.btn_addNote);
btnAddNoten.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG, "onClick: AddNoten");
startAddNoten();
}
});
ImageButton btnFach = findViewById(R.id.ibFach);
btnFach.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Fach");
startFach();
}
});
ImageButton btnHome = findViewById(R.id.ibHome);
btnHome.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Home");
startHome();
}
});
ImageButton btnHausaufgaben = findViewById(R.id.ibHausaufgaben);
btnHausaufgaben.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Hausaufgaben");
startHausaufgaben();
}
});
ImageButton btnKalender = findViewById(R.id.ibInfo);
btnKalender.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.i(TAG,"onClick: Kalender");
startKalender();
}
});
Button buttonAddNote = findViewById(R.id.btn_addNote);
buttonAddNote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(NotenActivity.this, AddEditNoteActivity.class);
startActivityForResult(intent, ADD_NOTE_REQUEST);
}
});
RecyclerView recyclerView = findViewById(R.id.notenList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final NotenListAdapter adapter = new NotenListAdapter();
recyclerView.setAdapter(adapter);
noteViewModel = ViewModelProviders.of(this).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>() {
#Override
public void onChanged(#Nullable List<Note> noten) {
adapter.setNotes(noten);
}
});
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
noteViewModel.delete(adapter.getNoteAt(viewHolder.getAdapterPosition()));
Toast.makeText(NotenActivity.this, "Note deleted", Toast.LENGTH_SHORT).show();
}
}).attachToRecyclerView(recyclerView);
adapter.setOnItemClickListener(new NotenListAdapter.OnItemClickListener() {
#Override
public void onItemClick(Note note) {
Intent intent = new Intent(NotenActivity.this, AddEditNoteActivity.class);
intent.putExtra(AddEditNoteActivity.EXTRA_ID, note.getId());
intent.putExtra(AddEditNoteActivity.EXTRA_TITLE, note.getTitleFach());
intent.putExtra(AddEditNoteActivity.EXTRA_DESCRIPTION, note.getNoten());
startActivityForResult(intent, EDIT_NOTE_REQUEST);
}
});
}
private void startAddNoten(){
Intent addNotenIntent = new Intent(this,AddNotenActivity.class);
startActivity(addNotenIntent);
}
private void startFach(){
Intent fachIntent = new Intent(this,FachActivity.class);
startActivity(fachIntent);
}
private void startHome(){
Intent homeIntent = new Intent(this,MainActivity.class);
startActivity(homeIntent);
}
private void startHausaufgaben(){
Intent hausaufgabenIntent = new Intent(this,HausaufgabenActivity.class);
startActivity(hausaufgabenIntent);
}
private void startKalender(){
Intent kalenderIntent = new Intent(this,InfoActivity.class);
startActivity(kalenderIntent);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_NOTE_REQUEST && resultCode == RESULT_OK) {
String title = data.getStringExtra(AddEditNoteActivity.EXTRA_TITLE);
String description = data.getStringExtra(AddEditNoteActivity.EXTRA_DESCRIPTION);
Note note = new Note(title, description);
noteViewModel.insert(note);
Toast.makeText(this, "Note saved", Toast.LENGTH_SHORT).show();
} else if (requestCode == EDIT_NOTE_REQUEST && resultCode == RESULT_OK) {
int id = data.getIntExtra(AddEditNoteActivity.EXTRA_ID, -1);
if (id == -1) {
Toast.makeText(this, "Note can't be updated", Toast.LENGTH_SHORT).show();
return;
}
String title = data.getStringExtra(AddEditNoteActivity.EXTRA_TITLE);
String description = data.getStringExtra(AddEditNoteActivity.EXTRA_DESCRIPTION);
Note note = new Note(title, description);
note.setId(id);
noteViewModel.update(note);
Toast.makeText(this, "Note updated", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Note not saved", Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu, menu);
return true;
}
/* #Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_all_notes:
noteViewModel.deleteAllNotes();
Toast.makeText(this, "All notes deleted", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}*/
}
If you Need any other activities just let me know. My "NotenActivity" is like my MainActivity.
Thank you very much !
Try using some RxJava, that can probably help you out.
But since you're using Room, LiveData, and ViewModel you can probably try using this AppExecutor class. This usually helps me out when I'm doing Database and Network operations.
Also be careful when running on the UI/Main Thread, for Database operations with lots of data its always best practice to do it on a separate thread.
import android.os.Looper;
import android.support.annotation.NonNull;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class AppExecutors {
private static final Object LOCK = new Object();
private static AppExecutors sInstance;
private final Executor diskIO;
private final Executor mainThread;
private final Executor networkIO;
private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
this.diskIO = diskIO;
this.networkIO = networkIO;
this.mainThread = mainThread;
}
public static AppExecutors getInstance() {
if (sInstance == null) {
synchronized (LOCK) {
sInstance = new AppExecutors(Executors.newSingleThreadExecutor(),
Executors.newFixedThreadPool(3),
new MainThreadExecutor());
}
}
return sInstance;
}
public Executor diskIO() {
return diskIO;
}
public Executor mainThread() {
return mainThread;
}
public Executor networkIO() {
return networkIO;
}
private static class MainThreadExecutor implements Executor {
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
#Override
public void execute(#NonNull Runnable command) {
mainThreadHandler.post(command);
}
}
}
//Then you can do something like this.
```AppExecutors.getInstance().getDiskIO.execute(()->database.NoteDao().getnAll());```
Maybe you could look on widely accepted solution of this problem, it could bring you to solution of your problem too...
The error tells me to cast this Call > arrayListCall= RetrofitBuilder.getRecipes();
but i cast it but still is wrong.My goal is to create a widget with the arraylist of ingredients for the selected recipe in the main. The error message shows:
Unable to start receiver com.example.mac.francosbakingapp.Widget.BankingAppWidgetProvider: java.lang.ClassCastException: $Proxy0 cannot be cast to retrofit2.Call
package com.example.mac.francosbakingapp.Widget;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
import com.example.mac.francosbakingapp.MainActivity;
import com.example.mac.francosbakingapp.Model.Ingredient;
import com.example.mac.francosbakingapp.Model.Recipe;
import com.example.mac.francosbakingapp.R;
import com.example.mac.francosbakingapp.RetrofitBuilder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Response;
public class RecipeIngredientsWidgetService extends RemoteViewsService{
#Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return (new ListViewFactory(this.getApplicationContext()) );
}
class ListViewFactory implements RemoteViewsService.RemoteViewsFactory{
private ArrayList<Ingredient> mIngredientsList;
private Context context;
public ListViewFactory( Context context) {
this.context = context;
}
#Override
public void onCreate() {
}
#Override
public void onDataSetChanged() {
loadData();
}
private void loadData() {
Call <ArrayList<Recipe>> arrayListCall= RetrofitBuilder.getRecipes();
try{
Response<ArrayList<Recipe>> arrayListResponse=arrayListCall.execute();
if (arrayListResponse!=null){
SharedPreferences sharedPreferences= PreferenceManager.getDefaultSharedPreferences(context);
int position=sharedPreferences.getInt(MainActivity.POSITION_KEY,0);
Recipe recipe= arrayListResponse.body().get(position);
mIngredientsList= (ArrayList<Ingredient>) recipe.getIngredients();
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
if(mIngredientsList !=null){
mIngredientsList=null;
}
}
#Override
public int getCount() {
return mIngredientsList==null ? 0: mIngredientsList.size();
}
#Override
public RemoteViews getViewAt(int position) {
Ingredient actIngredient=mIngredientsList.get(position);
RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.ingredient_list_item_widget_layout);
String ingredientName= actIngredient.getIngredient();
double ingredientQuantity=actIngredient.getQuantity();
String ingredientMeasure=actIngredient.getMeasure();
String ingredientString=String.format("${title}",ingredientName,ingredientQuantity,ingredientMeasure);
remoteViews.setTextViewText(R.id.tv_widget_population,ingredientString);
return remoteViews;
}
#Override
public RemoteViews getLoadingView() {
return null;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public boolean hasStableIds() {
return true;
}
}
}
Blockquote
The getRecipes
public static RecipesInterface getRecipes(){
interfaceRecipes= new Retrofit.Builder()
.baseUrl("http://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/")
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))
.build().create(RecipesInterface.class);
return interfaceRecipes;
}
Shows the error in the code
The problem i have is in the cast of;
Call > arrayListCall= RetrofitBuilder.getRecipes();
Complete project on :
https://github.com/franquicidad/FrancosBakingApp
Remote Service
I'm doing a test for Android remote Service.
In the first app module, I make a service, complete as below:
AppService
package com.hqyj.dev.aidltest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class AppService extends Service {
public AppService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return new IAppServiceRemoteBinder.Stub() {
#Override
public void basicTypes(
int anInt, long aLong,
boolean aBoolean, float aFloat,
double aDouble, String aString)
throws RemoteException {
}
#Override
public void setData(String data)
throws RemoteException {
setRealData(data);
}
#Override
public void registerCallback(IRemoteServiceCallback cb)
throws RemoteException {
AppService.this.callback = cb;
}
#Override
public void unregisterCallback(IRemoteServiceCallback cb)
throws RemoteException {
AppService.this.callback = null;
}
};
}
private IRemoteServiceCallback callback;
#Override
public void onCreate() {
super.onCreate();
System.out.println("Service started");
}
#Override
public void onDestroy() {
super.onDestroy();
System.out.println("Service stop");
}
public void setRealData(String data) {
this.data = data;
System.out.println("data = " + data);
try {
Thread.sleep(1000);
if (callback != null) {
callback.vlueChanged(data);
}
} catch (InterruptedException | RemoteException e) {
e.printStackTrace();
}
}
private String data = "default date";
}
And their are two AIDL files:
IAppServiceRemoteBinder.aild
// IAppServiceRemoteBinder.aidl
package com.hqyj.dev.aidltest;
// Declare any non-default types here with import statements
import com.hqyj.dev.aidltest.IRemoteServiceCallback;
interface IAppServiceRemoteBinder {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt,
long aLong,
boolean aBoolean, float aFloat,
double aDouble, String aString);
void setData(String data);
void registerCallback(IRemoteServiceCallback cb);
void unregisterCallback(IRemoteServiceCallback cb);
}
IRemoteServiceCallback.aild
// IRemoteServiceCallback.aidl
package com.hqyj.dev.aidltest;
// Declare any non-default types here with import statements
interface IRemoteServiceCallback {
/**
* return from server
*/
void vlueChanged(String value);
}
And in AndroidManifest.xml, this Server decleared as below:
AndroidManifest.xml
<service
android:name="com.hqyj.dev.aidltest.AppService"
android:enabled="true"
android:exported="true"
android:process=":remote">
</service>
And then, the in second module, copies all these aidl files with package name, as below:
And in MainActivity in anotherapp, complete as below:
package com.hqyj.dev.anotherapp;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.hqyj.dev.aidltest.IAppServiceRemoteBinder;
import com.hqyj.dev.aidltest.IRemoteServiceCallback;
public class MainActivity extends AppCompatActivity
implements View.OnClickListener, ServiceConnection {
private final String TAG = MainActivity.class.getSimpleName();
private Intent intent;
private IAppServiceRemoteBinder binder;
private int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_start).setOnClickListener(this);
findViewById(R.id.btn_stop).setOnClickListener(this);
findViewById(R.id.btn_set).setOnClickListener(this);
intent = new Intent();
intent.setComponent(new
ComponentName("com.hqyj.dev.aidltest",
"com.hqyj.dev.aidltest.AppService"));
}
#SuppressLint("DefaultLocale")
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
bindService(intent, this,
Context.BIND_AUTO_CREATE);
break;
case R.id.btn_set:
if (binder != null) {
try {
binder.setData(
String.format("the %d times",
++count));
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
case R.id.btn_stop:
try {
binder.unregisterCallback(callback);
} catch (RemoteException e) {
e.printStackTrace();
}
unbindService(this);
break;
}
}
#Override
public void onServiceConnected(
ComponentName name, IBinder service) {
binder =
IAppServiceRemoteBinder.Stub.asInterface(service);
Log.d(TAG, "onServiceConnected: " + 1);
try {
binder.registerCallback(callback);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
private IRemoteServiceCallback.Stub callback =
new IRemoteServiceCallback.Stub() {
#Override
public void
vlueChanged(String value) throws RemoteException {
Log.e(TAG, "vlueChanged: " + value);
}
};
}
As you see, I called the remote service by using bindService();
It works well, when I push these two apps into an emulator which using Android 7.0 as platform.
But
When I push these app into an real device(using Android 6.0), the flowing mistake happened:
AIDL failed!!
Why??