I am making a audio player app. I created a service for audio player and playback notification. I am facing problem with the previous/next buttons in the Player as well as the playback notification.
The previous/next buttons in the audio playback notification just restarts the playback and do not change the song/audio file. Other controls work well.
The previous/next buttons in the audio player (using exoplayer) change and play the next/previous file but the player artwork (image for audio file) do not change. Also, the play/pause button remains in paused state and when pressed, it plays a different file.
Here is the code for the AudioActivity and AudioService-
AudioActivity.java
package com.example.videoplayer.audio;
import static com.example.videoplayer.RecyclerViewClasses.MediaFilesActivity.FOLDER_NAME_KEY;
import static com.example.videoplayer.RecyclerViewClasses.MediaFilesActivity.MY_PREF;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.example.videoplayer.MediaFiles;
import com.example.videoplayer.MediaPlayer.PlaylistDialog;
import com.example.videoplayer.R;
import com.example.videoplayer.RecyclerViewClasses.MediaFilesAdapter;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.TracksInfo;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.util.Util;
import java.util.ArrayList;
public class AudioActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = AudioActivity.class.getSimpleName();
private static final int NOTIFICATION_ID = 1;
private static final String CHANNEL_ID = "channel_id";
PlayerView playerView;
SimpleExoPlayer player;
//public static SimpleExoPlayer player;
RelativeLayout root;
ImageView audioBack, audioList, menu_more;
ImageView nextButton, previousButton;
TextView playlistTitle, title;
ArrayList<MediaFiles> mAudioFilesArrayList;
int position;
MediaFilesAdapter mediaFilesAdapter;
String audioTitle;
String listTitle;
private AudioService mService;
private boolean mBound = false;
private Intent serviceIntent;
private ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
AudioService.LocalBinder binder = (AudioService.LocalBinder) iBinder;
mService = binder.getService();
mBound = true;
Log.i(TAG + " ###", "in onServiceConnected: calling initializePlayer()");
initializePlayer();
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBound = false;
}
};
void initializePlayer() {
if (mBound) {
Log.i(TAG + " ###", "initializePlayer() called");
player = mService.getplayerInstance();
// playerView.setVisibility(View.VISIBLE);
// player.setPlayWhenReady(true);
playerView.setPlayer(player);
// player.play();
// player.seekTo(position, C.TIME_UNSET);
playError();
}
}
#SuppressLint("UseCompatLoadingForDrawables")
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
Log.i(TAG + " ###", "onCreate() called");
super.onCreate(savedInstanceState);
setFullScreen();
setContentView(R.layout.activity_audio_player);
try {
getSupportActionBar().hide();
} catch (NullPointerException e) {
Log.e(TAG + " ###", "in VideoPlayerActivity: " + e);
}
playerView = findViewById(R.id.exoplayer_view_audio);
Log.i(TAG + " ###", "default artwork set in onCreate()");
root = findViewById(R.id.root_layout_audio);
audioBack = findViewById(R.id.audio_back_audio);
audioList = findViewById(R.id.audio_list);
nextButton = findViewById(R.id.exo_next);
previousButton = findViewById(R.id.exo_prev);
playlistTitle = findViewById(R.id.playlistTitle);
title = findViewById(R.id.audiofile_title);
menu_more = findViewById(R.id.audio_more);
SharedPreferences preferences = this.getSharedPreferences(MY_PREF, Context.MODE_PRIVATE);
listTitle = preferences.getString(FOLDER_NAME_KEY, "DEFAULT_FOLDER_NAME");
position = getIntent().getIntExtra("position", 1);
audioTitle = getIntent().getStringExtra("media_title");
Bundle b = getIntent().getBundleExtra(this.getString(R.string.bundle));
mAudioFilesArrayList = b.getParcelableArrayList(this.getString(R.string.media_array_list));
Log.i(TAG + " ###", "position=" + position);
Log.i(TAG + " ###", "is mAudioFilesArrayList null " + (mAudioFilesArrayList == null));
if (mAudioFilesArrayList == null)
return;
audioList.setOnClickListener(this);
nextButton.setOnClickListener(this);
previousButton.setOnClickListener(this);
audioBack.setOnClickListener(this);
menu_more.setOnClickListener(this);
startServiceIntent();
}
void startServiceIntent() {
Log.i(TAG + " ###", "entered startServiceIntent");
serviceIntent = new Intent(this, AudioService.class);
Log.i(TAG + " ###", "position=" + position);
serviceIntent.putExtra("position", position);
Bundle bundle = new Bundle();
Log.i(TAG + " ###", "is mediaArrayList null " + (mAudioFilesArrayList == null));
bundle.putParcelableArrayList(this.getString(R.string.media_array_list), mAudioFilesArrayList);
serviceIntent.putExtra("bundle", bundle);
Util.startForegroundService(this, serviceIntent);
playerView.setControllerHideOnTouch(false);
playerView.setUseController(true);
playerView.setControllerShowTimeoutMs(0);
playerView.showController();
playerView.setControllerAutoShow(true);
setUI();
}
private void playError() {
Log.i(TAG + " ###", "entered the playError() method()");
//Player.EventListener is deprecated
player.addListener(new Player.Listener() {
#Override
public void onTracksInfoChanged(#NonNull TracksInfo tracksInfo) {
Player.Listener.super.onTracksInfoChanged(tracksInfo);
Toast.makeText(AudioActivity.this, "TrackInfoChanged", Toast.LENGTH_SHORT).show();
}
#Override
public void onPlayerError(#NonNull PlaybackException error) {
Toast.makeText(AudioActivity.this, "Audio Playing Error", Toast.LENGTH_SHORT).show();
}
});
player.setPlayWhenReady(true);
}
private void setFullScreen() {
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
#Override
protected void onStart() {
super.onStart();
Log.i(TAG + " ###", "entered onStart()");
getApplicationContext().bindService(serviceIntent, mServiceConnection, 0);
initializePlayer();
setUI();
}
void setUI() {
Log.i(TAG + " ###", "entered setUI()");
title.setText(audioTitle);
playlistTitle.setText(listTitle);
Log.i(TAG + " ###", "text set in setUI()");
//playerView.setDefaultArtwork(AppCompatResources.getDrawable(this,R.drawable.ic_sharp_music_note_24));
//playerView.setUseArtwork(true);
}
#Override
protected void onResume() {
super.onResume();
Log.i(TAG + " ###", "onResume() called");
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onStop() {
Log.i(TAG + " ###", "onStop() called, unbinding service!");
getApplicationContext().unbindService(mServiceConnection);
mBound = false;
finish();
super.onStop();
}
#Override
public void onClick(View view) {
Log.i(TAG + " ###", "entered onClick() method");
switch (view.getId()) {
case R.id.exo_play:
player.play();
break;
case R.id.exo_pause:
player.pause();
break;
case R.id.exo_next:
try {
player.stop();
stopService(serviceIntent);
position++;
audioTitle = mAudioFilesArrayList.get(position).getTitle();
title.setText(audioTitle);
startServiceIntent();
initializePlayer();
player = mService.getplayerInstance();
//playerView.setPlayer(null);
playerView.setPlayer(player);
playError();
} catch (Exception e) {
Toast.makeText(this, "No next audio file", Toast.LENGTH_SHORT).show();
position--;
}
break;
case R.id.exo_prev:
Log.i(TAG + " ###", "previous button clicked!");
try {
player.stop();
Log.i(TAG+" ###","player stopped!");
stopService(serviceIntent);
position--;
audioTitle = mAudioFilesArrayList.get(position).getTitle();
title.setText(audioTitle);
startServiceIntent();
//initializePlayer();
player=mService.getplayerInstance();
//playerView.setPlayer(null);
playerView.setPlayer(player);
playError();
} catch (Exception e) {
Toast.makeText(this, "No previous Video", Toast.LENGTH_SHORT).show();
position++;
}
break;
case R.id.audio_back_audio:
if (player != null)
//player.release();
finish();
break;
case R.id.audio_list:
PlaylistDialog playlistDialog = new PlaylistDialog(mAudioFilesArrayList, mediaFilesAdapter);
playlistDialog.show(getSupportFragmentManager(), playlistDialog.getTag());
break;
case R.id.audio_more:
PopupMenu popupMenu = new PopupMenu(this, menu_more);
MenuInflater inflater = popupMenu.getMenuInflater();
inflater.inflate(R.menu.actions_video, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
int id = menuItem.getItemId();
switch (id) {
case R.id.share_file:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
String filepath = mAudioFilesArrayList.get(position).getPath();
Uri uri = Uri.parse(filepath);
shareIntent.setType("/");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(shareIntent, "Share File using"));
break;
}
return false;
}
});
popupMenu.show();
break;
}
}
}
AudioSerivce.java
package com.example.videoplayer.audio;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import com.example.videoplayer.MediaFiles;
import com.example.videoplayer.R;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
import java.io.File;
import java.util.ArrayList;
public class AudioService extends Service {
private static final String TAG = AudioService.class.getSimpleName();
private final IBinder mBinder = new LocalBinder();
private SimpleExoPlayer player;
private int position;
PlaybackParameters parameters;
private ArrayList<MediaFiles> mAudioFilesArrayList;
private PlayerNotificationManager.Builder playerNotificationManagerBuilder;
private PlayerNotificationManager playerNotificationManager;
ConcatenatingMediaSource concatenatingMediaSource;
private static final int NOTIFICATION_ID = 1;
private static final String CHANNEL_ID = "channel_id";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
Log.i(TAG+" ###","onDestroy() called");
releasePlayer();
super.onDestroy();
}
private void releasePlayer() {
if (player != null) {
Log.i(TAG+" ###","Player!=null and releasePlayer called");
playerNotificationManager.setPlayer(null);
player.release();
player = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public SimpleExoPlayer getplayerInstance() {
Log.i(TAG+" ###","getplayerInstance() called: "+(player==null));
if (player == null) {
startPlayer();
}
return player;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// try {
Bundle b = intent.getBundleExtra(this.getString(R.string.bundle));
String name=this.getString( R.string.media_array_list);
mAudioFilesArrayList = b.getParcelableArrayList(this.getString( R.string.media_array_list));
// }
// catch(Exception e)
// {
// Log.e(AudioService.class.getSimpleName()+" ###",e.toString());
// stopSelf();
// }
position = intent.getIntExtra("position", 1);
Log.i(TAG+"###"," in onStartCommand()");
Log.i(TAG+" ###","is mediaArrayList null"+(mAudioFilesArrayList==null));
Log.i(TAG+" ###","position="+position);
if (player == null) {
Log.i(TAG+" ###","Player is null, in onStartCommand calling startPlayer()");
Log.i(TAG+" ###","is mediaArrayList null"+(mAudioFilesArrayList==null));
Log.i(TAG+" ###","position="+position);
startPlayer();
}
return START_STICKY;
}
private void startPlayer() {
Log.i(TAG+" ###","entered startPlayer()");
Log.i(TAG+" ###","is mediaArrayList null"+(mAudioFilesArrayList==null));
Log.i(TAG+" ###","position="+position);
final Context context = this;
createNotificationChannel();
playerNotificationManagerBuilder = new PlayerNotificationManager.Builder(context, NOTIFICATION_ID, CHANNEL_ID)
.setRewindActionIconResourceId(R.drawable.ic_rewind)
.setNextActionIconResourceId(R.drawable.ic_next)
.setPreviousActionIconResourceId(R.drawable.ic_previous)
.setSmallIconResourceId(R.drawable.ic_sharp_music_note_24);
playerNotificationManagerBuilder.setPlayActionIconResourceId(R.drawable.ic_play);
playerNotificationManagerBuilder.setPauseActionIconResourceId(R.drawable.ic_pause);
playerNotificationManagerBuilder.setFastForwardActionIconResourceId(R.drawable.ic_fast_forward);
playerNotificationManagerBuilder.setMediaDescriptionAdapter(new PlayerNotificationManager.MediaDescriptionAdapter() {
#Override
public CharSequence getCurrentContentTitle(Player player) {
return mAudioFilesArrayList.get(position).getTitle();
}
#Nullable
#Override
public PendingIntent createCurrentContentIntent(Player player) {
Intent intent = new Intent(context, AudioActivity.class);
intent.putExtra("position", position);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(context.getString( R.string.media_array_list), mAudioFilesArrayList);
intent.putExtra("bundle",bundle);
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE);
}
#Nullable
#Override
public CharSequence getCurrentContentText(Player player) {
return "Summary";
}
#Nullable
#Override
public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
int window=player.getCurrentMediaItemIndex();
Log.i(TAG+"###","in getCurrentLargeIcon: window="+window);
return null;
// return getCurrentLargeIcon(player,callback);
}
});
playerNotificationManagerBuilder.setNotificationListener(new PlayerNotificationManager.NotificationListener() {
#Override
public void onNotificationCancelled(int notificationId, boolean dismissedByUser) {
Log.i(TAG+" ###","onNotificationCancelled called!");
stopSelf();
}
#Override
public void onNotificationPosted(int notificationId, Notification notification, boolean ongoing) {
startForeground(notificationId, notification);
Log.i(TAG+" ###","startForeground() in onNotificationPosted!");
}
});
playerNotificationManager=playerNotificationManagerBuilder.build();
Log.i(TAG+" ###","startPlayer() called");
String path = mAudioFilesArrayList.get(position).getPath();
Uri uri = Uri.parse(path);
// PlayerView.Builder builder = new ExoPlayer.Builder(this);
// builder.setSeekForwardIncrementMs(5000);
// builder.setSeekBackIncrementMs(5000);
// player = builder.build();
SimpleExoPlayer.Builder builder = new SimpleExoPlayer.Builder(this);
builder.setSeekForwardIncrementMs(10000);
builder.setSeekBackIncrementMs(10000);
player = builder.build();
DefaultDataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(this);
concatenatingMediaSource = new ConcatenatingMediaSource();
for (int i = 0; i < mAudioFilesArrayList.size(); i++) {
new File(String.valueOf(mAudioFilesArrayList.get(i)));
MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(Uri.parse(String.valueOf(uri))));
concatenatingMediaSource.addMediaSource(mediaSource);
}
player.setMediaSource(concatenatingMediaSource);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MUSIC)
.build();
player.setAudioAttributes(audioAttributes, true);
player.setPlaybackParameters(parameters);
player.prepare();
player.play();
player.seekTo(position,C.TIME_UNSET);
//player.setPlayWhenReady(true);
playerNotificationManager.setPlayer(player);
playerNotificationManager.setUseNextAction(true);
playerNotificationManager.setSmallIcon(R.drawable.ic_sharp_music_note_24);
playerNotificationManager.setColorized(true);
playerNotificationManager.setUseChronometer(true);
playerNotificationManager.setColor(R.color.teal_200);
playerNotificationManager.setUseChronometer(true);
playerNotificationManager.setUseRewindAction(true);
playerNotificationManager.setUseFastForwardAction(true);
playerNotificationManager.setUsePlayPauseActions(true);
Log.i(TAG+" ###","returning from startPlayer()");
}
private void createNotificationChannel() {
Log.i(TAG+" ###","createNotificationChannel()");
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
public class LocalBinder extends Binder {
public AudioService getService() {
return AudioService.this;
}
}
}
Please help me in finding the problem and resolving it.
In my opinion the use of MediaSessionCompat is essential for an audio app. A very good instructions can be found here.
I hope this helps you.
GGK
Related
I've been working on an Android NFC application on Android Studio, and I've hit a major roadblock. Basically, everytime my app detects a new NDEF NFC Tag, a new intent is created, and MainActivity seems to be reloaded, which results in onPause(), onCreate and onResume() being called.
The problem is, the app functions on a "session" system. The user scans a tag, logs in on a remote server, and the boolean sessionOpen is set to true. After that, the user is supposed to scan a different NFC tag, which would re-direct them on another page, while still being logged in (using a cookie) and the session still being opened.
Now, since onCreate() is called after a new NFC intent, it resets everything back to 0, which makes it impossible for me to keep track of their session., or anything for that matter.
I've tried overriding onSaveInstanceState and onRestoreInstanceState, but to no avail. Is there a way to prevent the NFC Intent from reloading the MainActivity, or from calling onCreate()? Or is there a way to restore variables from an older save state?
Here is my MainActivity.Java : (bits not relevant as well as some declarations have been removed)
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Parcelable;
import android.provider.Settings;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.CookieSyncManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.webkit.CookieManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import com.google.android.material.snackbar.Snackbar;
import okhttp3.Cookie;
public class MainActivity extends AppCompatActivity {
public static final String sessionSavedState = "";
public boolean sessionOpen;
WebView web;
TextView usernameview;
TextView uridetector;
protected LocationManager locationManager;
protected LocationListener locationListener;
public String NFCid = "";
public static final String Error_Detected = "No NFC Tag Detected";
NfcAdapter nfcAdapter;
PendingIntent pendingIntent;
IntentFilter writingTagFilters[];
boolean writeMode;
Tag myTag;
Context context;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
session = findViewById(R.id.sessionview);
time = findViewById(R.id.sessiontime);
user = findViewById(R.id.userview);
Memo = findViewById(R.id.multiline);
Memo.setMovementMethod(new ScrollingMovementMethod());
Memo.setText("Init\n");
tag_status = findViewById(R.id.tagstatus);
web = findViewById(R.id.WebView1);
CookieManager.getInstance().removeAllCookies(null);
WebSettings webSettings = web.getSettings();
webSettings.setJavaScriptEnabled(true);
web.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
web.setWebViewClient(new Callback());
web.setWebViewClient(new WebViewClient(){
#Override
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
if (CookieManager.getInstance().getCookie(web.getUrl()).contains("dc-auth"))
{
AuthCount = AuthCount + 1;
}
Memo.setText(Memo.getText() + "1) cookie before: " + CookieManager.getInstance().getCookie(web.getUrl()) + "\n");
Memo.setText(Memo.getText() + "session status : " + String.valueOf(sessionOpen) + "\n");
if (!sessionOpen)
{
if (CookieManager.getInstance().getCookie(web.getUrl()).contains("dc-auth") && AuthCount >= 2)
{
super.doUpdateVisitedHistory(view, url, isReload);
Memo.setText(Memo.getText() + "1) session opened\n");
sessionOpen = true;
tag_status.setImageResource(R.drawable.tagetape_wait);
}
else
{
super.doUpdateVisitedHistory(view, url, isReload);
}
}
else
{
Memo.setText(Memo.getText() + "1) passage\n");
super.doUpdateVisitedHistory(view, url, isReload);
}
Memo.setText(Memo.getText() + "1.1) passage\n");
String currentUrl = view.getUrl();
}
});
web.loadUrl("adress.com");
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(#NonNull Location location) {
}
};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.INTERNET
}, 10);
return;
}
locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 5000, 0, locationListener);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
longitudeString = String.valueOf(location.getLongitude());
latitudeString = String.valueOf(location.getLatitude());
if (longitudeString.isEmpty() && latitudeString.isEmpty())
{
LocationChange = false;
}
else{
LocationChange = true;
}
context = this;
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "This device does not support NFC", Toast.LENGTH_SHORT).show();
finish();
}
readFromIntent(getIntent());
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writingTagFilters = new IntentFilter[] { tagDetected };
}
public void readFromIntent(Intent intent) {
String action = intent.getAction();
Uri uri = intent.getData();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] uid = tag.getId(); //This is the Unique IDentifier of the card
//tag_id.setText(bytesToHex(uid)); //recuperation du payload NFC
NFCid = bytesToHex(uid);
NdefMessage[] msgs = null;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
//uridetector.setText(msgs[i].toString());
}
}
buildTagViews(msgs);
}
}
#SuppressLint("SetTextI18n")
private void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) return;
Uri ndef_uri;
String text = "";
String uri = "";
String ID = "";
String cookie = "";
byte[] payload = msgs[0].getRecords()[0].getPayload();
byte[] URIpayload = msgs[0].getRecords()[1].getPayload();
int languageCodeLength = payload[0] & 0063; //get the language code, for e.x : "en"
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; //verify encoding
try {
text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
uri = new String(URIpayload, languageCodeLength - 1, URIpayload.length - languageCodeLength + 1, textEncoding);
if (text.contains(";") && text.contains("user")) {
textList = text.split(";");
user.setText(textList[1]);
session.setText("session de " + textList[1]);
if (textList[2].contains("1")) { //DEBUG MODE
cookie = CookieManager.getInstance().getCookie(web.getUrl());
Memo.setText(Memo.getText() + "cookie before: " + cookie + "\n");
}
tag_status.setImageResource(R.drawable.tagdetected);
if (uri.contains("user") && uri.contains("adress.com")) {
if (LocationChange = false)
{
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Service de geo-location en cours d'initialisation. Veuillez patienter...", Snackbar.LENGTH_LONG);
snackbar.show();
}
else
{
uri = uri + "arugments"
web.loadUrl("https://" + uri);
}
}
} else if (text.contains("mobile")) {
tag_status.setImageResource(R.drawable.tagdetected);
if (!sessionOpen) {
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Aucune session ouverte. Veuillez scanner un tag utilisateur et/ou vous logger.", Snackbar.LENGTH_LONG);
snackbar.show();
}
else
{
tag_status.setImageResource(R.drawable.tagetape_wait);
}
if (uri.contains("stop") && uri.contains("adress.com"))
{
cookie = CookieManager.getInstance().getCookie(web.getUrl());
Memo.setText(Memo.getText() + "cookie after: " + cookie + "\n");
if (sessionOpen) {
uri = uri + "?tagid=" + NFCid + "&deviceid=" + getDeviceId2(context);
web.loadUrl("https://" + uri);
}
}
else
{
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Invalid NFC URL. ", Snackbar.LENGTH_LONG);
snackbar.show();
}
} else {
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Tag NFC Invalide.", Snackbar.LENGTH_LONG);
snackbar.show();
}
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEncoding", e.toString());
}
int prefixCode = payload[0] & 0x0FF;
if (prefixCode >= URI_PREFIX.length) prefixCode = 0;
String reducedUri = new String(payload, 1, payload.length - 1, Charset.forName("UTF-8"));
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putBoolean(sessionSavedState, sessionOpen);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
sessionOpen = savedInstanceState.getBoolean(sessionSavedState);
}
#Override
protected void onDestroy(){
super.onDestroy();
// Clear all the cookies
CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();
web.clearCache(true);
web.clearFormData();
web.clearHistory();
web.clearSslPreferences();
}
public void clearCookiesAndCache(Context context){
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
}
public static String getDeviceId2(Context context) {
String androidId = Settings.Secure.getString(
context.getContentResolver(), Settings.Secure.ANDROID_ID);
return androidId;
}
private class Callback extends WebViewClient {
#Override
public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
return false; //do not override loaded page
}
}
//timeout - disconnect methods
#Override
protected void onResume()
{
super.onResume();
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
if (sessionOpen) {
mCountDown.start();
}
}
#Override
protected void onPause()
{
super.onPause();
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.disableForegroundDispatch(this);
mCountDown.cancel();
}
#Override
public void onUserInteraction()
{
super.onUserInteraction();
// user interact cancel the timer and restart to countdown to next interaction
mCountDown.cancel();
if (sessionOpen) {
mCountDown.start();
}
}
}
So I have an application which has to monitor and range after beacons and than calculates the position of the user. After calculating this , the value is passed to the Wayfindigoverlayactivity.class where the value should be putt on the map with the blue dot.
I don know how to assign the value to the blue dot but before that my application is working on an endless loop and is opening the activity on ranging about 100x .
RangingActivity:
package com.indooratlas.android.sdk.examples.wayfinding;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.widget.EditText;
import android.content.Context;
import com.google.android.gms.maps.model.LatLng;
import com.indooratlas.android.sdk.IALocationRequest;
import com.indooratlas.android.sdk.examples.R;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
public class RangingActivity extends Activity implements BeaconConsumer,Runnable{
protected static final String TAG = "RangingActivity";
public LatLng center;
private final BlockingQueue queue;
private BeaconManager beaconManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ranging);
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.bind(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
beaconManager.unbind(this);
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public void onBeaconServiceConnect() {
RangeNotifier rangeNotifier = new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
int beacon_number = beacons.size();
Beacon[] beacon_array = beacons.toArray(new Beacon[beacons.size()]);
Beacon device1 = null, device2 = null, device3 = null;
Constants constants = new Constants();
float txPow1 = 0;
double RSSI1Unfiltered = 0;
double RSSI2Unfiltered = 0;
float txPow2 = 0;
double RSSI3Unfiltered = 0;
float txPow3 = 0;
if (beacon_number == 4) {
if (beacon_array[0].getIdentifier(0).toString() == constants.DEVICE1_UUID) {
device1 = beacon_array[0];
} else if (beacon_array[1].getIdentifier(0).toString() == constants.DEVICE1_UUID) {
device1 = beacon_array[1];
} else {
device1 = beacon_array[2];
}
if (beacon_array[0].getIdentifier(0).toString() == constants.DEVICE2_UUID) {
device2 = beacon_array[0];
} else if (beacon_array[1].getIdentifier(0).toString() == constants.DEVICE2_UUID) {
device2 = beacon_array[1];
} else {
device2 = beacon_array[2];
}
if (beacon_array[0].getIdentifier(0).toString() == constants.DEVICE3_UUID) {
device3 = beacon_array[0];
} else if (beacon_array[1].getIdentifier(0).toString() == constants.DEVICE3_UUID) {
device3 = beacon_array[1];
} else {
device3 = beacon_array[2];
}
RSSI1Unfiltered = device1.getRssi();
RSSI2Unfiltered = device2.getRssi();
RSSI3Unfiltered = device3.getRssi();
txPow1 = device1.getTxPower();
txPow2 = device2.getTxPower();
txPow3 = device3.getTxPower();
} else if (beacon_number > 0) {
Log.d(TAG, "didRangeBeaconsInRegion called with beacon count: " + beacons.size());
for (int i = 0; i < beacon_number; i++) {
Beacon nextBeacon = beacon_array[i];
Log.d(TAG, "The next beacon " + nextBeacon.getIdentifier(0) + " is about " + nextBeacon.getDistance() + " meters away." + "RSSI is: " + nextBeacon.getRssi());
logToDisplay("The next beacon" + nextBeacon.getIdentifier(0) + " is about " + nextBeacon.getDistance() + " meters away." + "RSSI is: " + nextBeacon.getRssi());
}
}
Log.d(TAG, "FLOAT!!!!!!!!" + txPow1);
LocationFinder locationFinder = new LocationFinder();
//pass location
center = locationFinder.findLocation(RSSI1Unfiltered, txPow1, RSSI2Unfiltered, txPow2, RSSI3Unfiltered, txPow3);
Log.d(TAG, "Current coordinates: asta e asta e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " + center.toString());
Bundle args = new Bundle();
args.putParcelable("b", center);
Intent intent00 = new Intent(RangingActivity.this, WayfindingOverlayActivity.class);
intent00.putExtras(args);
startActivity(intent00);
}
private void logToDisplay(final String s) {
runOnUiThread(new Runnable() {
#Override
public void run() {
EditText editText = RangingActivity.this.findViewById(R.id.textView3);
editText.append(s+"\n");
}
});
}
};
try {
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
beaconManager.addRangeNotifier(rangeNotifier);
} catch (RemoteException e) {
}
}
/* Blockinqueue try---not working
RangingActivity(BlockingQueue q)
{
queue = q;
}
public void run() {
LatLng res;
try
{
res = center;
queue.put(res);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
*/
}
Everything works fine here , until I open the next class where my map is the WayfindingOverlayActivity
package com.indooratlas.android.sdk.examples.wayfinding;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import com.google.android.material.snackbar.Snackbar;
import androidx.fragment.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.GroundOverlay;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.indooratlas.android.sdk.IALocation;
import com.indooratlas.android.sdk.IALocationListener;
import com.indooratlas.android.sdk.IALocationManager;
import com.indooratlas.android.sdk.IALocationRequest;
import com.indooratlas.android.sdk.IAOrientationListener;
import com.indooratlas.android.sdk.IAOrientationRequest;
import com.indooratlas.android.sdk.IAPOI;
import com.indooratlas.android.sdk.IARegion;
import com.indooratlas.android.sdk.IARoute;
import com.indooratlas.android.sdk.IAWayfindingListener;
import com.indooratlas.android.sdk.IAWayfindingRequest;
import com.indooratlas.android.sdk.examples.R;
import com.indooratlas.android.sdk.examples.SdkExample;
import com.indooratlas.android.sdk.resources.IAFloorPlan;
import com.indooratlas.android.sdk.resources.IALatLng;
import com.indooratlas.android.sdk.resources.IALocationListenerSupport;
import com.indooratlas.android.sdk.resources.IAVenue;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.RequestCreator;
import com.squareup.picasso.Target;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
#SdkExample(description = R.string.example_wayfinding_description)
public class WayfindingOverlayActivity extends FragmentActivity
implements GoogleMap.OnMapClickListener, OnMapReadyCallback ,Runnable{
private final BlockingQueue queue;
private static final String TAG = "IndoorAtlasExample";
/* used to decide when bitmap should be downscaled */
private static final int MAX_DIMENSION = 2048;
//kalman filter
private static final double KALMAN_R = 0.125d;
private static final double KALMAN_Q = 0.5d;
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private Circle mCircle;
private IARegion mOverlayFloorPlan = null;
private GroundOverlay mGroundOverlay = null;
private IALocationManager mIALocationManager;
private Target mLoadTarget;
private boolean mCameraPositionNeedsUpdating = true; // update on first location
private Marker mDestinationMarker;
private Marker mHeadingMarker;
private IAVenue mVenue;
private List<Marker> mPoIMarkers = new ArrayList<>();
private List<Polyline> mPolylines = new ArrayList<>();
private IARoute mCurrentRoute;
private IAWayfindingRequest mWayfindingDestination;
private IAWayfindingListener mWayfindingListener = new IAWayfindingListener() {
#Override
public void onWayfindingUpdate(IARoute route) {
mCurrentRoute = route;
if (hasArrivedToDestination(route)) {
// stop wayfinding
showInfo("You're there!");
mCurrentRoute = null;
mWayfindingDestination = null;
mIALocationManager.removeWayfindingUpdates();
}
updateRouteVisualization();
}
};
private IAOrientationListener mOrientationListener = new IAOrientationListener() {
#Override
public void onHeadingChanged(long timestamp, double heading) {
updateHeading(heading);
}
#Override
public void onOrientationChange(long timestamp, double[] quaternion) {
// we do not need full device orientation in this example, just the heading
}
};
private int mFloor;
// circle
private void showLocationCircle(LatLng center, double accuracyRadius) {
if (mCircle == null) {
// location can received before map is initialized, ignoring those updates
if (mMap != null) {
mCircle = mMap.addCircle(new CircleOptions()
.center(center)
.radius(accuracyRadius)
.fillColor(0x201681FB)
.strokeColor(0x500A78DD)
.zIndex(1.0f)
.visible(true)
.strokeWidth(5.0f));
mHeadingMarker = mMap.addMarker(new MarkerOptions()
.position(center)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_blue_dot))
.anchor(0.5f, 0.5f)
.flat(true));
}
} else {
// move existing markers position to received location
mCircle.setCenter(center);
mHeadingMarker.setPosition(center);
mCircle.setRadius(accuracyRadius);
}
}
private void updateHeading(double heading) {
if (mHeadingMarker != null) {
mHeadingMarker.setRotation((float) heading);
}
}
private IALocationListener mListener = new IALocationListenerSupport() {
public void onLocationChanged(IALocation location) {
Log.d(TAG, "NEW" + location.getLatitude() + " " + location.getLongitude());
if (mMap == null) {
return;
}
final LatLng center = new LatLng(location.getLatitude(),location.getLongitude());
final int newFloor = location.getFloorLevel();
if (mFloor != newFloor) {
updateRouteVisualization();
}
mFloor = newFloor;
showLocationCircle(center, location.getAccuracy());
if (mCameraPositionNeedsUpdating) {
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(center, 15.5f));
mCameraPositionNeedsUpdating = false;
}
}
};
/**
* Listener that changes overlay if needed
*/
private IARegion.Listener mRegionListener = new IARegion.Listener() {
#Override
public void onEnterRegion(final IARegion region) {
if (region.getType() == IARegion.TYPE_FLOOR_PLAN) {
Log.d(TAG, "enter floor plan " + region.getId());
mCameraPositionNeedsUpdating = true; // entering new fp, need to move camera
if (mGroundOverlay != null) {
mGroundOverlay.remove();
mGroundOverlay = null;
}
mOverlayFloorPlan = region; // overlay will be this (unless error in loading)
fetchFloorPlanBitmap(region.getFloorPlan());
//setupPoIs(mVenue.getPOIs(), region.getFloorPlan().getFloorLevel());
} else if (region.getType() == IARegion.TYPE_VENUE) {
mVenue = region.getVenue();
}
}
#Override
public void onExitRegion(IARegion region) {
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// prevent the screen going to sleep while app is on foreground
findViewById(android.R.id.content).setKeepScreenOn(true);
// instantiate IALocationManager
mIALocationManager = IALocationManager.create(this);
// Try to obtain the map from the SupportMapFragment.
((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map))
.getMapAsync(this);
Intent myIntent = new Intent(this, RangingActivity.class);
this.startActivity(myIntent);
Intent intent00 = getIntent();
LatLng center = intent00.getParcelableExtra("b");
Log.d(TAG,"Location!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + center);
}
#Override
protected void onDestroy() {
super.onDestroy();
// remember to clean up after ourselves
mIALocationManager.destroy();
}
/*Some blockingqueue---does not work
public class BlockinQueueExample
{
public void main(String[] args) throws Exception
{
BlockingQueue q = new ArrayBlockingQueue(1000);
RangingActivity producer = new RangingActivity(q);
WayfindingOverlayActivity consumer = new WayfindingOverlayActivity(q);
new Thread(producer).start();
new Thread(consumer).start();
}
}
WayfindingOverlayActivity(BlockingQueue q)
{
this.queue = q;
}
public void run() {
try{
queue.take();
Log.d(TAG,"BIANCABICA"+queue.take());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
*/
#Override
protected void onResume() {
super.onResume();
// start receiving location updates & monitor region changes
mIALocationManager.requestLocationUpdates(IALocationRequest.create(), mListener);
mIALocationManager.registerRegionListener(mRegionListener);
mIALocationManager.registerOrientationListener(
// update if heading changes by 1 degrees or more
new IAOrientationRequest(1, 0),
mOrientationListener);
if (mWayfindingDestination != null) {
mIALocationManager.requestWayfindingUpdates(mWayfindingDestination, mWayfindingListener);
}
}
EDIT , LAUNCHER ACTIVITY
package com.indooratlas.android.sdk.examples;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.indooratlas.android.sdk.examples.imageview.ImageViewActivity;
import com.indooratlas.android.sdk.examples.wayfinding.MonitoringActivity;
import com.indooratlas.android.sdk.examples.wayfinding.RangingActivity;
import com.indooratlas.android.sdk.examples.wayfinding.WayfindingOverlayActivity;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
import org.altbeacon.beacon.startup.BootstrapNotifier;
import org.altbeacon.beacon.startup.RegionBootstrap;
public class Bianca extends Activity implements BootstrapNotifier {
private static final String TAG = "RANGE";
private RegionBootstrap regionBootstrap;
private Button button;
private BackgroundPowerSaver backgroundPowerSaver;
private boolean haveDetectedBeaconsSinceBoot = false;
private MonitoringActivity monitoringActivity = null;
private String cumulativeLog = "";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
//--------------------------------meniu -------------------------------
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openAct();
}
});
Button button2 = findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openAct2();
}
});
Button button3 = findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openAct3();
}
});
Button button4 = findViewById(R.id.button4);
button4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openAct4();
}
});
//-----------------------------meniu----------------------------------
Notification.Builder builder = new Notification.Builder(this);
Intent intent = new Intent(this,WayfindingOverlayActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel = new NotificationChannel("My Notification Channel ID",
"My Notification Name", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("My Notification Channel Description");
NotificationManager notificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
builder.setChannelId(channel.getId());
}
beaconManager.enableForegroundServiceScanning(builder.build(), 456);
Log.d(TAG, "setting up background monitoring for beacons and power saving");
// wake up the app when a beacon is seen
Region region = new Region("backgroundRegion",
null, null, null);
regionBootstrap = new RegionBootstrap((BootstrapNotifier) this, region);
backgroundPowerSaver = new BackgroundPowerSaver(this);
}
public void openAct()
{
Intent intent = new Intent(this, WayfindingOverlayActivity.class);
startActivity(intent);
}
public void openAct2()
{
Intent intent2 = new Intent(this, RangingActivity.class);
startActivity(intent2);
}
public void openAct3()
{
Intent intent4 = new Intent(this, ImageViewActivity.class);
startActivity(intent4);
}
public void openAct4()
{
Intent intent5 = new Intent(this,RegionsActivity.class);
startActivity(intent5);
}
public void disableMonitoring() {
if (regionBootstrap != null) {
regionBootstrap.disable();
regionBootstrap = null;
}
}
public void enableMonitoring() {
Region region = new Region("backgroundRegion",
null, null, null);
regionBootstrap = new RegionBootstrap((BootstrapNotifier) this, region);
}
public void didEnterRegion(Region arg0) {
// In this example, this class sends a notification to the user whenever a Beacon
// matching a Region (defined above) are first seen.
Log.d(TAG, "did enter region.");
if (!haveDetectedBeaconsSinceBoot) {
Log.d(TAG, "auto launching MainActivity");
// The very first time since boot that we detect an beacon, we launch the
// MainActivity
Intent intent = new Intent(this, WayfindingOverlayActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Important: make sure to add android:launchMode="singleInstance" in the manifest
// to keep multiple copies of this activity from getting created if the user has
// already manually launched the app.
this.startActivity(intent);
haveDetectedBeaconsSinceBoot = true;
} else {
if (monitoringActivity != null) {
// If the Monitoring Activity is visible, we log info about the beacons we have
// seen on its display
Log.d(TAG, "I see a beacon again");
} else {
// If we have already seen beacons before, but the monitoring activity is not in
// the foreground, we send a notification to the user on subsequent detections.
Log.d(TAG, "Sending notification.");
}
}
}
public void didExitRegion(Region arg0) {
Log.d(TAG,"I no longer see a beacon.");
}
#Override
public void didDetermineStateForRegion(int i, Region region) {
}
}
The second class is not fully posted , only where I make changes.
The intent in the second class is in the OnCreate part
The location is calculated in the logcat , the only problem is that the application is working in a loop
Please help me , I am stuck. Thanks
I guess, you only need to open RangingActivity from onCreate() of WayFindingOverlayActivity if center is null. This means, we need to open RangingActivity to get the value for center. Doing null check for the center will also ensure that the application doesn't go in loop and proceed when we have the value for center. The code in the onCreate() of WayFindingOverlayActivity may look like this :
// edited here
Bundle extras = getIntent().getExtras();
if(extras == null){
Intent myIntent = new Intent(this, RangingActivity.class);
this.startActivity(myIntent);
} else{
LatLng center = extras.getParcelable("b");
Log.d("Location!!", center);
// call showLocationCircle() to show the blue dot
showLocationCircle(center, yourAccuracyRadius);
}
The following code allows you to start a video player and play the video.
The problem is that the NavigationBar hides a piece of the video, I would like to make it transparent.
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Point;
import android.media.MediaPlayer;
import android.widget.MediaController;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.view.MotionEvent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.VideoView;
public class SimpleVideoStream extends Activity implements
MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener,
MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener {
private String TAG = getClass().getSimpleName();
private VideoView mVideoView = null;
private MediaPlayer mMediaPlayer = null;
private MediaController mMediaController = null;
private ProgressBar mProgressBar = null;
private String mVideoUrl;
private Boolean mShouldAutoClose = true;
private boolean mControls;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Bundle b = getIntent().getExtras();
mVideoUrl = b.getString("mediaUrl");
mShouldAutoClose = b.getBoolean("shouldAutoClose", true);
mControls = b.getBoolean("controls", true);
RelativeLayout relLayout = new RelativeLayout(this);
relLayout.setBackgroundColor(Color.BLACK);
RelativeLayout.LayoutParams relLayoutParam = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
relLayoutParam.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
mVideoView = new VideoView(this);
mVideoView.setLayoutParams(relLayoutParam);
relLayout.addView(mVideoView);
// Create progress throbber
mProgressBar = new ProgressBar(this);
mProgressBar.setIndeterminate(true);
// Center the progress bar
RelativeLayout.LayoutParams pblp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
pblp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
mProgressBar.setLayoutParams(pblp);
// Add progress throbber to view
relLayout.addView(mProgressBar);
mProgressBar.bringToFront();
setOrientation(b.getString("orientation"));
setContentView(relLayout, relLayoutParam);
play();
}
private void play() {
mProgressBar.setVisibility(View.VISIBLE);
Uri videoUri = Uri.parse(mVideoUrl);
try {
mVideoView.setOnCompletionListener(this);
mVideoView.setOnPreparedListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.setVideoURI(videoUri);
mMediaController = new MediaController(this);
mMediaController.setAnchorView(mVideoView);
mMediaController.setMediaPlayer(mVideoView);
if (!mControls) {
mMediaController.setVisibility(View.GONE);
}
mVideoView.setMediaController(mMediaController);
} catch (Throwable t) {
Log.d(TAG, t.toString());
}
}
private void setOrientation(String orientation) {
if ("landscape".equals(orientation)) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}else if("portrait".equals(orientation)) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
private Runnable checkIfPlaying = new Runnable() {
#Override
public void run() {
if (mVideoView.getCurrentPosition() > 0) {
// Video is not at the very beginning anymore.
// Hide the progress bar.
mProgressBar.setVisibility(View.GONE);
} else {
// Video is still at the very beginning.
// Check again after a small amount of time.
mVideoView.postDelayed(checkIfPlaying, 100);
}
}
};
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "Stream is prepared");
mMediaPlayer = mp;
mMediaPlayer.setOnBufferingUpdateListener(this);
mVideoView.requestFocus();
mVideoView.start();
mVideoView.postDelayed(checkIfPlaying, 0);
}
private void pause() {
Log.d(TAG, "Pausing video.");
mVideoView.pause();
}
private void stop() {
Log.d(TAG, "Stopping video.");
mVideoView.stopPlayback();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy triggered.");
stop();
}
private void wrapItUp(int resultCode, String message) {
Log.d(TAG, "wrapItUp was triggered.");
Intent intent = new Intent();
intent.putExtra("message", message);
setResult(resultCode, intent);
finish();
}
public void onCompletion(MediaPlayer mp) {
Log.d(TAG, "onCompletion triggered.");
stop();
if (mShouldAutoClose) {
wrapItUp(RESULT_OK, null);
}
}
public boolean onError(MediaPlayer mp, int what, int extra) {
StringBuilder sb = new StringBuilder();
sb.append("MediaPlayer Error: ");
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
sb.append("Not Valid for Progressive Playback");
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
sb.append("Server Died");
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
sb.append("Unknown");
break;
default:
sb.append(" Non standard (");
sb.append(what);
sb.append(")");
}
sb.append(" (" + what + ") ");
sb.append(extra);
Log.e(TAG, sb.toString());
wrapItUp(RESULT_CANCELED, sb.toString());
return true;
}
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.d(TAG, "onBufferingUpdate : " + percent + "%");
}
#Override
public void onBackPressed() {
// If we're leaving, let's finish the activity
wrapItUp(RESULT_OK, null);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
// The screen size changed or the orientation changed... don't restart the activity
super.onConfigurationChanged(newConfig);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (mMediaController != null)
mMediaController.show();
return false;
}
}
I tried to add this, but it does not work very well, the problem is that the progressBar overlaps the NavigationBar, when the device is in portrait mode.
#Override
public boolean onTouchEvent(MotionEvent event) {
if (mMediaController != null){
mMediaController.show();
this.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE
);
}
return false;
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
Hello I have 2 Activities, 2 apps each with their classes ( around 10 classes in total), which i want to combine. I have a functional alarm and an functional MediaPlayer. I want to start the mediaplayer when the time is to set off the alarm. The problem is my app crashes when it's time to ring.
The Media Player class:
package com.never.mediaalarmplayer;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.MediaController;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* Created by Never on 5/14/2017.
*/
public class MediaPlayer extends AppCompatActivity implements MediaController.MediaPlayerControl {
private ArrayList<Song> songList;
private ListView songView;
private MusicService musicSrv;
private Intent playIntent;
private boolean musicBound=false;
private MusicController controller;
private boolean paused=false, playbackPaused=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mediaplayer);
songView = (ListView)findViewById(R.id.song_list);
songList = new ArrayList<>();
getSongList();
Collections.sort(songList, new Comparator<Song>(){
public int compare(Song a, Song b){
return a.getTitle().compareTo(b.getTitle());
}
});
SongAdapter songAdt = new SongAdapter(this, songList);
songView.setAdapter(songAdt);
setController();
Button btn = (Button)findViewById(R.id.open_alarm);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MediaPlayer.this, Alarm.class));
}
});
}
//connect to the service
private ServiceConnection musicConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder)service;
//get service
musicSrv = binder.getService();
//pass list
musicSrv.setList(songList);
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
#Override
protected void onStart() {
super.onStart();
if(playIntent==null){
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
#Override
protected void onPause(){
super.onPause();
paused=true;
}
#Override
protected void onResume(){
super.onResume();
if(paused){
setController();
paused=false;
}
}
#Override
protected void onStop(){
controller.hide();
super.onStop();
}
public void songPicked(View view){
musicSrv.setSong(Integer.parseInt(view.getTag().toString()));
musicSrv.playSong();
if(playbackPaused){
setController();
playbackPaused=false;
}
controller.show(0);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//menu item selected
switch (item.getItemId()) {
case R.id.action_shuffle:
//shuffle
musicSrv.setShuffle();
break;
case R.id.action_end:
stopService(playIntent);
musicSrv=null;
System.exit(0);
break;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
stopService(playIntent);
musicSrv=null;
super.onDestroy();
}
public void getSongList() {
//retrieve song info
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
if(musicCursor!=null && musicCursor.moveToFirst()){
//get columns
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
//add songs to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
songList.add(new Song(thisId, thisTitle, thisArtist));
}
while (musicCursor.moveToNext());
}
}
private void setController(){
//set the controller up
controller = new MusicController(this);
controller.setPrevNextListeners(new View.OnClickListener() {
#Override
public void onClick(View v) {
playNext();
}
}, new View.OnClickListener(){
#Override
public void onClick(View v){
playPrev();
}
});
controller.setMediaPlayer(this);
controller.setAnchorView(findViewById(R.id.song_list));
controller.setEnabled(true);
}
//play next
private void playNext(){
musicSrv.playNext();
if(playbackPaused){
setController();
playbackPaused=false;
}
controller.show(0);
}
//play prev
private void playPrev(){
musicSrv.playPrev();
if(playbackPaused) {
setController();
playbackPaused = false;
}
controller.show(0);
}
#Override
public void start() {
musicSrv.go();
}
#Override
public void pause() {
playbackPaused=true;
musicSrv.pausePlayer();;
}
#Override
public int getDuration() {
if(musicSrv!=null &&musicBound&&musicSrv.isPng())
return musicSrv.getDur();
else
return 0;
}
#Override
public int getCurrentPosition() {
if(musicSrv!=null&&musicBound&&musicSrv.isPng())
return musicSrv.getPosn();
else
return 0;
}
#Override
public void seekTo(int pos) {
musicSrv.seek(pos);
}
#Override
public boolean isPlaying() {
if(musicSrv!=null&&musicBound)
return musicSrv.isPng();
else
return false;
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
}
Alarm Receiver class:
package com.never.mediaalarmplayer;
import android.content.Context;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.content.WakefulBroadcastReceiver;
/**
* Created by Never on 4/29/2017.
*/
public class AlarmReceiver extends WakefulBroadcastReceiver{
private static Ringtone ringtone = null;
#Override
public void onReceive(Context context, Intent intent) {
Alarm.getTextView2().setText("It's time to wake up!");
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
ringtone = RingtoneManager.getRingtone(context, uri);
// ringtone.play();
MediaPlayer ms = new MediaPlayer();
ms.onStart();
}
public static void stopRingtone() {
ringtone.stop();
}
}
And the Alarm class:
package com.never.mediaalarmplayer;
import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Message;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
import java.util.Calendar;
public class Alarm extends AppCompatActivity {
private static int timeHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
private static int timeMinute = Calendar.getInstance().get(Calendar.MINUTE);
TextView textView1;
private static TextView textView2;
public static TextView getTextView2(){
return textView2;
}
AlarmManager alarmManager;
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setam layoutul pe care ne uitam si pe care lucram
setContentView(R.layout.activity_alarm);
// spunem ca textView1 este textviewul cu id-ul msg1
textView1 = (TextView)findViewById(R.id.msg1);
// afisam ora curenta
if(timeHour>9&&timeMinute>9)
textView1.setText(timeHour + ":" + timeMinute);
else if(timeHour>9&&timeMinute<=9)
textView1.setText(timeHour + ":" + "0" + timeMinute);
else if(timeHour<=9&&timeMinute>9)
textView1.setText("0" + timeHour + ":" + timeMinute);
else if(timeHour<=9&&timeMinute<=9)
textView1.setText("0" + timeHour + ":" + "0" + timeMinute);
textView2 = (TextView) findViewById(R.id.msg2);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent myIntent = new Intent (Alarm.this,AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(Alarm.this,0,myIntent,0);
OnClickListener listener1 = new OnClickListener(){
#Override
public void onClick(View v) {
textView2.setText("");
Bundle bundle = new Bundle();
bundle.putInt(MyConstants.HOUR, timeHour);
bundle.putInt(MyConstants.MINUTE, timeMinute);
MyDialogFragment fragment = new MyDialogFragment(new MyHandler());
fragment.setArguments(bundle);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(fragment, MyConstants.TIME_PICKER);
transaction.commit();
}
};
Button btn1 = (Button)findViewById(R.id.button1);
btn1.setOnClickListener(listener1);
OnClickListener listener2 = new OnClickListener() {
#Override
public void onClick(View v) {
textView2.setText("");
cancelAlarm();
}
};
Button btn2 = (Button)findViewById(R.id.button2);
btn2.setOnClickListener(listener2);
Button btn = (Button)findViewById(R.id.open_mp);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Alarm.this, MediaPlayer.class));
}
});
}
//A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue.
//There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
//Practic folosim un handler pentru a afisa ora la care am setat alarma dupa ce am setat-o
class MyHandler extends Handler
{
#Override
public void handleMessage (Message msg){
//A mapping from String keys to various Parcelable values.
//Bundle getBundle (String key)
//Returns the value associated with the given key, or null if no mapping of the desired type exists for the given key or a null value is explicitly associated with the key.
Bundle bundle = msg.getData();
//preluam ora si minutul la care am setat alarma
timeHour=bundle.getInt(MyConstants.HOUR);
timeMinute = bundle.getInt(MyConstants.MINUTE);
//afisam ora la care am setat alarma
if(timeHour>9&&timeMinute>9)
textView1.setText(timeHour + ":" + timeMinute);
else if(timeHour>9&&timeMinute<=9)
textView1.setText(timeHour + ":" + "0" + timeMinute);
else if(timeHour<=9&&timeMinute>9)
textView1.setText("0" + timeHour + ":" + timeMinute);
else if(timeHour<=9&&timeMinute<=9)
textView1.setText("0" + timeHour + ":" + "0" + timeMinute);
setAlarm();
}
}
#TargetApi(Build.VERSION_CODES.KITKAT)
private void setAlarm(){
// getInstance()
//Gets a calendar using the default time zone and locale.
Calendar calendar = Calendar.getInstance();
// set(int field, int value)
// Sets the given calendar field to the given value.
calendar.set(Calendar.HOUR_OF_DAY,timeHour);
calendar.set(Calendar.MINUTE,timeMinute);
// setExact(int type, long triggerAtMillis, PendingIntent operation)
// Schedules the alarm and if there is already an alarm by the intent then previous one will be canceled.
//RTC_WAKEUP
//It is used to fire pending intent at specified time forcing the phone to wake up.
//Practic prin linia asta de cod setam alarma si verificam daca ora curenta este egala cu ora programata pentru trezire si in caz afirmativ trimitem semnalul(pendingintent) ce este legat la intent astfel stim ca trebuie trimis catre AlarmRceiver, in acelasi timp ii spunem sa "trezeasca" telefonul
alarmManager.setExact(
//ii spunem sa "trezeasca telefonul" in cazul in care trebuie sa sune alarma
AlarmManager.RTC_WAKEUP,
// preluam ora la care setam alarma si retinem totul transformat in milisecunde
calendar.getTimeInMillis(),
//verificam daca este timpul sa sunam alarma
pendingIntent);
}
private void cancelAlarm(){
if(alarmManager!=null){
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();
AlarmReceiver.stopRingtone();
}
}
}
The Exception:
07-11 10:43:43.392 1915-1915/com.never.mediaalarmplayer D/Ringtone: Successfully created local player
07-11 10:43:43.397 1915-1915/com.never.mediaalarmplayer D/AndroidRuntime: Shutting down VM
07-11 10:43:43.397 1915-1915/com.never.mediaalarmplayer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.never.mediaalarmplayer, PID: 1915
java.lang.RuntimeException: Unable to start receiver com.never.mediaalarmplayer.AlarmReceiver: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.Application.dispatchActivityStarted(android.app.Activity)' on a null object reference
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2732)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.Application.dispatchActivityStarted(android.app.Activity)' on a null object reference
at android.app.Activity.onStart(Activity.java:1146)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:595)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at com.never.mediaalarmplayer.MediaPlayer.onStart(MediaPlayer.java:78)
at com.never.mediaalarmplayer.AlarmReceiver.onReceive(AlarmReceiver.java:23)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2725)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
It is my first time posting so if there is any problem with the post i will edit it also thank you very much.
Acitivities are not started like this as you are doing in your AlarmReceiver class's onReceive i.e.
MediaPlayer ms = new MediaPlayer();
They are started by Context.startActivity (Intent). It is android system which is supposed to start the activities as it manages a stack of activities and posts life-cycle callbacks for the them. Since you start activity yourself so you miss the initial life cycle callbacks e. g. onCreate.
I'd like to check GPS both when the app is started and when the refresh button is hit, and use those data points, in the form of mLatitude and mLongitude to call the weather api. Eventually I'm going to geocode the city but right now for debugging purposes I'm outputting the GPS coordinates to the locationLabel textview.
my MainActivity.java:
package com.example.paxie.stormy.ui;
import android.Manifest;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.example.paxie.stormy.GPS_Service;
import com.example.paxie.stormy.R;
import com.example.paxie.stormy.weather.Current;
import com.example.paxie.stormy.weather.Day;
import com.example.paxie.stormy.weather.Forecast;
import com.example.paxie.stormy.weather.Hour;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
public static final String DAILY_FORECAST = "DAILY_FORECAST";
public static final String HOURLY_FORECAST = "HOURLY_FORECAST";
private Forecast mForecast;
private double mLatitude;
private double mLongitude;
private BroadcastReceiver broadcastReceiver;
#Bind(R.id.timeLabel)
TextView mTimeLabel;
#Bind(R.id.temperatureLabel)
TextView mTemperatureLabel;
#Bind(R.id.humidityValue)
TextView mHumidityValue;
#Bind(R.id.precipValue)
TextView mPrecipValue;
#Bind(R.id.summaryLabel)
TextView mSummaryLabel;
#Bind(R.id.iconImageView)
ImageView mIconImageView;
#Bind(R.id.refreshImageView)
ImageView mRefreshImageView;
#Bind(R.id.progressBar)
ProgressBar mProgressBar;
#Bind(R.id.locationLabel)
TextView mLocationlabel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mProgressBar.setVisibility(View.INVISIBLE);
mRefreshImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getForecast();
}
});
getForecast();
Log.d(TAG, "Main UI code is running!");
}
private void getForecast() {
if(!runtime_permissions())
checkGPS();
String apiKey = "1621390f8c36997cb1904914b726df52";
String forecastUrl = "https://api.forecast.io/forecast/" + apiKey +
"/" + mLatitude + "," + mLongitude;
if (isNetworkAvailable()) {
toggleRefresh();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(forecastUrl)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
toggleRefresh();
}
});
alertUserAboutError();
}
#Override
public void onResponse(Response response) throws IOException {
runOnUiThread(new Runnable() {
#Override
public void run() {
toggleRefresh();
}
});
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mForecast = parseForecastDetails(jsonData);
runOnUiThread(new Runnable() {
#Override
public void run() {
updateDisplay();
}
});
} else {
alertUserAboutError();
}
} catch (IOException e)
{
Log.e(TAG, "Exception caught: ", e);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
} else {
Toast.makeText(this, "Network is currently unavailable!", Toast.LENGTH_LONG).show();
}
}
private void toggleRefresh() {
if (mProgressBar.getVisibility() == View.INVISIBLE) {
mProgressBar.setVisibility(View.VISIBLE);
mRefreshImageView.setVisibility(View.INVISIBLE);
} else {
mProgressBar.setVisibility(View.INVISIBLE);
mRefreshImageView.setVisibility(View.VISIBLE);
}
}
private void updateDisplay() {
mLocationlabel.setText(mLatitude + " " + mLongitude);
Current current = mForecast.getCurrent();
mTemperatureLabel.setText(current.getTemperature() + "");
mTimeLabel.setText("At " + current.getFormattedTime() + " it will be:");
mHumidityValue.setText(current.getHumidity() + "");
mPrecipValue.setText(current.getPrecipChance() + "%");
mSummaryLabel.setText(current.getSummary());
Drawable drawable = ContextCompat.getDrawable(this, current.getIconId());
mIconImageView.setImageDrawable(drawable);
}
private Forecast parseForecastDetails(String jsonData) throws JSONException {
Forecast forecast = new Forecast();
forecast.setCurrent(getCurrentDetails(jsonData));
forecast.setHourlyForecast(getHourlyForecast(jsonData));
forecast.setDailyForecast(getDailyForecast(jsonData));
return forecast;
}
private Day[] getDailyForecast(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
JSONObject daily = forecast.getJSONObject("daily");
JSONArray data = daily.getJSONArray("data");
Day[] days = new Day[data.length()];
for (int i = 0; i < data.length(); i++) {
JSONObject jsonDay = data.getJSONObject(i);
Day day = new Day();
day.setSummary(jsonDay.getString("summary"));
day.setIcon(jsonDay.getString("icon"));
day.setTemperatureMax(jsonDay.getDouble("temperatureMax"));
day.setTime(jsonDay.getLong("time"));
day.setTimeZone(timezone);
days[i] = day;
}
return days;
}
private Hour[] getHourlyForecast(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
JSONObject hourly = forecast.getJSONObject("hourly");
JSONArray data = hourly.getJSONArray("data");
Hour[] hours = new Hour[data.length()];
for (int i = 0; i < data.length(); i++) {
JSONObject jsonHour = data.getJSONObject(i);
Hour hour = new Hour();
hour.setSummary(jsonHour.getString("summary"));
hour.setTemperature(jsonHour.getDouble("temperature"));
hour.setIcon(jsonHour.getString("icon"));
hour.setTime(jsonHour.getLong("time"));
hour.setTimeZone(timezone);
hours[i] = hour;
}
return hours;
}
private Current getCurrentDetails(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
Log.i(TAG, "From JSON: " + timezone);
JSONObject currently = forecast.getJSONObject("currently");
Current current = new Current();
current.setHumidity(currently.getDouble("humidity"));
current.setTime(currently.getLong("time"));
current.setIcon(currently.getString("icon"));
current.setPrecipChance(currently.getDouble("precipProbability"));
current.setSummary(currently.getString("summary"));
current.setTemperature(currently.getDouble("temperature"));
current.setTimeZone(timezone);
Log.d(TAG, current.getFormattedTime());
return current;
}
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
private void alertUserAboutError() {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(getFragmentManager(), "error_dialog");
}
#OnClick(R.id.dailyButton)
public void startDailyActivity(View view) {
Intent intent = new Intent(this, DailyForecastActivity.class);
intent.putExtra(DAILY_FORECAST, mForecast.getDailyForecast());
startActivity(intent);
}
#OnClick(R.id.hourlyButton)
public void startHourlyActivity(View view) {
Intent intent = new Intent(this, HourlyForecastActivity.class);
intent.putExtra(HOURLY_FORECAST, mForecast.getHourlyForecast());
startActivity(intent);
}
private void checkGPS() {
if (broadcastReceiver == null) {
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
mLatitude = (double) intent.getExtras().get("latitude");
mLongitude = (double) intent.getExtras().get("longitude");
}
};
}
registerReceiver(broadcastReceiver, new IntentFilter("location_update"));
}
private boolean runtime_permissions() {
if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 100);
return true;
}
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
getForecast();
} else {
runtime_permissions();
}
}
}
#Override
protected void onResume() {
super.onResume();
checkGPS();
}
}
my GPSservice.java:
package com.example.paxie.stormy;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
/**
* Created by paxie on 10/27/16.
*/
public class GPS_Service extends Service {
private LocationListener listener;
private LocationManager locationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location_update");
i.putExtra("coordinates",location.getLongitude()+" "+location.getLatitude());
i.putExtra("longitude", location.getLongitude());
i.putExtra("latitude", location.getLatitude());
sendBroadcast(i);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
//noinspection MissingPermission
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,3000,0,listener);
}
#Override
public void onDestroy() {
super.onDestroy();
if(locationManager != null){
//noinspection MissingPermission
locationManager.removeUpdates(listener);
}
}
}
Here are two things you can try:
1. Please ensure you have included the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions in your manifest. If your app targets Android API 23 and above, you will need to include runtime permission handling.
2. Instead of having a LocationListener object as a class member, you should have your Service implement it as an interface and implement its onLocationChanged() method.
Apart from this, you really should consider using the location APIs' in Google Play Services, rather than those in AOSP (i.e. android.location).
See Making Your App Location-Aware