我正在编写一个Android应用程序,它有两个主要组件:一个在启动时启动的服务,以及一个我只想在我通过其图标手动启动它时启动的GUI,而不是在设备启动时启动。我知道如何在启动时启动服务,但它也会在启动时启动GUI,这是我不想要的。
我认为这与我的清单中的设置有关,但是尽管尝试了很多事情,我还没想出如何防止GUI也在启动时启动。
我应该补充一点,我没有在启动时以编程方式启动GUI。我确实在GUI的活动类中引用了静态公共变量,但我没有进行任何方法调用或向GUI的活动发送任何意图。
这是我的清单。我究竟做错了什么?非常感谢你。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="my.package.name"
android:versionCode="0"
android:versionName="0.1.0">
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="@drawable/icon"
android:label="@string/app_name"
android:allowBackup="true" >
<!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
I want MainActivity to only start when I
select its icon, NOT at boot time. However,
it always starts up at boot.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-->
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
MyBootReceiver properly starts up at boot time,
and it properly invokes MyBootService. At
the appropriate time, MyBootService invokes
RegisterActivity.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-->
<activity android:name=".RegisterActivity"
android:label="@string/app_name">
</activity>
<receiver
android:name=".MyBootReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="my.package.name" />
</intent-filter>
</receiver>
<service android:name=".MyBootService" />
</application>
</manifest>
添加广播接收器类:
package my.package.name;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent bootIntent = new Intent(context, MyBootService.class);
bootIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(bootIntent);
}
}
添加服务类...
package my.package.name;
import java.util.ArrayList;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.TelephonyManager;
public class MyBootService extends Service {
private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
private static final String GOOGLE_ACCOUNT_FEATURE = "service_ah";
private Context context = null;
@Override
public IBinder onBind(Intent intent) {
this.display("onBind");
return (null);
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
AccountManager am = AccountManager.get(this);
am.getAccountsByTypeAndFeatures(GOOGLE_ACCOUNT_TYPE, new String[]{GOOGLE_ACCOUNT_FEATURE},
new AccountManagerCallback<Account[]>() {
@Override
public void run(AccountManagerFuture<Account[]> acclist) {
MyBootService parent = MyBootService.this;
Intent regIntent = new Intent(parent.getApplicationContext(), RegisterActivity.class);
try {
ArrayList<String> accountNameList = new ArrayList<String>();
for (Account a: acclist.getResult()) {
accountNameList.add(a.name);
}
regIntent.putStringArrayListExtra("accountNames", accountNameList);
try {
TelephonyManager tmgr = (TelephonyManager) parent.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
String phoneNo = tmgr.getLine1Number();
regIntent.putExtra("phoneNumber", phoneNo);
}
catch (Throwable t) {
}
}
catch (Throwable t) {
// put error message here
}
regIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
parent.startActivity(regIntent);
}
}, null);
return (START_STICKY);
}
@Override
public void onDestroy() {
this.display("onDestroy");
super.onDestroy();
}
}
更多信息
我想出了一些正在发生的事情。首先,我错误地说我的MainActivity正在开始。经过更详细的调试,我发现没有调用 onCreate()和 onResume()方法。但是,应用程序的视图显示:黑屏,显示应用程序名称和默认图标。我最初误以为这是一个完整启动的迹象。
当然,这首先提出了为什么这个视图出现在启动时的问题。我有一些关于这个的信息,虽然我仍然对发生了什么感到困惑。我删除了由MyBootService调用的RegisterActivity类的 onCreate()方法。当调用 this.getIntent()时,应用程序的视图会在启动时显示。当 this.getIntent()被注释掉时,应用程序的视图不会在启动时显示。
请注意,这是RegisterActivity类的 onCreate(),MainActivity的 NOT 。
你们是否知道在调用 this.getIntent()时可能导致应用程序的视图出现的原因?
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If the following line is commented out, the
// application's view does not show up on boot;
// if the following line is not commented out,
// the application's view shows up.
Intent intent = this.getIntent();
}
答案 0 :(得分:3)
我认为您所看到的是Android使用的预览,以使应用启动速度更快。此预览基于您活动的主题。
尝试为RegisterActivity
设置一个更接近最终结果的自定义主题。例如,如果您的活动是对话框,请创建一个扩展Theme.Dialog
或Theme.Light.Dialog
您可以从Cyril Mottier的这篇博客文章中获取更多信息:Android App Launching Made Gorgeous
编辑:改为实际回答问题
答案 1 :(得分:0)
真实的,实际的答案
由于我得到的帮助和反馈,我终于找到了问题并解决了它:
我首先使用Activity(我的RegisterActivity类)是错误的,因为我不希望我最初放入RegisterActivity的功能与GUI相关联。由于缺乏Android模型的经验和缺乏足够的文档阅读,我没有意识到Activity总是有一个与之相关的视图。
现在我知道这一点,我重构了我的应用程序,以便以前在RegisterActivity中的所有功能都已移至MyBootService。现在,启动时没有弹出视图,我的应用程序就是我想要的。
感谢所有人的帮助和耐心。