我从广播接收器开始活动,但为什么我的其他活动也开始了?

时间:2014-11-28 06:10:03

标签: android android-intent android-activity broadcastreceiver android-pendingintent

在我的应用中,有一个MainActivity和一个AlarmActivityMainActivity用于设置闹钟。 AlarmActivity用于显示警报。在中间,我有一个实现BroadcastReceiver的类,以接收在MainActivity中安排的待定意图。我遇到的问题有两个。

1)当我只期望从下面看到的onReceive方法创建MainActivity时,正在创建AlarmActivity

2)当AlarmActivity创建时,它会在之后被销毁。请参阅下面的日志。

请注意,这只会在我关闭屏幕时发生。如果我销毁MainActivity并保持屏幕开启直到闹钟响起,一切都很顺利。如果我让MainActivity生效,并保持屏幕开启,则AlarmActivity会出现在MainActivity之上,正如预期的那样。否则,如果屏幕关闭...一瞬间显示AlarmActivity,它会消失,我在屏幕上看到MainActivity。是什么给了什么?

这是我安排闹钟的地方。并不是callContext变量是我的MainActivity类的上下文。

 Intent intentAlarm = new Intent(this.callingContext, AlarmActivity.class);

        //Get the Alarm Service
        AlarmManager alarmManager = (AlarmManager) callingContext.getSystemService(Context.ALARM_SERVICE);

     //user our intent and give it a time to broadcast at
          alarmManager.set(AlarmManager.RTC_WAKEUP,alarmTime, PendingIntent.getBroadcast(this.callingContext, 1, intentAlarm, PendingIntent.FLAG_CANCEL_CURRENT));


public class AlarmReceiver extends BroadcastReceiver { 

    final String TAG=this.toString();

    @Override
    public void onReceive(Context arg0, Intent arg1) {
        Log.i(TAG,"onReceive");

        //start a new activity, an alarm has gone off

        //See that I've tried using the application context, but this did not help.
        //Context context=arg0.getApplicationContext();
        Intent intent=new Intent(arg0,AlarmActivity.class);

        //This flag is required for starting an activity outside of an activity.
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        intent.putExtra("ACTIVITY_STARTED_FROM_BROADCAST_RECEIVER",true);
        arg0.startActivity(intent);
    }
}

警报活动生命周期方法。

protected void onCreate(Bundle savedInstanceState) {
        Log.i(TAG,"onCreate");
        if(savedInstanceState==null) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_alarm);


        }
    }

    public static void acquireScreenCpuWakeLock(Context context) {
        if (sCpuWakeLock != null) {
            return;
        }
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        sCpuWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
                | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "TYLER");
        sCpuWakeLock.acquire();
    }

    public static void releaseCpuLock() {
        if (sCpuWakeLock != null) {
            sCpuWakeLock.release();
            sCpuWakeLock = null;
        }
    }
    @Override
    protected void onResume() {
        Log.i(TAG,"onResume");
        super.onResume();

    //  getFragmentManager().beginTransaction().add(R.id.alarm_frame, new AlarmFragment()).commit();
    }

    @Override
    protected void onStart() {
        Log.i(TAG,"onStart");
        super.onStart();
        final Window win = getWindow();
        win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
                WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
                WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
        acquireScreenCpuWakeLock(this);
        alarmFragment=new AlarmFragment();
        alarmFragment.setArguments(getIntent().getExtras());
        getFragmentManager().beginTransaction().add(R.id.alarm_frame, alarmFragment).commit();

    }

    @Override
    protected void onPause(){
        Log.i(TAG,"onPause");
        super.onPause();
        releaseCpuLock();
        getFragmentManager().beginTransaction().remove(alarmFragment);
        Log.d("pfaff","wakelock released, alarm activity paused");

    }

   @Override
    protected  void onDestroy(){
       Log.i(TAG,"onDestroy");
       super.onDestroy();
     //  wakeLock.release();
        Log.d("pfaff","alarm activity destroyed");
   }

}

警报Framgnet生命周期方法。

  @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.fragment_alarm, container, false);
    }

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onAttach(Activity activity){
        Log.i(TAG,"onAttach");
        super.onAttach(activity);
        this.activity=activity;//camera

    }
    @Override
    public void onStart() {
        Log.i(TAG, "onStart");
        super.onStart();
    }

    @Override
    public void onResume() {
       Log.i(TAG,"onResume");
        super.onResume();
        final AlarmFragment thisFragment = this;
}

@Override
    public void onPause() {
        Log.i(this.toString(),"onPause");
        super.onPause();
        getActivity().onBackPressed();

    }


    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        Log.i(this.toString(),"onDestroy");

        super.onDestroy();
       // tearDownMedia();
        scanMyMedia();
        releaseCameraAndPreview();
        if(timeReceiverIsRegistered) {
            getActivity().unregisterReceiver(_broadcastReceiver);
        }
    }


