在我的应用中,有一个MainActivity
和一个AlarmActivity
。 MainActivity
用于设置闹钟。 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>
答案 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()方法中处理此问题。