5

起動時に起動するサービスと、デバイスの起動時ではなく、アイコンを介して手動で起動したときにのみ起動する GUI という 2 つの主要なコンポーネントを持つ Android アプリを作成しています。起動時にサービスを開始する方法は知っていますが、起動時に 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()がコメント化されている場合、起動時にアプリケーションのビューが表示されません。

これはMainActivityではなく、RegisterActivity クラスのonCreate()であることに注意してください。

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

2 に答える 2

3

あなたが見ているのは、Android がアプリの起動を速くするために使用するプレビューだと思います。このプレビューは、あなたの活動のテーマに基づいて作成されています。

RegisterActivity最終結果により近いカスタム テーマを設定してみてください。たとえば、アクティビティがダイアログの場合、テーマを拡張するTheme.Dialogか、Theme.Light.Dialog

詳細については、Cyril Mottier のブログ投稿: Android App Launching Made Gorgeousを参照してください。


編集:実際に質問に答えるように変更

于 2013-05-06T21:48:20.700 に答える
0

本当の答え

ここで得たヘルプとフィードバックのおかげで、私は最終的に自分の問題を理解し、解決しました。

最初に RegisterActivity に入れた機能を GUI に関連付けたくないので、そもそもアクティビティ (私の RegisterActivity クラス) を使用するのが間違っていました。Android モデルの経験が浅く、ドキュメントを十分に読んでいないため、Activity に常にビューが関連付けられていることに気付きませんでした。

これがわかったので、アプリをリファクタリングして、以前は RegisterActivity にあったすべての機能を MyBootService に移動しました。現在、起動時にビューがポップアップせず、私のアプリは私が望むことを行います。

あなたの助けと忍耐に感謝します。

于 2013-05-09T22:20:59.483 に答える