I am a beginner in android and right now working on a music streaming app. I have taken a course on Udemy for beginners for that and
the instructor goes line by line showing each step of creation,and i do exactly what he does. Now that we have reached the step of creating a notification for the
app, he uses something called 'NotificationCompat.Builder(this)'. Now when I type the same exact code, I get an error saying that the
NotificationCompat.Builder(context) has been deprecated now in android O. Due to this I am not getting the notifications on my phone when I
run it. Also the music is not being streamed. Due to this I am not able to proceed with further lectures.
I tried to ask the instructor on the forum for some help regarding this, but he does not seem to reply back. Also I tried to research
about the notification channels in android O, but I am unable to understand the concepts due to the lack of knowledge on basic android.
So it would be great if I could get some help regarding my problem.
I am uploading my code along with this.
The error is in PlayerService.java
(1). activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.music.zirakmistry.musicstreamingapp.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_media_play" />
</android.support.design.widget.CoordinatorLayout>
(2). MainActivity.java
public class MainActivity extends AppCompatActivity {
static FloatingActionButton playPauseButton;
PlayerService mBoundService;
boolean mServiceBound=false;
private ServiceConnection mServiceConnection=new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
PlayerService.MyBinder myBinder=(PlayerService.MyBinder)service;
mBoundService=myBinder.getService();
mServiceBound=true;
}
#Override
public void onServiceDisconnected(ComponentName name){
mServiceBound=false;
}
};
private BroadcastReceiver mMessageReceiver=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean isPlaying=intent.getBooleanExtra("isPlaying",false);
flipPlayPauseButton(isPlaying);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
playPauseButton = (FloatingActionButton) findViewById(R.id.fab);
playPauseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view){
if(mServiceBound)
mBoundService.togglePlayer();
}
});
startStreamingService("https://www.mymusicstreamingapp.com/music_app/cute.mp3");
}
private void startStreamingService(String url)
{
Intent i=new Intent(this,PlayerService.class);
i.putExtra("url",url);
i.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(i);
bindService(i,mServiceConnection,Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
if(mServiceBound){
unbindService(mServiceConnection);
mServiceBound=false;
}
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,new IntentFilter("changePlayButton"));
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
public static void flipPlayPauseButton(boolean isPlaying){
if(isPlaying){
playPauseButton.setImageResource(android.R.drawable.ic_media_pause);
}
else{
playPauseButton.setImageResource(android.R.drawable.ic_media_play);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
(3). PlayerService.java
public class PlayerService extends Service {
MediaPlayer mediaPlayer=new MediaPlayer();
private final IBinder mBinder=new MyBinder();
public class MyBinder extends Binder
{
PlayerService getService()
{
return PlayerService.this;
}
}
public PlayerService()
{
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
if(intent.getStringArrayExtra("url")!=null)
playStream(intent.getStringExtra("url"));
if(intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION))
{
Log.i("info","Start foregroung service");
showNotification();
}
else if(intent.getAction().equals(Constants.ACTION.PREV_ACTION))
{
Log.i("info","Prev pressed");
}
else if(intent.getAction().equals(Constants.ACTION.PLAY_ACTION))
{
Log.i("info","Play pressed");
}
else if(intent.getAction().equals(Constants.ACTION.NEXT_ACTION))
{
Log.i("info","Next pressed");
}
else if(intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION))
{
Log.i("info","Stop foreground received");
stopForeground(true);
stopSelf();
}
return START_REDELIVER_INTENT;
}
private void showNotification()
{
Intent notificationIntent=new Intent(this,MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags((Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK));
PendingIntent pendingIntent=PendingIntent.getActivity(this,0,notificationIntent,0);
Intent previousIntent=new Intent(this,MainActivity.class);
previousIntent.setAction(Constants.ACTION.PREV_ACTION);
PendingIntent ppreviousIntent=PendingIntent.getActivity(this,0,previousIntent,0);
Intent playIntent=new Intent(this,MainActivity.class);
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
PendingIntent pplayIntent=PendingIntent.getActivity(this,0,playIntent,0);
Intent nextIntent=new Intent(this,MainActivity.class);
nextIntent.setAction(Constants.ACTION.NEXT_ACTION);
PendingIntent pnextIntent=PendingIntent.getActivity(this,0,nextIntent,0);
Bitmap icon= BitmapFactory.decodeResource(getResources(),R.drawable.logo);
Notification notification=new NotificationCompat.Builder(this)
.setContentTitle("Music Player")
.setTicker("Playing music")
.setContentText("My Song")
.setSmallIcon(R.drawable.logo)
.setLargeIcon(Bitmap.createScaledBitmap(icon,128,128,false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.addAction(android.R.drawable.ic_media_previous,"Previous",ppreviousIntent)
.addAction(android.R.drawable.ic_media_play,"Play",pplayIntent)
.addAction(android.R.drawable.ic_media_next,"Next",pnextIntent)
.build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,notification);
}
#Override
public IBinder onBind(Intent intent)
{
return mBinder;
}
public void playStream(String url)
{
if(mediaPlayer!=null)
{
try
{
mediaPlayer.stop();
}
catch(Exception e)
{
}
mediaPlayer=null;
}
mediaPlayer=new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try
{
mediaPlayer.setDataSource(url);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
playPlayer();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
flipPlayPauseButton(false);
}
});
mediaPlayer.prepareAsync();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void pausePlayer()
{
try
{
mediaPlayer.pause();
flipPlayPauseButton(false);
}
catch(Exception e)
{
Log.d("EXCEPTION","failed to pause media player");
}
}
public void playPlayer()
{
try
{
mediaPlayer.start();
flipPlayPauseButton(true);
}
catch(Exception e)
{
Log.d("EXCEPTION","failed to pause media player");
}
}
public void flipPlayPauseButton(boolean isPlaying)
{
// code to communicate with main thread
Intent intent=new Intent("changePlayButton");
//add data
intent.putExtra("isPlaying",isPlaying);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
public void togglePlayer()
{
try
{
if(mediaPlayer.isPlaying())
pausePlayer();
else
playPlayer();
}
catch(Exception e)
{
Log.d("Exception","failed to toggle media player");
}
}
}
(4). Player.java
public class Player {
MediaPlayer mediaPlayer=new MediaPlayer();
public static Player player;
String url="";
public Player()
{
this.player = this;
}
public void playStream(String url)
{
if(mediaPlayer!=null)
{
try
{
mediaPlayer.stop();
}
catch(Exception e)
{
}
mediaPlayer=null;
}
mediaPlayer=new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try
{
mediaPlayer.setDataSource(url);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
playPlayer();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
MainActivity.flipPlayPauseButton(false);
}
});
mediaPlayer.prepareAsync();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void pausePlayer()
{
try
{
mediaPlayer.pause();
MainActivity.flipPlayPauseButton(false);
}
catch(Exception e)
{
Log.d("EXCEPTION","failed to pause media player");
}
}
public void playPlayer()
{
try
{
mediaPlayer.start();
MainActivity.flipPlayPauseButton(true);
}
catch(Exception e)
{
Log.d("EXCEPTION","failed to pause media player");
}
}
public void togglePlayer()
{
try
{
if(mediaPlayer.isPlaying())
pausePlayer();
else
playPlayer();
}
catch(Exception e)
{
Log.d("Exception","failed to toggle media player");
}
}
}
(5). Constants.java
public class Constants {
public interface ACTION {
public static String MAIN_ACTION="com.music.zirakmistry.musicstreamingapp.action.main";
public static String PREV_ACTION="com.music.zirakmistry.musicstreamingapp.action.prev";
public static String PLAY_ACTION="com.music.zirakmistry.musicstreamingapp.action.play";
public static String NEXT_ACTION="com.music.zirakmistry.musicstreamingapp.action.next";
public static String STARTFOREGROUND_ACTION="com.music.zirakmistry.musicstreamingapp.action.startforeground";
public static String STOPFOREGROUND_ACTION="com.music.zirakmistry.musicstreamingapp.action.stopforeground";
}
public interface NOTIFICATION_ID
{
public static int FOREGROUND_SERVICE=101;
}
}
(6). AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.music.zirakmistry.musicstreamingapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".PlayerService"
android:enabled="true"
android:exported="true" />
</application>
</manifest>
In order to facilitate the new feature called Notification Channels in Android Oreo the previous method was deprecated.
Notification Channels allow us to group notifications based on their intended behavior. So whenever a user don't need to see a specific type of notification they can disable the corresponding channel.
So for example consider an e-commerce app. It shows notifications for promotions/offers, order status, etc. Promotion and offer notifications are grouped into a channel named "promotion". So if the user don't want to see only these notifications they can disable the "promotion" channel from the app settings.
If you use the deprecated method, the notification will fail silently in Oreo. To make it work, use the new Builder constructor. Change your code as below:
Notification notification=new NotificationCompat.Builder(this, CHANNEL_ID)
// set title, message, etc.
.build();
And create a notification channel like this for Oreo:
NotificationManager manager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Support for Android Oreo: Notification Channels
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"Channel_name_to_be_displayed_in_Settings",
NotificationManager.IMPORTANCE_DEFAULT);
manager.createNotificationChannel(channel);
}
Related
I want to run my android application always in background like whatsapp,truecaller i have used all things but when device is reboot the application is stop running in background for that i have used broadcast receiver to listen boot. here is my code.
My Service
public class Myservice extends Service {
File file;
private static String fileName = null;
private MediaRecorder recorder = null;
boolean mStartRecording = true;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
Intent intent = new Intent("RestartService");
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
onTaskRemoved(intent);
file = new File(Environment.getExternalStorageDirectory(), "pranay");
if (!file.exists()) {
boolean mkdir = file.mkdirs();
if (!mkdir) {
Toast.makeText(this, "Fialed", Toast.LENGTH_SHORT).show();
}
}
fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/pranay/" + UUID.randomUUID().toString() + "sample.mp3";
Log.i("msg", "running");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
String channel = "pranay";
NotificationChannel notificationChannel = new NotificationChannel("id", channel, NotificationManager.IMPORTANCE_NONE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
Notification notification = new NotificationCompat.Builder(this, "id")
.setContentTitle("sa")
.setContentText("ssa")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
TelephonyManager manager1 = (TelephonyManager) getApplicationContext().getSystemService(getApplicationContext().TELEPHONY_SERVICE);
manager1.listen(new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String phoneNumber) {
super.onCallStateChanged(state, phoneNumber);
if (TelephonyManager.EXTRA_STATE_IDLE.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE))) {
cleanup();
} else if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
try {
recorder.prepare();
} catch (IOException e) {
Log.e("msg", "prepare() failed");
}
recorder.start();
mStartRecording = true;
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
return super.onStartCommand(intent,flags,startId);
}
private void startForeground(Notification notification, String id) {
startForeground(notification, id);
}
private void cleanup(){
if(recorder!=null)
{
try {
recorder.stop();
}catch (Exception e){
Log.e("msg",String.valueOf(e.getMessage()));
}finally {
recorder.release();
recorder=null;
}
stopSelf();
mStartRecording = false;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(),this.getClass());
restartServiceIntent.setPackage(getPackageName());
startService(restartServiceIntent);
super.onTaskRemoved(rootIntent);
}
}
Broad cast receiver
public class Receiver extends BroadcastReceiver {
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Toast.makeText(context,"Booted",Toast.LENGTH_SHORT).show();
Intent serviceIntent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(serviceIntent);
}
}
Manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".Receiver"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="RestartService"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="android.intent.action.REBOOT"/>
</intent-filter>
</receiver>
<service android:name=".Myservice"/>
I am using android 10 and pie is it working on this versions?
You can use JobService android.intent.action.BOOT_COMPLETED this method is not worked on latest version of Android.
JobService
public MyJobService extends JobService {
private Handler myHandler = new Handler(new Handler.Callback() {
#Override
public boolean handler(Message msg) {
Log.e("TAG", "Does it run after reboot? ");
return true;
}
});
#Override
public boolean onStartJob(JobParameters params) {
myHandler.sendMessage(Message.obtain(myHandler, 1, params));
return true;
}
#Override
public boolean onStopJob(JobParameters params) {
myHandler.removeMessages(1);
}
}
MainActivity
MainActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle saveInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
ComponentName serviceComponent = new ComponentName(this,MyJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);
builder.setMinimumLatency(1 * 1000);
builder.setOverrideDeadline(5 * 1000);
builder.setPersisted(true);
JobScheduler jobScheduler = (JobScheduler) getSystemService(this.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="you.package.name">
<application
..............
>
<service
android:name=".your.package.MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
</mainfest>
In my app there is a media player which is playing streamed url.
The player starts in oncreate method when the connection to internet is available.I have a broadcast receiver which checks the connection to the internet and notify the user. I am facing a problem here that when my app shifts from Wifi to cellular network, media player should take a little pause and starts again because the network is available again. But i'am unable to find the logic that how can i achieve this?
Here is my sample code,Kindly solve the issue?
Any help will be grateful.
Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name=".receivers.NetworkChangeReciever">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Main Activity:
private BroadcastReceiver mNetworkReceiver;
static TextView tv_check_connection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_check_connection=(TextView) findViewById(R.id.tv_check_connection);
mNetworkReceiver = new NetworkChangeReciever();
registerNetworkBroadcastForNougat();
// checkNetworkStatus();
mSelectedTrackTitle = (TextView) findViewById(R.id.selected_track_title);
nowplaying = (TextView) findViewById(R.id.nowplaying);
mPlayerControl = (ImageView) findViewById(R.id.player_control);
mPlayerControl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
togglePlayPause();
}
});
mSelectedTrackTitle.setText("FM World Pakistan");
nowplaying.setText("Now Playing");
mPlayerControl.setImageResource(R.drawable.ic_pause_circle_filled);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mMediaPlayer.setDataSource(url);
mMediaPlayer.prepare();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mMediaPlayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
nowplaying.setText("Offline");
Toast.makeText(MainActivity.this, "Radio Offline", Toast.LENGTH_LONG).show();
mPlayerControl.setImageResource(R.drawable.ic_play_circle_filled);
}
public static void dialog(boolean value){
if(value){
tv_check_connection.setText("We are back !!!");
tv_check_connection.setBackgroundResource(R.color.neton);
tv_check_connection.setTextColor(Color.WHITE);
Handler handler = new Handler();
Runnable delayrunnable = new Runnable() {
#Override
public void run() {
tv_check_connection.setVisibility(View.GONE);
}
};
handler.postDelayed(delayrunnable, 3000);
}else {
tv_check_connection.setVisibility(View.VISIBLE);
tv_check_connection.setText("Could not connect to Internet.");
tv_check_connection.setBackgroundResource(R.color.colorAccent);
tv_check_connection.setTextColor(Color.WHITE);
nowplaying.setText("Buffering...");
mPlayerControl.setImageResource(R.drawable.ic_play_circle_filled);
}
}
private void registerNetworkBroadcastForNougat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
protected void unregisterNetworkChanges() {
try {
unregisterReceiver(mNetworkReceiver);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
private void togglePlayPause() {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
nowplaying.setText("Offline");
mPlayerControl.setImageResource(R.drawable.ic_play_circle_filled);
} else {
mMediaPlayer.start();
nowplaying.setText("Now Playing");
mPlayerControl.setImageResource(R.drawable.ic_pause_circle_filled);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterNetworkChanges();
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer = null;
}
}
Receiver Class:
public class NetworkChangeReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try
{
if (isOnline(context)) {
dialog(true);
Log.e("Hi", "Online Connect Intenet ");
} else {
dialog(false);
Log.e("Sorry","Conectivity Failure !!! ");
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
private boolean isOnline(Context context) {
try {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
}
I found a solution as, if media player is declared as static; we can reinitialize it in dialog()
public static void dialog(boolean value){
if(value){
tv_check_connection.setText("We are back !!!");
tv_check_connection.setBackgroundResource(R.color.neton);
tv_check_connection.setTextColor(Color.WHITE);
//recreate media player
Handler handler = new Handler();
Runnable delayrunnable = new Runnable() {
#Override
public void run() {
tv_check_connection.setVisibility(View.GONE);
}
};
handler.postDelayed(delayrunnable, 3000);
}else {
tv_check_connection.setVisibility(View.VISIBLE);
tv_check_connection.setText("Could not connect to Internet.");
tv_check_connection.setBackgroundResource(R.color.colorAccent);
tv_check_connection.setTextColor(Color.WHITE);
nowplaying.setText("Buffering...");
mPlayerControl.setImageResource(R.drawable.ic_play_circle_filled);
//pause media player
}
}
I want to force app to end if user disable his internet connection during running of app
I tried this code and work good at the begining of app but when I disable internet during running it isnt closed!
this is my code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log_reg);
if(!isNetworkAvailable(this)) {
Toast.makeText(this,"No Internet connection",Toast.LENGTH_LONG).show();
finish(); //Calling this method to close this activity when internet is not available.
}
register_btn = (Button)findViewById(R.id.registerbtn);
register_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(LogRegActivity.this,RegisterActivity.class);
startActivity(i);
}
});
login_btn=(Button)findViewById(R.id.loginbtn);
login_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i =new Intent(LogRegActivity.this,LoginActivity.class);
startActivity(i);
}
});
}
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(conMan.getActiveNetworkInfo() != null && conMan.getActiveNetworkInfo().isConnected())
return true;
else
return false;
}
}
this is my build.gradle when i used broadcast receiver it shows that using reciever is deprecated for N or higher how can i fix this problem??
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
android {
compileSdkVersion 27
defaultConfig {
applicationId "net.amr.myapplication"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
Use broadcast receiver for connectivity change, here is steps for achieve this:
Step 1 : register receiver in manifest.xml
<receiver android:name="NetworkChangeReceiver ">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Step 2 : Create broadcast receiver :
public class NetworkChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
if(checkInternet(context))
{
Toast.makeText(context, "Network Available",Toast.LENGTH_LONG).show();
}
}
boolean checkInternet(Context context) {
ServiceManager serviceManager = new ServiceManager(context);
if (serviceManager.isNetworkAvailable()) {
return true;
} else {
return false;
}
}
}
Step 3 : Broadcast receiver which will handle network change:
public class HandleNetwork extend AppcompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerNetworkBroadcastForNougat();
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (isNetworkAvailable(this)) {
//logic on network enable
} else {
//logic on network disable
}
public static boolean isNetworkAvailable(Context context) {
if (context == null) return false;
try {
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService
(Context.CONNECTIVITY_SERVICE);
if (connManager.getActiveNetworkInfo() != null && connManager.getActiveNetworkInfo()
.isAvailable() && connManager.getActiveNetworkInfo().isConnected()) {
return true;
}
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
return false;
}
//Register receiver
private void registerNetworkBroadcastForNougat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
registerReceiver(mMessageReceiver , new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
registerReceiver(mMessageReceiver , new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
protected void unregisterNetworkChanges() {
try {
unregisterReceiver(mNetworkReceiver);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterNetworkChanges();
}
}
}
Hope it will help you!!
You need to register a broadcast receiver for CONNECTIVITY_ACTION. There you can check for the state of the connection.
Also see the official documentation.
You need to create one activity and and open that activity with following flags and then finish it by calling finish() in onCreate() of created activity.
add following code where you are checking internet connectivity
startActivity(new Intent(this, NoInternetActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)))
in NoInternetActivity activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
finish();
}
and don't forget to add NoInternetActivity in manifest
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I have been trying to create a basic flashlight app using an image button (beginner). Where i have no syntax errors in the code but do have have some NULL pointer exception in the run time.
Here is my main activity class :-
public class FlashLight extends Activity{
Camera camera = null;
Parameters params = null;
boolean isFlashOn = false;
boolean hasFlash;
ImageButton btnSwitch = (ImageButton) findViewById(R.id.imageButton1);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hasFlash = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if(!hasFlash)
{
AlertDialog alert = new AlertDialog.Builder(FlashLight.this).create();
alert.setTitle("Error");
alert.setMessage("Application Not Supported");
alert.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// closing the application
finish();
}
});
return;
}
// get the camera
getCamera();
// displaying button image
toggleButtonImage();
// Switch button click event to toggle flash on/off
btnSwitch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isFlashOn) {
// turn off flash
turnOffFlash();
} else {
// turn on flash
turnOnFlash();
}
}
});
}
private void getCamera() {
if(camera == null)
{
try{
camera = Camera.open();
params = camera.getParameters();
}
catch (RuntimeException e) {
Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
}
}
}
private void toggleButtonImage() {
try{
if(isFlashOn){
btnSwitch.setImageResource(R.drawable.switchon);
}else{
btnSwitch.setImageResource(R.drawable.switchoff);
}
}
catch(RuntimeException e){
Log.e("Could not toggle Button image ", e.getMessage());
}
}
private void turnOnFlash() {
try{
if (!isFlashOn) {
if (camera == null || params == null) {
return;
}
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
camera.startPreview();
isFlashOn = true;
// changing button/switch image
toggleButtonImage();
}
}
catch(RuntimeException e){
Log.e("Could not turn on Flash ", e.getMessage());
}
}
private void turnOffFlash() {
try{
if (isFlashOn) {
if (camera == null || params == null) {
return;
}
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
camera.stopPreview();
isFlashOn = false;
// changing button/switch image
toggleButtonImage();
}
}
catch(RuntimeException e){
Log.e("Could not turn off flash ", e.getMessage());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.flash_light, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onPause() {
super.onPause();
// on pause turn off the flash
turnOffFlash();
}
#Override
protected void onRestart() {
super.onRestart();
}
#Override
protected void onResume() {
super.onResume();
// on resume turn on the flash
if(hasFlash)
turnOnFlash();
}
#Override
protected void onStart() {
super.onStart();
// on starting the app get the camera params
getCamera();
}
#Override
protected void onStop() {
super.onStop();
// on stop release the camera
if (camera != null) {
camera.release();
camera = null;
}
}
}
while here is my manifest file :-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flashlight"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="FlashLight"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Please, help in the identification of the following error in the logcat menu:-
02-10 23:18:23.409: E/AndroidRuntime(13237): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.flashlight/com.example.flashlight.FlashLight}: java.lang.NullPointerException
ImageButton btnSwitch gives you NULL Pointer, you don't have
setContentView(R.layout.name_of_your_activity);
Change this and it will work:
Camera camera = null;
Camera.Parameters params = null;
boolean isFlashOn = false;
boolean hasFlash;
ImageButton btnSwitch; //add this
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.name_of_your_xml_layout_for_activity);//add this
btnSwitch=(ImageButton)findViewById(R.id.imageButton1);//add this
hasFlash = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);...
I am following the patterns that are used in the Compass example in a new project and have most of the logic working. However, when I tap while my live card is displayed I hear the 'click' noise but my menu activity doesn't display. I think that I am missing a piece of the puzzle, but I have not been able to figure out what as of yet.
When I tap, besides the click, I also see this in logcat:
01-08 10:02:26.796: I/ActivityManager(196): START {flg=0x10008000 cmp=com.example.speeddisplay/.SpeedDisplayMenuActivity} from pid -1
So it looks like it should be starting my activity, but it doesn't show up. Here are some pieces of relevant code...although I am not sure where the issue is.
Service portion in AndroidManifest.xml:
<service
android:name="com.example.speeddisplay.service.SpeedService"
android:enabled="true"
android:icon="#drawable/ic_drive_50"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voiceinput_speeddisplay" />
</service>
onStartCommand method in SpeedService.java:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Constants.DEBUG) {
Log.d(TAG, "onStartCommand");
}
if (liveCard == null) {
liveCard = timelineManager.createLiveCard(LIVE_CARD_ID);
speedRenderer = new SpeedRenderer(this, speedManager);
liveCard.setDirectRenderingEnabled(true);
liveCard.getSurfaceHolder().addCallback(speedRenderer);
// Display the options menu when the live card is tapped.
Intent menuIntent = new Intent(this, SpeedDisplayMenuActivity.class);
menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
liveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));
liveCard.publish(PublishMode.REVEAL);
if(Constants.DEBUG){
Log.d(TAG, "liveCard published");
}
}
return START_STICKY;
}
Here is my SpeedDisplayMenuActivity.java. None of these methods are getting called.
public class SpeedDisplayMenuActivity extends Activity {
private SpeedService.SpeedBinder speedService;
private boolean mResumed;
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (Constants.DEBUG) {
Log.e("Service Stuff", "Service connected.");
}
if (service instanceof SpeedService.SpeedBinder) {
speedService = (SpeedService.SpeedBinder) service;
openOptionsMenu();
}
if (Constants.DEBUG) {
Log.e("Service Stuff", "service was an instance of " + service.getClass().getName());
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
// Do nothing.
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
if(Constants.DEBUG){
Log.e("Menu", "Created.");
}
super.onCreate(savedInstanceState);
bindService(new Intent(this, SpeedService.class), mConnection, 0);
}
#Override
protected void onResume() {
if(Constants.DEBUG){
Log.e("Menu", "Resumed.");
}
super.onResume();
mResumed = true;
openOptionsMenu();
}
#Override
protected void onPause() {
if(Constants.DEBUG){
Log.e("Menu", "Paused.");
}
super.onPause();
mResumed = false;
}
#Override
public void openOptionsMenu() {
if (Constants.DEBUG) {
Log.e("Options Menu", "Open");
}
if (mResumed && speedService != null) {
if (Constants.DEBUG) {
Log.e("Options Menu", "Open with correct params");
}
super.openOptionsMenu();
} else {
if (Constants.DEBUG) {
Log.e("Options Menu", "Open with INCORRECT params");
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (Constants.DEBUG) {
Log.e("Options Menu", "Created");
}
getMenuInflater().inflate(R.menu.speed, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (Constants.DEBUG) {
Log.e("Options Menu", "Item Selected");
}
switch (item.getItemId()) {
// case R.id.read_aloud:
// mCompassService.readHeadingAloud();
// return true;
case R.id.stop:
if (Constants.DEBUG) {
Log.e("Options Menu", "Stop");
}
stopService(new Intent(this, SpeedService.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onOptionsMenuClosed(Menu menu) {
if (Constants.DEBUG) {
Log.e("Options Menu", "Closed");
}
super.onOptionsMenuClosed(menu);
unbindService(mConnection);
// We must call finish() from this method to ensure that the activity
// ends either when an
// item is selected from the menu or when the menu is dismissed by
// swiping down.
finish();
}
Does anybody see what I am missing?
That is right, declaring the SpeedDisplayMenuActivity is the problem in this case.
I have seen cases where many other types of exceptions / crash that normally happens in Android environment is gracefully handled in Glass.
That is definitely good for the user experience, but makes little tough on development. Hopefully some kind of settings come in future to enable exceptions as well in future!