如何在android O

时间:2018-04-26 09:27:21

标签: java android android-notifications android-8.0-oreo

我是Android的初学者,现在正在制作音乐流媒体应用。为了初学者,我为Udemy学习了一门课程 教师一行一行地展示创作的每一步,我完全按照他的方式行事。现在我们已经到了创建通知的步骤 应用程序,他使用了一个名为'NotificationCompat.Builder(this)'的东西。现在,当我键入相同的确切代码时,我得到一个错误,说明了 {O}现在已经在Android O中被弃用了。由于这个原因,我在手机上没有收到通知 运行。音乐也没有流式传输。由于这个原因,我无法继续进一步的讲座。 我试图向论坛上的讲师询问有关此问题的一些帮助,但他似乎没有回复。我也试着去研究 关于android O中的通知通道,但由于缺乏基本的android知识,我无法理解这些概念。 如果我能就我的问题得到一些帮助,那就太棒了。 我正在上传我的代码。 错误发生在NotificationCompat.Builder(context)

  

(1)。 activity_main.xml中

PlayerService.java
  

(2)。 MainActivity.java

<?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>
  

(3)。 PlayerService.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);
    }
}
  

(4)。 Player.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");
        }
    }
}
  

(5)。 Constants.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");
        }
    }
}
  

(6)。的AndroidManifest.xml

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;
    }
}

1 个答案:

答案 0 :(得分:2)

为了方便Android Oreo中名为Notification Channels的新功能,不推荐使用上一种方法。

通知渠道允许我们根据预期行为对通知进行分组。因此,每当用户不需要查看特定类型的通知时,他们就可以禁用相应的通道。

例如,考虑一个电子商务应用程序。它显示促销/优惠,订单状态等的通知。促销和优惠通知分组到名为“促销”的频道中。因此,如果用户不希望仅看到这些通知,则可以从应用设置中禁用“促销”频道。

如果您使用已弃用的方法,则通知将在Oreo中以静默方式失败。要使其工作,请使用新的Builder构造函数。更改您的代码如下:

Notification notification=new NotificationCompat.Builder(this, CHANNEL_ID)
    // set title, message, etc.
    .build();

为奥利奥创建一个这样的通知渠道:

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);
}