这是logcat:

   11-27 21:56:46.036  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.AlarmReceiver@41eb2158﹕ onReceive
    11-27 21:56:46.066  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.MainActivity@41eaaf08﹕ onCreate
    11-27 21:56:46.066  29370-29370/com.example.videoalarmt I/timePickerFragment{41ea1e58}﹕ onCreateView
    11-27 21:56:46.096  29370-29370/com.example.videoalarmt E/TextView﹕ Saved cursor position 2/2 out of range for (restored) text
    11-27 21:56:46.096  29370-29370/com.example.videoalarmt E/TextView﹕ Saved cursor position 2/2 out of range for (restored) text
    11-27 21:56:46.136  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.AlarmActivity@41ed7bf8﹕ onCreate
    11-27 21:56:46.136  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.AlarmActivity@41ed7bf8﹕ onStart
    11-27 21:56:46.136  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.AlarmActivity@41ed7bf8﹕ onResume
    11-27 21:56:46.136  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40}﹕ onAttach
    11-27 21:56:46.136  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40}﹕ onViewCreated
    11-27 21:56:46.136  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40}﹕ onStart
    11-27 21:56:46.136  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40}﹕ onResume
    11-27 21:56:46.136  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40}﹕ was started from broadcast receiver
    11-27 21:56:46.206  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40 #0 id=0x7f0a0024}﹕ onPause
    11-27 21:56:46.206  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.AlarmActivity@41ed7bf8﹕ onPause
    11-27 21:56:46.787  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40 #0 id=0x7f0a0024}﹕ Putting media recorder in PREPARED state from DATASOURCECONFIGURED state
    11-27 21:56:46.787  29370-29370/com.example.videoalarmt I/MediaRecorderJNI﹕ prepare: surface=0x76608e58
    11-27 21:56:47.137  29370-29370/com.example.videoalarmt E/MediaPlayer﹕ Should have subtitle controller already set
    11-27 21:56:47.137  29370-29370/com.example.videoalarmt I/Choreographer﹕ Skipped 53 frames!  The application may be doing too much work on its main thread.
    11-27 21:56:47.237  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.AlarmActivity@41ed7bf8﹕ onStop
    11-27 21:56:47.598  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40 #0 id=0x7f0a0024}﹕ onDestroy
    11-27 21:56:47.598  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.AlarmActivity@41ed7bf8﹕ onDestroy
    11-27 21:56:47.658  29370-29370/com.example.videoalarmt W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
    11-27 21:57:02.243  29370-29370/com.example.videoalarmt I/com.example.videoalarmt.MainActivity@41eaaf08﹕ onDestroy

这是我的清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.videoalarmt"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="21" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-feature android:name="android.hardware.camera.front" android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Holo.Light.NoActionBar"
        >

        <meta-data android:name="com.google.android.gms.version"
           android:value="@integer/google_play_services_version" />

           <receiver android:name="com.example.videoalarmt.AlarmReceiver"/>
        <activity
            android:name="com.example.videoalarmt.MainActivity"
            android:label="@string/app_name" 
            android:screenOrientation="portrait"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
          <activity
            android:name="com.example.videoalarmt.AlarmActivity"
            android:label="@string/app_name" 
            android:screenOrientation="portrait"
            >
        </activity>

            <activity android:name="com.google.android.gms.ads.AdActivity"
             android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>

    </application>



</manifest>

6 个答案:

答案 0 :(得分:2)

没有理由创建MainActivity。我在代码中找到的唯一问题是在下面一行:

Intent intentAlarm = new Intent(this.callingContext, AlarmActivity.class);

在这里,您正在使用Activity类创建一个intent,但在您的待定意图中,您正在使用getBroadCast()方法。它应该是:

Intent intentAlarm = new Intent(this.callingContext, AlarmReceiver.class);

我还没有尝试过你的代码,但这可能是导致问题的原因。 请进行此更改并检查是否仍在创建Mainactivity?

答案 1 :(得分:1)

从查看代码和日志开始,我认为您的问题是在片段中调用onBackPressed

11-27 21:56:46.206  29370-29370/com.example.videoalarmt I/AlarmFragment{41edaa40 #0 id=0x7f0a0024}﹕ onPause

你的AlarmFragment.onPause不应该调用getActivity().onBackPressed()。这很可能是导致您的活动关闭的原因。只需在AlarmFragment.onPause中删除该行,我认为您的问题将得到解决。

答案 2 :(得分:0)

在BroadcastReceiver的onReceive()中,您不能执行超过10秒的操作。 see here official doc

当屏幕锁定时,cpu停止工作see here

所以当屏幕锁定然后cpu停止工作并且时间超过10秒时,你会收到此错误。

因此,您应wake lock预防此错误。在屏幕锁定时使用此应用程序 并且还会看到此link1 link2

我希望我的信息有助于您解决问题。

答案 3 :(得分:0)

intent intent = new Intent(context, WordService.class);  
context.startService(intent);

答案 4 :(得分:0)

据我所知,这种行为出现了。当您打开主要活动然后设置闹钟然后在闹钟接收器获取之前关闭屏幕。然后当您再次打开屏幕时,您会看到警报活动闪烁并消失。

基于此,这里有解释:

  

由于它在后台工作,接收器会在接收时发出警报   屏幕关闭。发生了接收器启动警报的情况   活动,因为屏幕关闭,警报活动暂停和   报警片段将其关闭。但是,所有这些事件都会堆积起来   你解锁了屏幕,你就会看到所有这些都在发生。

您可以在屏幕启动后推迟警报活动启动。当闹钟接收器获取某些内容时,请检查屏幕。如果关闭则保存SharedPreferances中的警报设置。您可以设置广播接收器以打开和关闭屏幕事件。在屏幕上检查您的共享偏好以获得延期的警报并在您清除共享偏好后开始警报活动。

另一种解决方案是添加

<uses-permission android:name="android.permission.WAKE_LOCK" />

对您的清单的许可,并在您的接收器获取内容时设置屏幕。并在接收器的屏幕上开始报警活动。

您还应该使用getActivity().finish()而不是getActivity().onBackPressed()来关闭活动。

答案 5 :(得分:-1)

每当按下锁定按钮时,应用程序进入暂停模式。如果您希望应用程序执行某些操作(或继续执行某些操作),则需要在主要活动的onPause()方法中处理此问题。