AndroidStudio前台服务示例程序
2026/7/25 2:00:19 网站建设 项目流程

如果你的应用需要持续、稳定地执行后台任务(比如音乐播放、运动轨迹记录),那么将你的Service设置为前台服务是最高优先级的方案。前台服务会显示一个持续的通知,告诉用户你的应用正在运行。系统会将其视为用户正在交互的应用,从而极大地降低被杀死或限制的概率。

我的示例程序里有两个前台服务程序,一个是定时器服务程序,一个是位置服务程序。

可以选择一个并启动。该示例程序适合于Android13及以上版本。

注:运行程序需要手机上安装有google play服务、google TTS,并在手机设置中授予示例程序后台省电优化白名单(各品牌手机设置方法有异)、自启动权限、位置权限(始终允许)、通知权限。如果全部设置到位,那么程序中的权限申请就会成功,不会弹出对话框。

注:在手机上,定时器最短响应时间为1分钟,设置小于1分钟的间隔是没用的(测试机为小米)。对于位置服务,只有在手机位置变化情况下才会触发回调。手机放桌上不动,位置服务回调基本上不会触发。

定时器服务程序代码:

package com.example.train; 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.media.AudioAttributes; import android.media.AudioManager; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import androidx.core.app.NotificationCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import android.app.AlarmManager; import android.os.SystemClock; import android.speech.tts.TextToSpeech; import android.util.Log; import org.greenrobot.eventbus.EventBus; import java.util.Locale; public class TimerForegroundService extends Service { private static final int NOTIF_ID = 1; // 全局唯一的通知标识 String NOTIFICATION_CHANNEL_ID = "foreground_service_channel"; String CHANNEL_NAME = "前台服务通知"; String text = "定时器正在运行"; //用于定时器 AlarmManager alarmManager = null; PendingIntent pendingIntent = null; public static int count = 0;//定时器计数 public static float vol = 0.5f;//音量 private TextToSpeech tts; public TimerForegroundService() { } @Override public void onCreate() { super.onCreate(); // 初始化代码 //创建通知模板 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); } tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { // 关键:设置音频属性为闹钟模式,强制可听 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { AudioAttributes attrs = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_ALARM) .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED) .build(); tts.setAudioAttributes(attrs); } int result = tts.setLanguage(Locale.CHINA); // 设置中文 if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Log.e("TTS", "中文语言包不可用"); } else{ //AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE); //am.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(am.getStreamMaxVolume(AudioManager.STREAM_MUSIC) * 0.8), 0); EventBus.getDefault().post(new MyEvent(1,"TTS语音初始化完成")); } } } }); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) { int code = intent.getIntExtra("code", 0); String text = intent.getStringExtra("text"); switch(code){ case 0: // 这里启动前台服务 startForeground(NOTIF_ID, buildNotification(text)); // 1是通知ID,必须是唯一的正整数 startTimer(); EventBus.getDefault().post(new MyEvent(1,"定时器服务已启动!")); break; case 1: updateNotification(text); tts.setPitch(1.2f);// 音高调节(0.5-2.0,默认1.0) tts.setSpeechRate(0.9f);// 语速调节(0.5-2.0,默认1.0) Bundle params = new Bundle(); //因为TTS被设为闹钟模式(便于熄屏后播放),所以手机音量键无法控制语音大小,需要代码来控制 params.putFloat(TextToSpeech.Engine.KEY_PARAM_VOLUME, TimerForegroundService.vol); // 0.0(静音) ~ 1.0(最大) tts.speak(text, TextToSpeech.QUEUE_FLUSH, params, null); break; case 2: stopForeground(true); stopSelf(); EventBus.getDefault().post(new MyEvent(1,"定时器服务已停止!")); break; } } return START_STICKY; } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. //throw new UnsupportedOperationException("Not yet implemented"); return null; } private Notification buildNotification(String contentText) { //Notification 点击跳转需通过 PendingIntent 封装 Intent 并传入 Notification //Android 12+ 必须显式指定 FLAG_IMMUTABLE 或 FLAG_MUTABLE,否则应用崩溃 。 Intent intent = new Intent(this, MainActivity.class); int flag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT; PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, flag); return new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.train) .setContentTitle("前台服务") .setContentText(contentText) .setContentIntent(pendingIntent)// 绑定点击事件 .setAutoCancel(true)// 点击后自动消失 .setOngoing(true) .build(); } private void updateNotification(String newContent) { Notification updatedNotification = buildNotification(newContent); NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(NOTIF_ID, updatedNotification); Intent intent = new Intent("com.example.broadcast.MY_BROADCAST"); intent.putExtra("data", newContent); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } private void startTimer() { alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(this, YourBroadcastReceiver.class); pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE); long interval = 10000; // // 设置AlarmManager每分触发一次 alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, pendingIntent); alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), interval, pendingIntent); } private void stopTimer() { alarmManager.cancel(pendingIntent); pendingIntent.cancel(); // API level >= 19 (KitKat) required for this line of code to work correctly if FLAG_NO_CREATE is used in getBroadcast() method call for PendingIntent creation. Otherwise, it can be safely omitted for older versions of Android or if FLAG_CANCEL_CURRENT is used instead of FLAG_NO_CREATE or FLAG_UPDATE_CURRENT in getBroadcast() method call for PendingIntent creation. } // 在 Activity 的 onDestroy 中务必调用 stopTimer() @Override public void onDestroy() { super.onDestroy(); stopTimer(); tts.stop(); // 停止当前播报 tts.shutdown(); // 释放底层资源(关键步骤) tts = null; // 避免悬空引用 } }

定时器回调:

package com.example.train; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Build; import java.time.LocalTime; public class YourBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 处理每秒触发的事件 TimerForegroundService.count++; LocalTime now = null; // 获取当前时间 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { now = LocalTime.now(); int hour = now.getHour(); // 获取小时 int minute = now.getMinute(); // 获取分钟 int second = now.getSecond(); String text = String.format("%d点%d分%d秒",hour,minute,second); Intent d = new Intent(context, TimerForegroundService.class); d.putExtra("code", 1); d.putExtra("text", text); context.startForegroundService(d); } } }

位置服务程序代码:

package com.example.train; import android.Manifest; 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.content.pm.PackageManager; import android.media.AudioAttributes; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Looper; import androidx.core.app.ActivityCompat; import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; import android.location.Location; import android.speech.tts.TextToSpeech; import java.util.Locale; import android.util.Log; import android.content.Context; import android.media.AudioManager; import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationCallback; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationResult; import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.Priority; import org.greenrobot.eventbus.EventBus; public class LocationForegroundService extends Service { private FusedLocationProviderClient fusedLocationClient; private LocationCallback locationCallback; private static final int NOTIF_ID = 2; // 全局唯一的通知标识 String NOTIFICATION_CHANNEL_ID = "location_service_channel"; String CHANNEL_NAME = "前台位置服务通知"; String text = "位置服务正在运行"; public static int count = 0; public static float vol = 0.5f;//音量 private TextToSpeech tts; public LocationForegroundService() { } @Override public void onCreate() { super.onCreate(); fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); //创建通知模板 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); } tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { // 关键:设置音频属性为闹钟模式,强制可听 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { AudioAttributes attrs = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_ALARM) .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED) .build(); tts.setAudioAttributes(attrs); } int result = tts.setLanguage(Locale.CHINA); // 设置中文 if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Log.e("TTS", "中文语言包不可用"); } else{ //AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE); //am.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(am.getStreamMaxVolume(AudioManager.STREAM_MUSIC) * 0.8), 0); EventBus.getDefault().post(new MyEvent(1,"TTS语音初始化完成")); } } } }); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) { int code = intent.getIntExtra("code", 0); String text = intent.getStringExtra("text"); switch(code){ case 0: // 这里启动前台服务 startForeground(NOTIF_ID, buildNotification(text)); // 1是通知ID,必须是唯一的正整数 requestLocationUpdates(); EventBus.getDefault().post(new MyEvent(1,"位置服务已启动!")); break; /* case 1: updateNotification(text); tts.setPitch(1.2f);// 音高调节(0.5-2.0,默认1.0) tts.setSpeechRate(0.9f);// 语速调节(0.5-2.0,默认1.0) tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, null); break;*/ case 2: stopForeground(true); stopSelf(); EventBus.getDefault().post(new MyEvent(1,"位置服务已停止!")); break; } } return START_STICKY; } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return null; } @Override public void onDestroy() { super.onDestroy(); fusedLocationClient.removeLocationUpdates(locationCallback); tts.stop(); // 停止当前播报 tts.shutdown(); // 释放底层资源(关键步骤) tts = null; // 避免悬空引用 } private Notification buildNotification(String contentText) { //Notification 点击跳转需通过 PendingIntent 封装 Intent 并传入 Notification //Android 12+ 必须显式指定 FLAG_IMMUTABLE 或 FLAG_MUTABLE,否则应用崩溃 。 Intent intent = new Intent(this, MainActivity.class); int flag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT; PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, flag); return new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.train) .setContentTitle("前台服务") .setContentText(contentText) .setContentIntent(pendingIntent)// 绑定点击事件 .setAutoCancel(true)// 点击后自动消失 .setOngoing(true) .build(); } private void updateNotification(String newContent) { Notification updatedNotification = buildNotification(newContent); NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(NOTIF_ID, updatedNotification); } private void requestLocationUpdates() { // 1. 创建 Builder,设置基础间隔为 10 秒 (10000 毫秒) LocationRequest.Builder builder = new LocationRequest.Builder(10000); // 2. 配置其他参数 LocationRequest locationRequest = builder .setPriority(Priority.PRIORITY_HIGH_ACCURACY ) // 高精度 .setMinUpdateIntervalMillis(10000) // 最快 10 秒更新一次 .setMaxUpdateDelayMillis(20000) // 最长延迟 20 秒必须更新一次 .build(); // 3. 构建最终的 LocationRequest 对象 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) { return; } for (Location location : locationResult.getLocations()) { // 处理接收到的位置更新 //Log.d("LocationService", "Location: " + location.getLatitude() + ", " + location.getLongitude()); } count++; text = String.format("位置服务已执行%d次",LocationForegroundService.count); updateNotification(text); tts.setPitch(1.2f);// 音高调节(0.5-2.0,默认1.0) tts.setSpeechRate(0.9f);// 语速调节(0.5-2.0,默认1.0) Bundle params = new Bundle(); params.putFloat(TextToSpeech.Engine.KEY_PARAM_VOLUME, LocationForegroundService.vol); // 0.0(静音) ~ 1.0(最大) tts.speak(text, TextToSpeech.QUEUE_FLUSH, params, null); } }, Looper.getMainLooper()); } } }

主程序代码:

package com.example.train; import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.view.View; import android.widget.*; import androidx.activity.EdgeToEdge; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; public class MainActivity extends AppCompatActivity { //用于‌标识位置权限请求‌的自定义整数常量,通常在调用 requestPermissions() 方法时作为第一个参数传入, //以便在 onRequestPermissionsResult() 回调中识别该请求。 private static final int LOCATION_PERMISSION_REQUEST_CODE = 201; private static final int NOTICE_PERMISSION_REQUEST_CODE = 200; android.widget.Button button = null; android.widget.Button button2 = null; //用于标记程序要启动哪一个前台服务 private enum ServiceType{None,Timer,Location} ServiceType type = ServiceType.None; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_main); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); // 注册事件监听器 EventBus.getDefault().register(this); //android 13及以上系统动态获取通知权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { checkPostNotificationPermission(); checkLocationNotificationPermission(); } button = findViewById(R.id.button);//启动服务 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startService(); } }); button2 = findViewById(R.id.button2);//停止服务 button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopService(); } }); RadioGroup radioGroup = findViewById(R.id.radioGroup2); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { float vol = 0; // 检查哪个RadioButton被选中 if (checkedId == R.id.radioButton3) { vol = 0.3f; } else if (checkedId == R.id.radioButton4) { vol = 0.5f; }else if (checkedId == R.id.radioButton5) { vol = 0.8f; } else if (checkedId == R.id.radioButton6) { vol = 0; } TimerForegroundService.vol = vol; LocationForegroundService.vol = vol; } }); } @Override protected void onResume() { super.onResume(); EditText edit = findViewById(R.id.editTextText); if(TimerForegroundService.count > 0){ String val = String.format("定时器已执行%d次",TimerForegroundService.count); edit.setText(val); } else if(LocationForegroundService.count > 0){ String val = String.format("位置服务已执行%d次",LocationForegroundService.count); edit.setText(val); } } @Override protected void onDestroy() { super.onDestroy(); stopService(); // 注销事件监听器 EventBus.getDefault().unregister(this); } @Subscribe(threadMode = ThreadMode.MAIN) // 确保在主线程中更新UI public void onMessageEvent(MyEvent event) { // MyEvent是你要接收的事件类型 // 处理事件 switch(event.code){ case 1: EditText edit = findViewById(R.id.editTextText); edit.append(event.text+"\n");//添加初始化信息 break; } } private void checkPostNotificationPermission() { if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions((Activity) this, new String[]{ Manifest.permission.POST_NOTIFICATIONS}, NOTICE_PERMISSION_REQUEST_CODE); } else{ EditText edit = findViewById(R.id.editTextText); edit.append("通知权限已开启\n"); } } private void checkLocationNotificationPermission(){ if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); } else{ EditText edit = findViewById(R.id.editTextText); edit.append("位置权限已开启\n"); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == NOTICE_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //允许了通知权限 EditText edit = findViewById(R.id.editTextText); edit.append("通知权限申请成功!\n"); } else { Toast.makeText(this, "您拒绝了通知权限", Toast.LENGTH_SHORT).show(); } } else if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //允许了位置权限 EditText edit = findViewById(R.id.editTextText); edit.append("位置权限申请成功!\n"); } else { Toast.makeText(this, "您拒绝了位置权限", Toast.LENGTH_SHORT).show(); } } } private void startService(){ // Android 8.0+ 必须使用此方法启动前台服务 if (type == ServiceType.None && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { RadioGroup radioGroup = findViewById(R.id.radioGroup); int selectedId = radioGroup.getCheckedRadioButtonId(); if(selectedId == R.id.radioButton1){ type = ServiceType.Timer; } else{ type = ServiceType.Location; } Intent intent = (type == ServiceType.Timer) ? new Intent(this, TimerForegroundService.class) : new Intent(this, LocationForegroundService.class); intent.putExtra("code", 0); intent.putExtra("text", "0");//初始化启动无文本内容 startForegroundService(intent); } } private void stopService(){ if (type != ServiceType.None && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Intent intent = (type == ServiceType.Timer) ? new Intent(this, TimerForegroundService.class) : new Intent(this, LocationForegroundService.class); intent.putExtra("code", 2); intent.putExtra("text", "0");//初始化启动无文本内容 startForegroundService(intent); } } }

权限申请:

包括前台服务的申明,前台服务通知权限申请,TTS权限申请,位置服务申请

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <queries> <intent> <action android:name="android.intent.action.TTS_SERVICE" /> </intent> </queries> <!-- 1. 声明基础及细分权限 --> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.USE_EXACT_ALARM" /> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Train"> <service android:name=".LocationForegroundService" android:enabled="true" android:exported="true" android:foregroundServiceType="location"></service> <receiver android:name=".YourBroadcastReceiver" /> <!-- 2. 在 Service 中声明类型 --> <service android:name=".TimerForegroundService" android:enabled="true" android:exported="true" android:foregroundServiceType="location" /> <!-- 组件仅能被应用内部组件(如其他Activity、Service等)启动或绑定。 --> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

在手机中的表现:

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询