android8.0以上版本的前台服务
程序员文章站
2024-02-29 19:02:58
...
转载:https://blog.csdn.net/qq_40909351/article/details/84986330#commentBox
这个也是我最近看书遇到的问题吧,这边转一下别人的,方便以后查看
android8.0以上版本的前台服务
本人是小白,最近在学习郭林老师的第一行代码的第二版时,在第10章的前台服务的小节里面,发现在我的模拟器上运行不了,然后找了许多大神写的博客,发现原因是安卓8.0之后的前台服务需要使用startForegroundService()函数启动服务,然后按照大神的博客里面的步骤做了还不行,然后查看了一下错误日志,
下面是程序崩溃时打印的error日志中的一部分
2018-12-13 11:28:51.156 10945-10945/com.xiaogege.servicetest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xiaogege.servicetest, PID: 10945
java.lang.RuntimeException: Unable to create service com.xiaogege.servicetest.MyService: java.lang.SecurityException: Permission Denial: startForeground from pid=10945, uid=10089 requires android.permission.FOREGROUND_SERVICE
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3544)
at android.app.ActivityThread.access$1300(ActivityThread.java:199)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1666)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
发现还要在AndroidManifest申请一下android.permission.FOREGROUND_SERVICE权限,然后就可以正常运行了。
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
下面是MyService里面的代码
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG="MyService";
private static final String ID="channel_1";
private static final String NAME="前台服务";
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException ("Not yet implemented");
}
@Override
public void onCreate(){
super.onCreate ();
Log.d (TAG,"onCreate");
if(Build.VERSION.SDK_INT>=26){
setForeground();
}else{
}
}
@Override
public void onDestroy(){
super.onDestroy ();
Log.d (TAG,"onDestroy");
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
Log.d(TAG,"onStartCommand");
return super.onStartCommand (intent,flags,startId);
}
@TargetApi (26)
private void setForeground(){
NotificationManager manager=(NotificationManager)getSystemService (NOTIFICATION_SERVICE);
NotificationChannel channel=new NotificationChannel (ID,NAME,NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel (channel);
Notification notification=new Notification.Builder (this,ID)
.setContentTitle ("收到一条重要通知")
.setContentText ("这是重要通知")
.setSmallIcon (R.mipmap.ic_launcher)
.setLargeIcon (BitmapFactory.decodeResource (getResources (),R.mipmap.ic_launcher))
.build ();
startForeground (1,notification);
}
}
下面是MainActivity里面的代码
import android.content.Intent;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.main_activity_layout);
Button start=findViewById (R.id.start);
Button stop=findViewById (R.id.stop);
start.setOnClickListener (this);
stop.setOnClickListener (this);
}
@Override
public void onClick(View view){
switch(view.getId ()){
case R.id.start:
Intent start=new Intent (this,MyService.class);
if(Build.VERSION.SDK_INT>=26){
startForegroundService (start);
}else{
startService (start);
}
break;
case R.id.stop:
Intent stop=new Intent (this,MyService.class);
stopService (stop);
break;
default:
break;
}
}
}
下面是AndroidManifest中的代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xiaogege.servicetest">
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE"
/>
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
</application>
</manifest>
现在再点击开始按钮就可以正常运行了
推荐阅读
-
android8.0以上版本的前台服务
-
在Red Hat 5.6之后的版本上升级php版本 博客分类: PHP编程服务器
-
在Red Hat 5.6之后的版本上升级php版本 博客分类: PHP编程服务器
-
在vista系统中自带的IIS6怎样安装、配置PHP5.3及以上版本
-
已备份数据库的磁盘结构版本为611,服务器支持版本为539,无法还
-
使用pthreads实现真正的PHP多线程(需PHP5.3以上版本)
-
AMFPHP1.4与PHP5.3及以上版本不兼容问题的解决
-
富文本编辑器UEditor的安装配置,及PHP版本服务器端上传设置
-
Android通知栏前台服务的实现
-
查看远程Redis服务器的版本