问题
Description
I am developing an app (for testing purposes), that every 60 seconds will save a word in a database (using SQLiteOpenHelper). I am trying to achieve that by using AlarmManager (setRepeating) + Wake Lock (PARTIAL_WAKE_LOCK). It is important that the app also runs even if the screen is black.
I tested my app for 2 days, tried several approaches but i have 1 issue which i can´t figure out. The best result i got code-wise is what i posted.
I tested the app on 2 different phones a Samsung Galaxy s6 edge and a HTC One M8. On the Samsung phone the app will run for 1-5 iterations and then die totally. On the HTC it will keep running as if the Wake Lock works as it should. An iteration in my case is my AlarmManager which make a call every 60 seconds.
Notice! The app does run as it should on the Samsung Phone, if i have the USB with charging connected, but that was expected since the CPU does not sleep then.
My Question
Am i doing something wrong if i want to achieve what my description says?
Versions
Samsung Galaxy s6 Edge Android version: 6.0.1
HTC One M8 Android version: 6.0.1
Code
AndroidManifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Repeating_activity"/>
<receiver android:name=".Notification_receiver"/>
</application>
</manifest>
MainActivity
package com.example.acce.dailyrepeatinglocalnotification;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private TextView text;
String tag = "LifeCycleEvents";
AlarmManager alarmManager;
PendingIntent pendingIntent;
boolean isAlarmRunning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(tag, "In the onCreate() event");
text = (TextView) findViewById(R.id.textView3);
}
public void startAlarm(View v) {
Calendar calendar = Calendar.getInstance();
Intent intent = new Intent(getApplicationContext(), Notification_receiver.class);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),60000, pendingIntent);
Toast.makeText(this,"Alarm started", Toast.LENGTH_SHORT).show();
isAlarmRunning = true;
}
public void stopAlarm(View v) {
if(isAlarmRunning) {
alarmManager.cancel(pendingIntent);
Toast.makeText(this,"Alarm stopped", Toast.LENGTH_SHORT).show();
isAlarmRunning = false;
} else {
Toast.makeText(this,"No alarm running!", Toast.LENGTH_SHORT).show();
}
}
public void ShowAll(View view) {
List notificationList = new ArrayList<String>();
DatabaseHandler db = new DatabaseHandler(this);
notificationList = db.getAllNotifications();
int msg = notificationList.size();
text.setText(String.valueOf(msg));
}
}
Notification_receiver
package com.example.acce.dailyrepeatinglocalnotification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
public class Notification_receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "asdasdasd");
wl.acquire();
DatabaseHandler db = new DatabaseHandler(context);
db.addNotification("A new notification");
wl.release();
}
}
DatabaseHandler
package com.example.acce.dailyrepeatinglocalnotification;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Daniel on 01-10-2016.
*/
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "AlarmNotifications";
// table name
private static final String TABLE_NAME = "notifications";
// Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_NAME + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT)";
db.execSQL(CREATE_CONTACTS_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
// Create tables again
onCreate(db);
}
// add
public void addNotification(String name) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, name);
db.insert(TABLE_NAME, null, values);
db.close();
}
public List getAllNotifications() {
List<String> notifcationList = new ArrayList<String>();
String selectQuery = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if(cursor.moveToFirst()) {
do {
notifcationList.add(cursor.getString(1)); // the name
} while(cursor.moveToNext());
}
return notifcationList;
}
}
来源:https://stackoverflow.com/questions/39816985/android-os-shuts-down-the-wakelock-alarmmanager-after-a-few-minutes