I am working on mediaplayer app, but i have problem with onDestroy methods, i need to continue with playing music when i minimalize the app. But when i do it stops playing and throws errors or when i comment it, it is playing in background but problem is that it doesnt stop even when i kill the app, i can controll it just with my notification controller, but when i destroy controller by swiping, it is playing and i have music in background without music player.
public class MainActivity extends AppCompatActivity {
private MediaPlayerService player;
private boolean serviceBound = false;
private ArrayList<Audio> audioList;
private RWAdapter rwa;
private RecyclerView rv;
public static final String Broadcast_PLAY_NEW_AUDIO = "com.example.rsabo.mp3player.PlayNewAudio";
public static final String Broadcast_PAUSE_AUDIO= "com.example.rsabo.mp3player.PauseAudio";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
}
loadAudio();
initRW();
}
private void initRW(){
if (audioList.size()>0) {
rv = (RecyclerView) findViewById(R.id.myRecyclerView);
rv.setLayoutManager(new LinearLayoutManager(this));
;
rwa = new RWAdapter(audioList, getApplicationContext());
rv.setAdapter(rwa);
rv.addOnItemTouchListener(new MyTouchListener(this, new onItemClickListener() {
#Override
public void onClick(View view, int index) {
playAudio(index);
}
}));
}
}
//ulozi sa instancia
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("ServiceState", serviceBound);
}
//obnovi sa instancia tam kde bola naposledy ulozena
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
serviceBound = savedInstanceState.getBoolean("ServiceState");
}
//znici instanciu
#Override
protected void onDestroy() {
super.onDestroy();
// if(serviceBound){
// unbindService(serviceConnection);
// player.stopSelf();
// }
}
//viaze tuto triedu s prehravacom, nastavi hodnotu serviceBound na true ked sa vytvori spojenie
private ServiceConnection serviceConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MediaPlayerService.LocalBinder binder = (MediaPlayerService.LocalBinder) service;
player = binder.getService();
serviceBound = true;
Toast.makeText(MainActivity.this, "Service bound", Toast.LENGTH_SHORT).show();
}
#Override
public void onServiceDisconnected(ComponentName name) {
serviceBound = false;
}
};
//Metoda pozrie ci je sluzba aktivna,
//ak nie je, do uloziska hodi arraylist s pesnickami, a spusti sluzbu
//ak je vlozi do uloziska novy audioIndex a posle spravu ze ma spustit pesnicku
private void playAudio(int audioIndex){
if(!serviceBound){
Ulozisko ulozisko = new Ulozisko(getApplicationContext());
ulozisko.storeAudio(audioList);
ulozisko.storeAudioIndex(audioIndex);
Intent playerIntent = new Intent(this, MediaPlayerService.class);
startService(playerIntent);
bindService(playerIntent, serviceConnection, Context.BIND_AUTO_CREATE);
} else {
Ulozisko ulozisko = new Ulozisko(getApplicationContext());
ulozisko.storeAudioIndex(audioIndex);
Intent broadcastIntent = new Intent(Broadcast_PLAY_NEW_AUDIO);
sendBroadcast(broadcastIntent);
}
}
private void pauseAudio(){
Intent broadcastIntent = new Intent(Broadcast_PAUSE_AUDIO);
sendBroadcast(broadcastIntent);
}
//nacita pesnicky z mobilu
private void loadAudio() {
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);
if(cursor != null && cursor.getCount() > 0) {
audioList = new ArrayList<>();
while (cursor.moveToNext()){
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
audioList.add(new Audio(data, title, album, artist));
}
}
cursor.close();
}
}
MediaPlayerService
public class MediaPlayerService extends Service implements MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnInfoListener, MediaPlayer.OnBufferingUpdateListener,
AudioManager.OnAudioFocusChangeListener {
private static final int NOTIFICATION_ID = 101;
private MediaSessionManager mediaSessionManager;
private MediaSessionCompat mediaSession;
private MediaControllerCompat.TransportControls transportControls;
private MediaPlayer mediaPlayer;
private String mediaFile;
private int resumePosition;
private AudioManager audioManager;
private boolean hovor = false;
private PhoneStateListener phoneStateListener;
private TelephonyManager telephonyManager;
private ArrayList<Audio> audioList;
private int audioIndex = -1;
private Audio activeAudio;
private final IBinder iBinder = new LocalBinder();
private PlayStatus status;
public static final String ACTION_PLAY = "com.example.rsabo.mp3player.ACTION_PLAY";
public static final String ACTION_PAUSE = "com.example.rsabo.mp3player.ACTION_PAUSE";
public static final String ACTION_PREVIOUS = "com.example.rsabo.mp3player.ACTION_PREVIOUS";
public static final String ACTION_NEXT = "com.example.rsabo.mp3player.ACTION_NEXT";
public static final String ACTION_STOP = "com.example.rsabo.mp3player.ACTION_STOP";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return iBinder;
}
//pri vytvoreni zavola metody callStateListener(),registerJeNahlasReciever(), registerPlayNewAudio()
#Override
public void onCreate() {
super.onCreate();
callStateListener();
registerJeNahlasReciever();
registerPlayNewAudio();
}
//podla priority zvuku v systeme zvysi zvuk, ukonci, zastavi alebo stisi mediaPlayer
#Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
if (mediaPlayer == null) initMediaPlayer();
else if (!mediaPlayer.isPlaying()) mediaPlayer.start();
mediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
if (mediaPlayer.isPlaying()) mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
if (mediaPlayer.isPlaying()) mediaPlayer.pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
if (mediaPlayer.isPlaying()) mediaPlayer.setVolume(0.1f, 0.1f);
break;
}
}
//metoda na ziskanie AudioFocusu/priority hrania zvuku
private boolean requestAudioFocus() {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
}
//metoda ktora odstrani audioFocus
private boolean removeAudioFocus() {
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED == audioManager.abandonAudioFocus(this);
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
#Override
public void onCompletion(MediaPlayer mp) {
skipToNext();
buildNotification(PlayStatus.PLAYING);
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.d("Media Player error", "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK" + extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.d("Media Player error", "MEDIA_ERROR_SERVER_DIED" + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.d("Media Player error", "MEDIA_ERROR_UNKNOWN" + extra);
break;
}
return false;
}
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
#Override
public void onSeekComplete(MediaPlayer mp) {
}
class LocalBinder extends Binder {
MediaPlayerService getService() {
return MediaPlayerService.this;
}
}
//inicializacia mediaPlayeru, ak sa nenastavi cesta vyhodi chybu a zastavi sa
private void initMediaPlayer() {
if (mediaPlayer == null)
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnSeekCompleteListener(this);
mediaPlayer.setOnInfoListener(this);
mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
// nastavi cestu k hudbe
mediaPlayer.setDataSource(activeAudio.getData());
} catch (IOException e) {
e.printStackTrace();
stopSelf();
}
mediaPlayer.prepareAsync();
}
//nastavenie funkcie tlacidla play
private void playMedia() {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
}
//nastavenie funkcie tlacidla stop
private void stopMedia() {
if (mediaPlayer == null) return;
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
}
//nastavenie funkcie tlacidla pause
private void pauseMedia() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
resumePosition = mediaPlayer.getCurrentPosition();
}
}
//nastavenie funkcie tlacidla resume
private void resumeMedia() {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(resumePosition);
mediaPlayer.start();
}
}
//inicializuje prhravac, ak neziska audiofocus alebo cestu k hudbe zastavi sa
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
Ulozisko ulozisko = new Ulozisko(getApplicationContext());
audioList = ulozisko.loadAudio();
audioIndex = ulozisko.loadAudioIndex();
if (audioIndex != -1 && audioIndex < audioList.size()) {
activeAudio = audioList.get(audioIndex);
} else {
stopSelf();
}
} catch (NullPointerException e) {
stopSelf();
}
if (!requestAudioFocus()) {
stopSelf();
}
if (mediaSessionManager == null) {
try {
initMediaSession();
initMediaPlayer();
} catch (RemoteException e) {
e.printStackTrace();
stopSelf();
}
buildNotification(PlayStatus.PLAYING);
}
handleIncomingActions(intent);
return super.onStartCommand(intent, flags, startId);
}
//metode prida zrusenie audiofocusu a nastavi prehravac na null, vypne phoneStateListener, odregistruje recievre, zmaze notifikaciu a vycisti playlist
#Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
stopMedia();
mediaPlayer.release();
}
removeAudioFocus();
if (phoneStateListener != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
removeNotification();
unregisterReceiver(jeNahlasReciever);
unregisterReceiver(playNewAudio);
new Ulozisko(getApplicationContext()).clearCacheAudioPlaylist();
}
//ked sa vyberu sluchadla tak sa hranie zastavi
private BroadcastReceiver jeNahlasReciever = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
pauseMedia();
buildNotification(PlayStatus.PAUSED);
}
};
private void registerJeNahlasReciever() {
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
registerReceiver(jeNahlasReciever, intentFilter);
}
//metoda ktora zisiti v akom stave je hovor, a ked telefon zvoni alebo prebieha hovor, zastavi prehravanie
private void callStateListener() {
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
if (mediaPlayer != null) {
pauseMedia();
hovor = true;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if (mediaPlayer != null) {
if (hovor) {
hovor = false;
resumeMedia();
}
}
break;
}
}
};
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
//ked prepnem pesnicku tak sa pomocou tejto metody resetne prehravac a prepne na dalsiu pesnicku podla indexu ktory dostala v sprave
private BroadcastReceiver playNewAudio = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// if(status == PlayStatus.PAUSED) {
audioIndex = new Ulozisko(getApplicationContext()).loadAudioIndex();
if (audioIndex != -1 && audioIndex < audioList.size()) {
activeAudio = audioList.get(audioIndex);
} else {
stopSelf();
}
stopMedia();
mediaPlayer.reset();
initMediaPlayer();
updateInfo();
buildNotification(PlayStatus.PLAYING);
// } else if (status == PlayStatus.PLAYING){
// pauseMedia();
// updateInfo();
// buildNotification(PlayStatus.PAUSED);
// }
}
};
private void registerPlayNewAudio() {
IntentFilter filter = new IntentFilter(MainActivity.Broadcast_PLAY_NEW_AUDIO);
registerReceiver(playNewAudio, filter);
}
//skontroluje ci mediaSessionManager existuje
//vytvori mediaSession a da mu controller
private void initMediaSession() throws RemoteException {
if (mediaSessionManager != null) return;
mediaSessionManager = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
mediaSession = new MediaSessionCompat(getApplicationContext(), "Prehravac");
transportControls = mediaSession.getController().getTransportControls();
mediaSession.setActive(true);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
updateInfo();
mediaSession.setCallback(new MediaSessionCompat.Callback() {
#Override
public void onPlay() {
super.onPlay();
resumeMedia();
buildNotification(PlayStatus.PLAYING);
}
#Override
public void onPause() {
super.onPause();
pauseMedia();
buildNotification(PlayStatus.PAUSED);
}
#Override
public void onSkipToNext() {
super.onSkipToNext();
skipToNext();
updateInfo();
buildNotification(PlayStatus.PLAYING);
}
#Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
skipToPrevious();
updateInfo();
buildNotification(PlayStatus.PLAYING);
}
#Override
public void onStop() {
super.onStop();
removeNotification();
stopSelf();
}
#Override
public void onSeekTo(long pos) {
super.onSeekTo(pos);
}
});
}
//updatne aktualne info o pesnicke
private void updateInfo() {
Bitmap albumArt = BitmapFactory.decodeResource(getResources(), R.drawable.image);
mediaSession.setMetadata(new MediaMetadataCompat.Builder()
//.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, activeAudio.getArtist())
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, activeAudio.getAlbum())
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, activeAudio.getTitle())
.build());
}
//metoda ktora prepne pesnicku na dalsiu, ak je pesnicka posledna tak ju nastavi na prvu v zozname
private void skipToNext() {
if (audioIndex == audioList.size() - 1) {
audioIndex = 0;
activeAudio = audioList.get(audioIndex);
} else {
activeAudio = audioList.get(++audioIndex);
}
new Ulozisko(getApplicationContext()).storeAudioIndex(audioIndex);
stopMedia();
mediaPlayer.reset();
initMediaPlayer();
}
//metoda ktora prepne pesnicku dozadu, ak je na zaciatku zoznamu tak ju nastavi na poslednu
private void skipToPrevious() {
if (audioIndex == 0) {
audioIndex = audioList.size() - 1;
activeAudio = audioList.get(audioIndex);
} else {
activeAudio = audioList.get(--audioIndex);
}
new Ulozisko(getApplicationContext()).storeAudioIndex(audioIndex);
stopMedia();
mediaPlayer.reset();
initMediaPlayer();
}
//metoda ktora spravi v notifikacnom panely prehravac a vzdy ked sa vola tato metoda tak sa v notifikacii updatne info o pesnicke
private void buildNotification(PlayStatus playStatus) {
int notificationAction = android.R.drawable.ic_media_pause;
PendingIntent playAleboPause = null;
if (playStatus == PlayStatus.PLAYING) {
notificationAction = android.R.drawable.ic_media_pause;
playAleboPause = playbackAction(1);
status = PlayStatus.PLAYING;
} else if (playStatus == PlayStatus.PAUSED) {
notificationAction = android.R.drawable.ic_media_play;
playAleboPause = playbackAction(0);
status = PlayStatus.PAUSED;
}
Bitmap albumArt = BitmapFactory.decodeResource(getResources(), R.drawable.image);
NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setShowWhen(false)
.setStyle(new NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.getSessionToken())
.setShowActionsInCompactView(0, 1, 2))
.setColor(getResources().getColor(R.color.colorPrimary))
//.setLargeIcon(activeAudio.)
.setSmallIcon(android.R.drawable.stat_sys_headset)
.setContentText(activeAudio.getArtist())
.setContentTitle(activeAudio.getTitle())
.setSubText(activeAudio.getAlbum())
.addAction(android.R.drawable.ic_media_previous, "previous", playbackAction(3))
.addAction(notificationAction, "pause", playAleboPause)
.addAction(ic_media_next, "next", playbackAction(2));
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, notificationBuilder.build());
}
//zmaze notifikaciu
private void removeNotification() {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFICATION_ID);
}
// nastavenie akcie na tlacidla v notifikacii
private PendingIntent playbackAction(int cisloAkcie) {
Intent akcia = new Intent(this, MediaPlayerService.class);
switch (cisloAkcie) {
case 0:
akcia.setAction(ACTION_PLAY);
return PendingIntent.getService(this, cisloAkcie, akcia, 0);
case 1:
akcia.setAction(ACTION_PAUSE);
return PendingIntent.getService(this, cisloAkcie, akcia, 0);
case 2:
akcia.setAction(ACTION_NEXT);
return PendingIntent.getService(this, cisloAkcie, akcia, 0);
case 3:
akcia.setAction(ACTION_PREVIOUS);
return PendingIntent.getService(this, cisloAkcie, akcia, 0);
default:
break;
}
return null;
}
//metoda zisti ktora akcia je aktualna a zavola metodu cez transportControls
private void handleIncomingActions(Intent playbackAction) {
if (playbackAction == null || playbackAction.getAction() == null) return;
String akcia = playbackAction.getAction();
if (akcia.equalsIgnoreCase(ACTION_PLAY)) {
transportControls.play();
} else if (akcia.equalsIgnoreCase(ACTION_PAUSE)) {
transportControls.pause();
} else if (akcia.equalsIgnoreCase(ACTION_NEXT)) {
transportControls.skipToNext();
} else if (akcia.equalsIgnoreCase(ACTION_PREVIOUS)) {
transportControls.skipToPrevious();
} else if (akcia.equalsIgnoreCase(ACTION_STOP)) {
transportControls.stop();
}
}
}
Try this to startForeground()
Notification.Builder mBuilder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_icon)
.setContentTitle(getString(R.string.title))
.setContentText("");
Intent resultIntent = new Intent(this, ResultIntent.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ParentStack.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int mId = 1489;
startForeground(mId, mBuilder.build());
Related
When the app is in the foreground can get calls well, but when is in the background and a call is active and the run app: it can not get that's call.
When the app is in the foreground, get call works well (get push-notification and connecting is being automatically, also you can push "Incoming Call" notification to connecting call).
I fixed it in swift but I cant fix it for android.
ios fixed with this funcs:
func applicationDidEnterBackground(_ application: UIApplication) {
if !isCallScreen {
UIApplication.shared.unregisterForRemoteNotifications()
}
}
func funBack() {
let state = UIApplication.shared.applicationState
if state == .background {
UIApplication.shared.unregisterForRemoteNotifications()
}
if isCallScreen {
isCallScreen = false
DispatchQueue.main.async {
self.window?.rootViewController?.navigationController?.popViewController(animated: true)
}
}
}
Messaging service
public class MessagingService extends FirebaseMessagingService {
private int notificationNumber = 1;
private LocalBroadcastManager broadcaster;
private int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
private DatabaseReference mDatabase;
private SinchClient sinchClient;
private SharedPref pref;
public static boolean firsttimeFun = true;
#Override
public void onCreate() {
broadcaster = LocalBroadcastManager.getInstance(this);
pref = new SharedPref(this);
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//
if (SinchHelpers.isSinchPushPayload(remoteMessage.getData())) {
NotificationResult result = sinchClient.relayRemotePushNotificationPayload(
remoteMessage.getData());
}
if (!AppLifecycleListener.isActivityVisible()) {
AppLifecycleListener.activityResumed();
}
// it's NOT Sinch message - process yourself
class FcmListenerService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage){
Map data = remoteMessage.getData();
if (SinchHelpers.isSinchPushPayload(data)) {
new ServiceConnection() {
private Map payload;
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (sinchClient != null) {
NotificationResult result = sinchClient.relayRemotePushNotificationPayload(payload);
// handle result, e.g. show a notification or similar
}
}
#Override
public void onServiceDisconnected(ComponentName name) {}
public void relayMessageData(Map<String, String> data) {
payload = data;
getApplicationContext().bindService(new Intent(getApplicationContext(), CallActivity.class), this, BIND_AUTO_CREATE);
}
}.relayMessageData(data);
}
}
}
// String bundleString = remoteMessage.getNotification().getBody();
//
// String bundleString = remoteMessage.getData().get("message");
Map bundle = remoteMessage.getData();
String callId = bundle.get("callID").toString();
String groupname = bundle.get("group").toString();
try {
bundle.get("hangup").toString();
Intent intent = new Intent("MyData");
intent.putExtra("callID", callId);
broadcaster.sendBroadcast(intent);
return;
} catch (Exception e) {
e.printStackTrace();
}
//IF app is in background use return for ignore notifications
if (!AppLifecycleListener.isActivityVisible()) {
sendNotification(callId, groupname);
//return;
}
Log.i("MessageFrom", "From: " + callId);
if (firsttimeFun) {
firsttimeFun = false;
startActivity(new Intent(this, CallActivity.class).putExtra("callerId", callId).putExtra("name", groupname).putExtra("isOutGoing", false).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
if (AppLifecycleListener.isActivityVisible())
sendNotification(callId, groupname);
//return;
// sendNotification(bundle.get("message").toString());
}
#Override
public void onNewToken(String s) {
/* HashMap map=new HashMap();
map.put("fcmToken",s);
mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("Users").child(pref.getUserId()).updateChildren(map);*/
}
#RequiresApi(api = Build.VERSION_CODES.N)
private void sendNotification(String callId, String groupname) {
PendingIntent contentIntent;
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, CallActivity.class).putExtra("callerId", callId).putExtra("name", groupname).putExtra("isOutGoing", false), 0);
int notifyID = 1;
String CHANNEL_ID = "CallAppChanel";// The id of the channel.
CharSequence name = getString(R.string.channel_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mChannel = new NotificationChannel(CHANNEL_ID, "Channel 1", importance);
}
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.icon)
.setContentTitle("Incoming Call")
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setContentIntent(contentIntent)
.setColor(getResources().getColor(R.color.purple))
.setAutoCancel(true)
.setOnlyAlertOnce(true)
.setChannelId(CHANNEL_ID)
.setPriority(importance)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.build();
int notificationId = new Random().nextInt(100) + 1;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mNotificationManager.createNotificationChannel(mChannel);
mNotificationManager.notify(notificationId, notification);
} else {
mNotificationManager.notify(notificationId, notification);
}
}
}
AppLifecycleListener
public class AppLifecycleListener extends Application implements Application.ActivityLifecycleCallbacks, LifecycleObserver {
private Context context;
Activity activityRunning;
private static Application instance;
private static boolean activityVisible;
private boolean inForeground;
public void setContext(Context context) {
this.context = context;
}
public Context getContext() {
return this.context;
}
public static Context getContextApp() {
return instance.getApplicationContext();
}
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
/*getVersionRequest(this);*/
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
activityRunning = activity;
}
#Override
public void onActivityStarted(#NonNull Activity activity) {
}
#Override
public void onActivityResumed(Activity activity) {
// Utility.logCatMsg("Activity Resume : " + activity.getLocalClassName());
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener((Activity) context, new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
Log.e("newToken",newToken);
}
});
}
#Override
public void onActivityPaused(Activity activity) {
// Utility.logCatMsg("Activity Pause : " + activity.getLocalClassName());
}
#Override
public void onActivityStopped(Activity activity) {
// Utility.logCatMsg("Activity Stop : " + activity.getLocalClassName());
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
// Utility.logCatMsg("Activity Destroyed : " + activity.getLocalClassName());
}
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
}
// Camera activity code
public class CamActivity extends AppCompatActivity implements
ActivityCompat.OnRequestPermissionsResultCallback,
AspectRatioFragment.Listener {
public static boolean activityStatus;
private Handler handler = new Handler();
private FirebaseAnalytics mFirebaseAnalytics;
private static final String TAG = "CamActivity";
private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final String FRAGMENT_DIALOG = "dialog";
private static final int SELECT_PICTURE = 1;
private static final int[] FLASH_OPTIONS = {
CameraView.FLASH_AUTO,
CameraView.FLASH_OFF,
CameraView.FLASH_ON,
};
private static final int[] FLASH_ICONS = {
R.drawable.ic_flash_auto,
R.drawable.ic_flash_off,
R.drawable.ic_flash_on,
};
private static final int[] FLASH_TITLES = {
R.string.flash_auto,
R.string.flash_off,
R.string.flash_on,
};
private int mCurrentFlash;
private CameraView mCameraView;
private Handler mBackgroundHandler;
private FloatingActionButton fab;
private ImageView open_gallery;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_picture:
if (mCameraView != null) {
try {
mCameraView.takePicture();
/*handler.postDelayed(() ->
mCameraView.takePicture(),
500);*/
}catch (Exception e){
Log.e(TAG,"mCameraView"+e.toString());
}
}
break;
case R.id.open_gallery:
openGallery();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
Bundle bundle1 = new Bundle();
bundle1.putString(TAG, TAG);
bundle1.putString(TAG, TAG);
mFirebaseAnalytics.logEvent(TAG, bundle1);
setContentView(R.layout.activity_camera_renderer);
mCameraView = findViewById(R.id.camera);
open_gallery = findViewById(R.id.open_gallery);
if (open_gallery!=null)
open_gallery.setOnClickListener(mOnClickListener);
activityStatus = true;
if (mCameraView != null) {
mCameraView.addCallback(mCallback);
}
fab = findViewById(R.id.take_picture);
if (fab != null) {
fab.setOnClickListener(mOnClickListener);
}
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowTitleEnabled(false);
}
//toolbar.setTitle("Camera");
toolbar.setNavigationIcon(R.drawable.ic_back_arrow);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
closeCamera();
}
});
//Listen for capture image and close camera
registerReceiver(syncCamReceiver, new IntentFilter("Camera"));
}
#Override
public void onBackPressed() {
closeCamera();
super.onBackPressed();
}
/**CLose camera**/
private void closeCamera(){
try{
unregisterReceiver(syncCamReceiver);
}
catch (Exception e){
Log.d(TAG,"Error while unregistering");
}
SN88Constant.getIk6Obj(getApplicationContext()).sendPhotoSwitch(false);
CamActivity.this.finish();
}
BroadcastReceiver syncCamReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent intent) {
if (intent.getAction().equalsIgnoreCase("Camera")) {
//0 for open cam, 1 take picture 2 close camera
if(intent.getIntExtra(Constants.CAMERA_REQUEST_TYPE,-1)==1){
fab .performClick();
}
else if(intent.getIntExtra(Constants.CAMERA_REQUEST_TYPE,-1)==2){
CamActivity.this.finish();
}
}
}
};
#Override
protected void onResume() {
activityStatus = true;
try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
if (mCameraView != null)
mCameraView.start();
} else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
ConfirmationDialogFragment
.newInstance(R.string.camera_permission_confirmation,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION,
R.string.camera_permission_not_granted)
.show(getSupportFragmentManager(), FRAGMENT_DIALOG);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION);
}
}catch (Exception e){
Log.d(TAG,"Camera_onresume"+e.toString());
}
super.onResume();
}
#Override
protected void onPause() {
mCameraView.stop();
super.onPause();
}
#Override
protected void onDestroy() {
closeCamera();
activityStatus = false;
if (mBackgroundHandler != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mBackgroundHandler.getLooper().quitSafely();
} else {
mBackgroundHandler.getLooper().quit();
}
mBackgroundHandler = null;
}
super.onDestroy();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CAMERA_PERMISSION:
if (permissions.length != 1 || grantResults.length != 1) {
throw new RuntimeException("Error on requesting camera permission.");
}
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.camera_permission_not_granted,
Toast.LENGTH_SHORT).show();
}
// No need to start camera here; it is handled by onResume
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.aspect_ratio:
FragmentManager fragmentManager = getSupportFragmentManager();
if (mCameraView != null
&& fragmentManager.findFragmentByTag(FRAGMENT_DIALOG) == null) {
final Set<AspectRatio> ratios = mCameraView.getSupportedAspectRatios();
final AspectRatio currentRatio = mCameraView.getAspectRatio();
AspectRatioFragment.newInstance(ratios, currentRatio)
.show(fragmentManager, FRAGMENT_DIALOG);
}
return true;
case R.id.switch_flash:
if (mCameraView != null) {
mCurrentFlash = (mCurrentFlash + 1) % FLASH_OPTIONS.length;
item.setTitle(FLASH_TITLES[mCurrentFlash]);
item.setIcon(FLASH_ICONS[mCurrentFlash]);
mCameraView.setFlash(FLASH_OPTIONS[mCurrentFlash]);
}
return true;
case R.id.switch_camera:
if (mCameraView != null) {
try {
int facing = mCameraView.getFacing();
mCameraView.setFacing(facing == CameraView.FACING_FRONT ?
CameraView.FACING_BACK : CameraView.FACING_FRONT);
}catch (Exception e){
e.printStackTrace();
}
}
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onAspectRatioSelected(#NonNull AspectRatio ratio) {
if (mCameraView != null) {
//Toast.makeText(this, ratio.toString(), Toast.LENGTH_SHORT).show();
try {
mCameraView.setAspectRatio(ratio);
}catch (Exception e){
Log.d(TAG,"onAspectRatioSelected"+e.toString());
}
}
}
private Handler getBackgroundHandler() {
if (mBackgroundHandler == null) {
HandlerThread thread = new HandlerThread("background");
thread.start();
mBackgroundHandler = new Handler(thread.getLooper());
}
return mBackgroundHandler;
}
private CameraView.Callback mCallback
= new CameraView.Callback() {
#Override
public void onCameraOpened(CameraView cameraView) {
Log.d(TAG, "onCameraOpened");
}
#Override
public void onCameraClosed(CameraView cameraView) {
Log.d(TAG, "onCameraClosed");
}
#Override
public void onPictureTaken(CameraView cameraView, final byte[] data) {
Log.d(TAG, "onPictureTaken " + data.length);
Toast.makeText(cameraView.getContext(), R.string.picture_taken, Toast.LENGTH_SHORT)
.show();
getBackgroundHandler().post(new Runnable() {
#Override
public void run() {
String folderPath = Environment.getExternalStorageDirectory() + "/DCIM/Camera";
File folder = new File(folderPath);
if (!folder.exists()) {
File wallpaperDirectory = new File(folderPath);
wallpaperDirectory.mkdir();
}
File file = new File(folderPath,"/Img"+System.currentTimeMillis()+ ".png");
OutputStream os = null;
try {
os = new FileOutputStream(file);
os.write(data);
os.close();
scanFile(file.getAbsolutePath());
} catch (IOException e) {
Log.w(TAG, "Cannot write to " + file, e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Ignore
}
}
}
}
});
}
};
public static class ConfirmationDialogFragment extends DialogFragment {
private static final String ARG_MESSAGE = "message";
private static final String ARG_PERMISSIONS = "permissions";
private static final String ARG_REQUEST_CODE = "request_code";
private static final String ARG_NOT_GRANTED_MESSAGE = "not_granted_message";
public static ConfirmationDialogFragment newInstance(#StringRes int message,
String[] permissions, int requestCode, #StringRes int notGrantedMessage) {
ConfirmationDialogFragment fragment = new ConfirmationDialogFragment();
Bundle args = new Bundle();
args.putInt(ARG_MESSAGE, message);
args.putStringArray(ARG_PERMISSIONS, permissions);
args.putInt(ARG_REQUEST_CODE, requestCode);
args.putInt(ARG_NOT_GRANTED_MESSAGE, notGrantedMessage);
fragment.setArguments(args);
return fragment;
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle args = getArguments();
return new AlertDialog.Builder(getActivity())
.setMessage(args.getInt(ARG_MESSAGE))
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String[] permissions = args.getStringArray(ARG_PERMISSIONS);
if (permissions == null) {
throw new IllegalArgumentException();
}
ActivityCompat.requestPermissions(getActivity(),
permissions, args.getInt(ARG_REQUEST_CODE));
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getActivity(),
args.getInt(ARG_NOT_GRANTED_MESSAGE),
Toast.LENGTH_SHORT).show();
}
})
.create();
}
}
//Scans the saved file so it appears in the gallery
private void scanFile(String path) {
MediaScannerConnection.scanFile(this,
new String[] { path }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("TAG", "Finished scanning " + path);
}
});
}
/*
* open gallery for image preview
* */
private void openGallery(){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
}
}
// Getting error :
E/CamActivity: mCameraViewjava.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.camera2.CaptureRequest$Builder.set(android.hardware.camera2.CaptureRequest$Key, java.lang.Object)' on a null object reference
I hope you are all well. I've been having trouble with creating a notification service.
I have an audio app with recyclerviews and it's adapter class containing the viewholders. From the onBindviewholder I created an onclicklistener method that opens a player activity.
What I would like to happen is when you click on any item of the recyclerview, it starts the audio together with the foreground notification.
Please give your answers in written code as I am a novice in code jargon.
Thanks in advance.
Here's my code :
Player activity
public class Player extends AppCompatActivity implements MediaPlayer.OnCompletionListener {
TextView song_name, duration_played, total_duration;
ImageView nextbtn,prevbtn,shufflebtn,repeatbtn;
SeekBar seekBar;
FloatingActionButton playpausebtn;
Uri uri;
int position=-1;
int finalTime;
private cardhelper currentItem;
static MediaPlayer mMediaplayer;
static List<cardhelper>macam = new ArrayList<>();
private Handler handler = new Handler();
private Thread playThread, prevThread,nextThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
initViews();
getIntentMethod();
song_name.setText(macam.get(position).getSurah());
mMediaplayer.setOnCompletionListener(this);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mMediaplayer!=null && fromUser){
mMediaplayer.seekTo(progress * 1000);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
Player.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mMediaplayer!=null){
int mCurrentposition = mMediaplayer.getCurrentPosition()/1000;
seekBar.setProgress(mCurrentposition);
duration_played.setText(formattedTime(mCurrentposition));
finalTime = mMediaplayer.getDuration()/1000;
total_duration.setText(formattedTime(finalTime));
}
handler.postDelayed(this, 1000);
}
});
shufflebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(shuffleboolean){
shuffleboolean=false;
shufflebtn.setImageResource(R.drawable.ic_shuffle);
}else{
shuffleboolean=true;
shufflebtn.setImageResource(R.drawable.ic_shuffle_on);
}
}
});
repeatbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(repeatBoolean){
repeatBoolean=false;
repeatbtn.setImageResource(R.drawable.ic_repeat);
}else{
repeatBoolean=true;
repeatbtn.setImageResource(R.drawable.ic_repeat_on);
}
}
});
}
#Override
protected void onResume() {
playThreadbtn();
nextThreadbtn();
prevThreadbtn();
super.onResume();
}
private void playThreadbtn() {
playThread= new Thread(){
#Override
public void run() {
super.run();
playpausebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playpausebtnClicked();
}
});
}
};
playThread.start();
}
private void playpausebtnClicked() {
if(mMediaplayer.isPlaying()){
playpausebtn.setImageResource(R.drawable.ic_play);
mMediaplayer.pause();
seekBar.setMax(mMediaplayer.getDuration()/1000);
Player.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mMediaplayer!=null){
int mCurrentposition = mMediaplayer.getCurrentPosition()/1000;
seekBar.setProgress(mCurrentposition);
}
handler.postDelayed(this, 1000);
}
});
}else{
playpausebtn.setImageResource(R.drawable.ic_baseline_pause_24);
mMediaplayer.start();
seekBar.setMax(mMediaplayer.getDuration()/1000);
Player.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mMediaplayer!=null){
int mCurrentposition = mMediaplayer.getCurrentPosition()/1000;
seekBar.setProgress(mCurrentposition);
}
handler.postDelayed(this, 1000);
}
});
}
}
private void nextThreadbtn() {
nextThread= new Thread(){
#Override
public void run() {
super.run();
nextbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
nextbtnClicked();
}
});
}
};
nextThread.start();
}
private void nextbtnClicked() {
if(mMediaplayer.isPlaying()){
mMediaplayer.stop();
mMediaplayer.release();
if(shuffleboolean && !repeatBoolean){
position= getRandom(macam.size() - 1);
}
else if (! shuffleboolean && ! repeatBoolean){
position=((position + 1)% macam.size());
}
//else position will be position..
int cardhelper= macam.get(position).getAudio();
mMediaplayer= MediaPlayer.create(getApplicationContext(), cardhelper);
song_name.setText(macam.get(position).getSurah());
seekBar.setMax(mMediaplayer.getDuration()/1000);
Player.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mMediaplayer!=null){
int mCurrentposition = mMediaplayer.getCurrentPosition()/1000;
seekBar.setProgress(mCurrentposition);
}
handler.postDelayed(this, 1000);
}
});
mMediaplayer.setOnCompletionListener(this);
playpausebtn.setBackgroundResource(R.drawable.ic_baseline_pause_24);
mMediaplayer.start();
}else {
mMediaplayer.stop();
mMediaplayer.release();
if(shuffleboolean && !repeatBoolean){
position= getRandom(macam.size() - 1);
}
else if (! shuffleboolean && ! repeatBoolean){
position=((position + 1)% macam.size());
}
int cardhelper= macam.get(position).getAudio();
mMediaplayer= MediaPlayer.create(getApplicationContext(), cardhelper);
song_name.setText(macam.get(position).getSurah());
seekBar.setMax(mMediaplayer.getDuration()/1000);
Player.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mMediaplayer!=null){
int mCurrentposition = mMediaplayer.getCurrentPosition()/1000;
seekBar.setProgress(mCurrentposition);
}
handler.postDelayed(this, 1000);
}
});
mMediaplayer.setOnCompletionListener(this);
playpausebtn.setBackgroundResource(R.drawable.ic_play);
}
}
private int getRandom(int i) {
Random random = new Random();
return random.nextInt(i+ 1);
}
private void prevThreadbtn() {
prevThread= new Thread(){
#Override
public void run() {
super.run();
prevbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prevbtnClicked();
}
});
}
};
prevThread.start();
}
private void prevbtnClicked() {
if(mMediaplayer.isPlaying()){
mMediaplayer.stop();
mMediaplayer.release();
position=((position-1) < 0 ? (macam.size() -1 ): (position - 1));
int cardhelper= macam.get(position).getAudio();
mMediaplayer= MediaPlayer.create(getApplicationContext(), cardhelper);
song_name.setText(macam.get(position).getSurah());
seekBar.setMax(mMediaplayer.getDuration()/1000);
Player.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mMediaplayer!=null){
int mCurrentposition = mMediaplayer.getCurrentPosition()/1000;
seekBar.setProgress(mCurrentposition);
}
handler.postDelayed(this, 1000);
}
});
mMediaplayer.setOnCompletionListener(this);
playpausebtn.setBackgroundResource(R.drawable.ic_baseline_pause_24);
mMediaplayer.start();
}else {
mMediaplayer.stop();
mMediaplayer.release();
position=((position-1) < 0 ? (macam.size() -1 ): (position - 1));
int cardhelper= macam.get(position).getAudio();
mMediaplayer= MediaPlayer.create(getApplicationContext(), cardhelper);
song_name.setText(macam.get(position).getSurah());
seekBar.setMax(mMediaplayer.getDuration()/1000);
Player.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mMediaplayer!=null){
int mCurrentposition = mMediaplayer.getCurrentPosition()/1000;
seekBar.setProgress(mCurrentposition);
}
handler.postDelayed(this, 1000);
}
});
mMediaplayer.setOnCompletionListener(this);
playpausebtn.setBackgroundResource(R.drawable.ic_play);
}
}
private String formattedTime(int mCurrentposition) {
String totalout = "";
String totalNew = "";
String seconds = String.valueOf(mCurrentposition % 60);
String minutes = String.valueOf(mCurrentposition / 60);
totalout = minutes + ":" + seconds;
totalNew = minutes + ":" + "0" + seconds;
if(seconds.length() == 1){
return totalNew;
}
else {
return totalout;
}
}
private void getIntentMethod() {
position= getIntent().getIntExtra("position",-1);
macam=cardalbums;
macam=malbie;
if(macam!=null ){
playpausebtn.setImageResource(R.drawable.ic_baseline_pause_24);
currentItem = cardalbums.get(position);
currentItem = malbie.get(position);
}
if(mMediaplayer!=null){
mMediaplayer.stop();
mMediaplayer.release();
mMediaplayer= MediaPlayer.create(getApplicationContext(),currentItem.getAudio());
mMediaplayer.start();
}else{
mMediaplayer= MediaPlayer.create(getApplicationContext(),currentItem.getAudio());
mMediaplayer.start();
}
seekBar.setMax(mMediaplayer.getDuration()/ 1000);
}
private void initViews() {
song_name=findViewById(R.id.textTitle);
duration_played=findViewById(R.id.textCurrentTime);
total_duration=findViewById(R.id.textTotalTime);
nextbtn=findViewById(R.id.buttonNext);
prevbtn=findViewById(R.id.buttonPrevious);
shufflebtn=findViewById(R.id.buttonShuffle);
repeatbtn=findViewById(R.id.buttonRepeat);
seekBar=findViewById(R.id.playerSeekbar);
playpausebtn=findViewById(R.id.buttonPlay);
}
#Override
public void onCompletion(MediaPlayer mp) {
nextbtnClicked();
if(mMediaplayer!=null){
int cardhelper= macam.get(position).getAudio();
mMediaplayer= MediaPlayer.create(getApplicationContext(), cardhelper);
mMediaplayer.start();
mMediaplayer.setOnCompletionListener(this);
}
}
}
Fragment Adapter Class
public class musicadapter extends RecyclerView.Adapter<musicadapter.cardViewHolder>implements Filterable {
List<cardhelper> mcardalbums;
List<cardhelper>filteredData;
Filter filter;
int audio;
int position;
Context mcontext;
musicadapter(Context mcontext, List<cardhelper> mcardalbums) {
this.mcardalbums = mcardalbums;
this.mcontext=mcontext;
this.filteredData=mcardalbums;
}
#Override
public cardViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.card_design, parent, false);
cardViewHolder cvh= new cardViewHolder(v);
return cvh;
}
#Override
public void onBindViewHolder(#NonNull cardViewHolder holder, int position) {
cardhelper currentItem = mcardalbums.get(position);
holder.surah.setText(currentItem.getSurah());
holder.count.setText(currentItem.getNumOfSongs());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mcontext, Player.class);
intent.putExtra("position", position);
mcontext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return mcardalbums.size();
}
#Override
public Filter getFilter() {
return new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mcardalbums = (List<cardhelper>) results.values;
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<cardhelper> filteredResults = null;
if (constraint.length() == 0) {
filteredResults = filteredData;
} else {
filteredResults = getFilteredResults(constraint.toString().toLowerCase());
}
FilterResults results = new FilterResults();
results.values = filteredResults;
return results;
}
};
}
protected List<cardhelper> getFilteredResults(String constraint) {
List<cardhelper> results = new ArrayList<>();
for (cardhelper item : filteredData) {
if (item.getSurah().toLowerCase().contains(constraint)) {
results.add(item);
}
}
return results;
}
public static class cardViewHolder extends RecyclerView.ViewHolder {
TextView count,surah;
#SuppressLint("ResourceType")
public cardViewHolder(View itemView) {
super(itemView);
count = itemView.findViewById(R.id.card_count);
surah = itemView.findViewById(R.id.card_surah);
}
}
}
so after a few weeks of research i found out how to this. Please bear in my I'm a novice but this is what i got from my observation:
You don't need a Service Class to create a notification because it can be created anywhere and called from button clicks inside a method. It will obligatorily need a channel, and addAction button to appear:
public void showNotification(int playpausebtn) {
final Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.new_disc);
macam= (ArrayList<cardhelper>) malbie;
macam= (ArrayList<cardhelper>) cardalbums;
if (macam != null) {
currentItem = malbie.get(position);
currentItem = cardalbums.get(position);
}
Intent previousIntent = new Intent(ACTION_PREVIOUS);
previousIntent.setAction(ACTION_PREVIOUS);
PendingIntent ppreviousIntent = PendingIntent.getBroadcast(this, 1, previousIntent, 0);
Intent playIntent = new Intent(ACTION_PLAY);
playIntent.setAction(ACTION_PLAY);
PendingIntent pplayIntent = PendingIntent.getBroadcast(this, 2, playIntent, 0);
Intent nextIntent = new Intent(ACTION_NEXT);
nextIntent.setAction(ACTION_NEXT);
PendingIntent pnextIntent = PendingIntent.getBroadcast(this, 3, nextIntent, 0);
// Create a new MediaSession
final MediaSession mediaSession = new MediaSession(this, "debug tag");
// Update the current metadata
mediaSession.setMetadata(new MediaMetadata.Builder()
.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, icon)
.putString(MediaMetadata.METADATA_KEY_ARTIST, "Pink Floyd")
.putString(MediaMetadata.METADATA_KEY_TITLE, "The Great Gig in the Sky")
.build());
// Indicate you're ready to receive media commands:
Intent intentOpenApp = new Intent(getApplicationContext(), Userxui.class);
PendingIntent pendingIntentOpenApp = PendingIntent.getActivity(getApplicationContext(), 0,
intentOpenApp, 0);
// Create a new Notification
NotificationCompat.Builder noti = new NotificationCompat.Builder(getApplicationContext(), "CHANNEl_ID");
// Hide the timestamp
noti.setShowWhen(false);
noti.setLargeIcon(icon);
noti.setVisibility(androidx.core.app.NotificationCompat.VISIBILITY_PUBLIC);
// Set the Notification style
noti.setContentTitle(currentItem.getSurah());
noti.addAction(R.drawable.ic_previous, "previous", ppreviousIntent);
noti.addAction(playpausebtn, "pause", pplayIntent);
noti.addAction(R.drawable.ic_next, "next", pnextIntent);
noti.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0, 1, 2)
.setMediaSession(MediaSessionCompat.Token.fromToken(mediaSession.getSessionToken())));
noti.setContentIntent(pendingIntentOpenApp);
noti.setSmallIcon(R.drawable.only);
noti.setOnlyAlertOnce(true);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"Siraa",
NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
noti.setChannelId(CHANNEL_ID);
}
notificationManager.notify(0, noti.build());
}
To implement notification action button you need to create Strings :
public static final String ACTION_PLAY = "action_play";
public static final String ACTION_NEXT = "action_next";
public static final String ACTION_PREVIOUS = "action_previous";
public static final String CHANNEL_ID = "Channel1";
NotificationManager notificationManager;
3.Register these actions inside a Broadcast receiver with intentfilters:
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_PLAY);
filter.addAction(ACTION_NEXT);
filter.addAction(ACTION_PREVIOUS);
receiver=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String actioname = intent.getAction();
if(actioname!=null){
switch (actioname){
case ACTION_PLAY:
Toast.makeText(context,"Click play",Toast.LENGTH_SHORT).show();
\\\ implement whatever
playpausebtnClicked();
break;
case ACTION_NEXT:
Toast.makeText(context,"Clicked next",Toast.LENGTH_SHORT).show();
nextbtnClicked();
break;
case ACTION_PREVIOUS:
Toast.makeText(context,"Clicked previous",Toast.LENGTH_SHORT).show();
prevbtnClicked();
break;
}
}
}
};
registerReceiver(receiver,filter);
and open themethod in my buttonclick event.
That's it no need to register in the manifest file. Hope this helped.
I am a new android studio user. I am trying to build a BLE GATT service app. the app works fine for unpaired devices. However, the issue arises when I tried to scan for a device which is already paired. it does not show on the scan.
I am not using MainActivity, instead of that, I am using DeviceScanActivity as my Main. here's the snippet of that part:
public class DeviceScanActivity extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
private static final int REQUEST_ENABLE_BT = 1;
private static final long SCAN_PERIOD = 7500;
private static final int LOCATION_REQUEST = 255;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// getActionBar().setTitle(R.string.title_devices);
getActionBar().setDisplayShowTitleEnabled(false);
mHandler = new Handler();
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (!mScanning) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
mLeDeviceListAdapter.clear();
scanLeDevice(true);
break;
case R.id.menu_stop:
scanLeDevice(false);
break;
}
return true;
}
#Override
protected void onStart(){
super.onStart();
verifyPermissionAndScan();
if (!mBluetoothAdapter.isEnabled()){
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter);
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onPause() {
super.onPause();
scanLeDevice(false);
mLeDeviceListAdapter.clear();
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
if (device == null) return;
final Intent intent = new Intent(this, DeviceControlActivity.class);
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
if (mScanning) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
mScanning = false;
}
startActivity(intent);
}
private void scanLeDevice(final boolean enable) {
if (enable && !mScanning) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private LayoutInflater mInflater;
private HashMap<BluetoothDevice, Integer> mDevicesRssi = new HashMap<>();
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<>();//i removed BluetoothDevice from the diamond bracket
mInflater = DeviceScanActivity.this.getLayoutInflater();
}
public void addDevice(BluetoothDevice device, int rssi) {
if (mDevicesRssi.containsKey(device)) {
int oldRssi = mDevicesRssi.get(device);
if (Math.abs(oldRssi - rssi) > 2) {
mDevicesRssi.put(device, rssi);
notifyDataSetChanged();
}
} else {
mDevicesRssi.put(device, rssi);
notifyDataSetChanged();
}
if(!mLeDevices.contains(device)) {
mLeDevices.add(device);
notifyDataSetChanged();
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
#Override
public int getCount() {
return mLeDevices.size();
}
#Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
//
BluetoothDevice device = mLeDevices.get(i);
//
if (view == null) {
view = mInflater.inflate(R.layout.listitem_device, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
viewHolder.deviceBonded = (TextView) view.findViewById(R.id.device_bonded);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
updateBondedState(device, viewHolder);
updateRssi(device, viewHolder);
return view;
}
private void updateBondedState(BluetoothDevice device, ViewHolder viewHolder) {
switch(device.getBondState()) {
case BOND_NONE:
viewHolder.deviceBonded.setVisibility(View.INVISIBLE);
break;
case BOND_BONDING:
viewHolder.deviceBonded.setText(R.string.bonding_state);
viewHolder.deviceBonded.setVisibility(View.VISIBLE);
break;
case BOND_BONDED:
viewHolder.deviceBonded.setText(R.string.bonded_state);
viewHolder.deviceBonded.setVisibility(View.VISIBLE);
break;
}
}
private void updateRssi(BluetoothDevice device, ViewHolder viewHolder) {
final int rssi = mDevicesRssi.get(device);
viewHolder.deviceRssi.setText(String.format("%s dBm", String.valueOf(rssi)));
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLeDeviceListAdapter.addDevice(device,rssi);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
static class ViewHolder {
TextView deviceName;
TextView deviceAddress;
TextView deviceRssi;
TextView deviceBonded;
}
#TargetApi(23)
private void verifyPermissionAndScan() {
if (ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED) {
Toast.makeText(this, R.string.location_already_given, Toast.LENGTH_LONG);
} else {
requestPermissions(new String[] {ACCESS_COARSE_LOCATION}, LOCATION_REQUEST);
}
}
#Override
public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
if (requestCode != LOCATION_REQUEST) return;
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
Toast.makeText(this, R.string.permission_allowed, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, R.string.permission_not_allowed, Toast.LENGTH_LONG).show();
}
}
}
This is my DeviceControlActiviy class file:
public class DeviceControlActivity extends Activity {
private final static String TAG = DeviceControlActivity.class.getSimpleName();
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
private TextView mConnectionState;
private TextView mDataField;
private String mDeviceName;
private String mDeviceAddress;
private ExpandableListView mGattServicesList;
private BluetoothLeService mBluetoothLeService;
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gatt_services_characteristics);
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
mGattServicesList.setOnChildClickListener(servicesListClickListner);
mConnectionState = (TextView) findViewById(R.id.connection_state);
mDataField = (TextView) findViewById(R.id.data_value);
// getActionBar().setTitle(mDeviceName);
getActionBar().setDisplayShowTitleEnabled(false);
getActionBar().setDisplayHomeAsUpEnabled(true);
final Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
private final ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
// mBluetoothLeService.connect(mDeviceAddress);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
displayGattServices(mBluetoothLeService.getSupportedGattServices());
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
private final ExpandableListView.OnChildClickListener servicesListClickListner =
new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
if (mGattCharacteristics != null) {
final BluetoothGattCharacteristic characteristic =
mGattCharacteristics.get(groupPosition).get(childPosition);
final int charaProp = characteristic.getProperties();
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(
mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(characteristic);
}
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
mNotifyCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(
characteristic, true);
}
return true;
}
return false;
}
};
private void clearUI() {
mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
mDataField.setText(R.string.no_data);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
final boolean result = mBluetoothLeService.connect(mDeviceAddress);
Log.d(TAG, "Connect request result=" + result);
}
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mGattUpdateReceiver);
}
#Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_services, menu);
if (mConnected) {
menu.findItem(R.id.menu_connect).setVisible(false);
menu.findItem(R.id.menu_disconnect).setVisible(true);
} else {
menu.findItem(R.id.menu_connect).setVisible(true);
menu.findItem(R.id.menu_disconnect).setVisible(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_connect:
mBluetoothLeService.connect(mDeviceAddress);
return true;
case R.id.menu_disconnect:
mBluetoothLeService.disconnect();
return true;
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mConnectionState.setText(resourceId);
}
});
}
private void displayData(String data) {
if (data != null) {
mDataField.setText(data);
}
}
private void displayGattServices(List<BluetoothGattService> gattServices) {
if (gattServices == null) return;
String uuid = null;
String unknownServiceString = getResources().getString(R.string.unknown_service);
String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
= new ArrayList<ArrayList<HashMap<String, String>>>();
mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
for (BluetoothGattService gattService : gattServices) {
HashMap<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
currentServiceData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
new ArrayList<HashMap<String, String>>();
List<BluetoothGattCharacteristic> gattCharacteristics =
gattService.getCharacteristics();
ArrayList<BluetoothGattCharacteristic> charas =
new ArrayList<BluetoothGattCharacteristic>();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap<String, String> currentCharaData = new HashMap<String, String>();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
this,
gattServiceData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 },
gattCharacteristicData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 }
);
mGattServicesList.setAdapter(gattServiceAdapter);
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
}
I get the device name, address and RSSI for unpaired devices perfectly. but if the device is already paired it does not show on the device list, also if I click on a device on the unpaired device list, it does not automatically pair the device with the phone. I need to do it manually from the phone's BT setting.
This displays all the devices the phone was paired with (even if it is not paired with currently)
JAVA
for(BluetoothDevice device : BluetoothAdapter.getDefaultAdapter().getBondedDevices()){
device.getName(); // name
device.getAddress();// Address
}
KOTLIN
for (device in BluetoothAdapter.getDefaultAdapter().bondedDevices) {
device.name // name
device.address// Address
}
Hope this helps!
i have bluetooth Fragment.
I have my first Activity in which the BT connection is established. There is an option presented to the user and, based on their selection, a different Activity will load.
public class BluetoothFragment extends Fragment {
private NameMappingDataSource mName;
private DeviceAutoConnectDataSource deviceAutoConnect;
private ActivateDatasource activateDatasource;
List<DisplayNameMapping> dataItemsdevice = new ArrayList<DisplayNameMapping>();
private static final String TAG = "BluetoothChatFragment";
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
private static final int REQUEST_ENABLE_BT = 3;
private ListView mConversationView;
private EditText mOutEditText;
private Button mSendButton;
private String mConnectedDeviceName = null;
private String mConnectedDeviceAddress = null;
private ArrayAdapter<String> mConversationArrayAdapter;
private StringBuffer mOutStringBuffer;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothService mMessage = null;
private Context context;
boolean mBound = false;
#Override
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mName = new NameMappingDataSource(getActivity());
deviceAutoConnect = new DeviceAutoConnectDataSource(getActivity());
activateDatasource = new ActivateDatasource(getActivity());
setHasOptionsMenu(true);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
FragmentActivity activity = getActivity();
Toast.makeText(activity, "Bluetooth is not available", Toast.LENGTH_LONG).show();
activity.finish();
}
}
#Override
public void onStart() {
super.onStart();
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} else if (mMessage == null) {
setupChat();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (mMessage != null) {
mMessage.stop();
}
}
#Override
public void onResume() {
super.onResume();
if (mMessage != null) {
if (mMessage.getState() == BluetoothService.STATE_NONE) {
mMessage.start();
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_bluetooth_chat, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
mConversationView = (ListView) view.findViewById(R.id.in);
mOutEditText = (EditText) view.findViewById(R.id.edit_text_out);
mSendButton = (Button) view.findViewById(R.id.button_send);
}
private void setupChat() {
mConversationArrayAdapter = new ArrayAdapter<String>(getActivity(), R.layout.message);
mConversationView.setAdapter(mConversationArrayAdapter);
mOutEditText.setOnEditorActionListener(mWriteListener);
mSendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
View view = getView();
if (null != view) {
TextView textView = (TextView) view.findViewById(R.id.edit_text_out);
String message = textView.getText().toString();
sendMessage(message.getBytes());
}
}
});
final Button testButton = (Button) getActivity().findViewById(R.id.button1);
testButton.setTag(1);
testButton.setBackgroundResource(R.drawable.open);
testButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final int status = (Integer) v.getTag();
if (status == 1) {
v.setTag(0);
} else {
testButton.setBackgroundResource(R.drawable.open);
v.setTag(1);
}
}
});
mMessage = new BluetoothService(getActivity(), mHandler);
mOutStringBuffer = new StringBuffer("");
}
private void ensureDiscoverable() {
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
public void sendMessage(byte[] message) {
if (mMessage.getState() != BluetoothService.STATE_CONNECTED) {
Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
if (message.length > 0) {
mMessage.write(message);
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
private TextView.OnEditorActionListener mWriteListener
= new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
// If the action is a key-up event on the return key, send the message
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
String message = view.getText().toString();
sendMessage(message.getBytes());
}
return true;
}
};
private void setStatus(int resId) {
FragmentActivity activity = getActivity();
if (null == activity) {
return;
}
final ActionBar actionBar = activity.getActionBar();
if (null == actionBar) {
return;
}
actionBar.setSubtitle(resId);
}
private void setStatus(CharSequence subTitle) {
FragmentActivity activity = getActivity();
if (null == activity) {
return;
}
final ActionBar actionBar = activity.getActionBar();
if (null == actionBar) {
return;
}
actionBar.setSubtitle(subTitle);
}
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
int t = 0;
FragmentActivity activity = getActivity();
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BluetoothService.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
mConversationArrayAdapter.clear();
break;
case BluetoothService.STATE_CONNECTING:
setStatus(R.string.title_connecting);
break;
case BluetoothService.STATE_LISTEN:
case BluetoothService.STATE_NONE:
setStatus(R.string.title_not_connected);
break;
}
break;
case Constants.MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
mConversationArrayAdapter.add("Me: " + writeBuf);
break;
case Constants.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(mConnectedDeviceName + ": " + readMessage);
break;
case Constants.MESSAGE_DEVICE_NAME:
mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME);
mConnectedDeviceAddress = msg.getData().getString(Constants.DEVICE_ADDRESS);
if (null != activity) {
Toast.makeText(activity, "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
}
break;
case Constants.MESSAGE_TOAST:
if (null != activity) {
Toast.makeText(activity, msg.getData().getString(Constants.TOAST),
Toast.LENGTH_SHORT).show();
mConnectedDeviceAddress=null;
}
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, true);
}
break;
case REQUEST_CONNECT_DEVICE_INSECURE:
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, false);
}
break;
case REQUEST_ENABLE_BT:
if (resultCode == Activity.RESULT_OK) {
setupChat();
} else {
Log.d(TAG, "BT not enabled");
Toast.makeText(getActivity(), R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
getActivity().finish();
}
}
}
private void connectDevice(Intent data, boolean secure) {
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
mMessage.connect(device, secure);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.bluetooth_chat, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.secure_connect_scan: {
Intent serverIntent = new Intent(this.context, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
return true;
}
case R.id.insecure_connect_scan: {
Intent serverIntent = new Intent(this.context, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);
return true;
}
case R.id.discoverable: {
ensureDiscoverable();
return true;
}
case R.id.menu_user: {
if(mConnectedDeviceAddress!=null) {
mName.open();
List<DisplayNameMapping> str = mName.getDisplayNameMappingLiked(mConnectedDeviceAddress);
mName.close();
String setname = str.get(0).getDisplay_name();
showInputDialogCheckPWAdminUser(setname, mConnectedDeviceAddress);
}
return true;
}
case R.id.menu_history: {
Intent userIntent = new Intent(getActivity(),UserListActivity.class);
userIntent.putExtra("addressdevice", mdeviceaddress);
startActivity(userIntent);
}
}
return false;
}
}
How to send message to here used connection of bletoothfragment.class
Please help me. I don't know
public class UserListActivity extends Activity implements UserListAdapter.customButtonListener {
Button btnadduser,btnconfig;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=this;
getActionBar().setDisplayHomeAsUpEnabled(true);
userdata = new UserDataSource(this);
namedata = new NameMappingDataSource(this);
userdevicedata=new UserDeviceDatasource(this);
setContentView(R.layout.activity_user_list);
btnconfig=(Button) findViewById(R.id.btnconfig);
btnconfig.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
'How to send message to here used connection of bletoothfragment.class '
} catch (Exception ex) {
}
}
});
}
public void onButtonClickListner(int position, String value) {
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
You can save last connected device address and then you can use it.
String address = intent.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(device, secure);