Skip to content

Commit

Permalink
API 26, reworked to remove service and limits
Browse files Browse the repository at this point in the history
uses an alarm now.  Should use a job scheduler, but haven't learn it
yet.
  • Loading branch information
JimSeker committed Aug 24, 2017
1 parent 06f64a0 commit cabe845
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 165 deletions.
26 changes: 13 additions & 13 deletions BroadcastBoot/app/app.iml
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,10 @@
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/ndk" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/rs" />
Expand All @@ -94,17 +92,19 @@
<excludeFolder url="file:https://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file:https://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="jdk" jdkName="Android API 26 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-core-ui-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-media-compat-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-25.4.0" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-vector-drawable-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-compat-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-core-utils-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-fragment-25.4.0" level="project" />
<orderEntry type="library" exported="" name="animated-vector-drawable-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-core-ui-26.0.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-26.0.1" level="project" />
<orderEntry type="library" exported="" name="support-media-compat-26.0.1" level="project" />
<orderEntry type="library" exported="" name="support-compat-26.0.1" level="project" />
<orderEntry type="library" exported="" name="constraint-layout-solver-1.0.2" level="project" />
<orderEntry type="library" exported="" name="constraint-layout-1.0.2" level="project" />
<orderEntry type="library" exported="" name="support-annotations-26.0.1" level="project" />
<orderEntry type="library" exported="" name="support-v4-26.0.1" level="project" />
<orderEntry type="library" exported="" name="support-vector-drawable-26.0.1" level="project" />
<orderEntry type="library" exported="" name="support-core-utils-26.0.1" level="project" />
<orderEntry type="library" exported="" name="support-fragment-26.0.1" level="project" />
<orderEntry type="library" exported="" name="animated-vector-drawable-26.0.1" level="project" />
</component>
</module>
9 changes: 5 additions & 4 deletions BroadcastBoot/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
compileSdkVersion 26
buildToolsVersion "26.0.1"

defaultConfig {
applicationId "edu.cs4730.broadcastboot"
minSdkVersion 16
targetSdkVersion 25
targetSdkVersion 26
versionCode="1"
versionName="1.0"
}
Expand All @@ -22,5 +22,6 @@ android {

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.4.0'
compile 'com.android.support:appcompat-v7:26.0.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
}
9 changes: 2 additions & 7 deletions BroadcastBoot/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop" >
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Expand All @@ -27,13 +25,10 @@
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="edu.cs4730.broadcastboot.myAction" />
</intent-filter>
</receiver>

<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -1,72 +1,71 @@
package edu.cs4730.broadcastboot;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

/*
* This example sets a receiver to a boot message and then makes sure that it's service
* is running on start up.
* This example sets a receiver to a boot message to a receiver.
* the receiver then sets an alarm for X minutes. X is set in the receiver.
*
* services are hard to keep running in the background in API 26, so alarms were used for this
* example. It should be a scheduled job, when I have time to learn ithem.
*/

public class MainActivity extends AppCompatActivity {

public static final String ACTION = "edu.cs4730.broadcastboot.myAction";
MainFragment mFragment;
final String TAG = "MainActivity";
public static String id = "test_channel_01";


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

String info = "Nothing";
Bundle extras = getIntent().getExtras();
if (extras != null) {
info = extras.getString("mText");
}
Log.wtf(TAG, "info is " + info);
mFragment = MainFragment.newInstance(info);

if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, mFragment).commit();
}
//if my service is not running, start it. for testing, before rebooting emulators... so much fun...
if (!isMyServiceRunning(MyService.class)) {
//not running, start it.
Intent i = new Intent(getBaseContext(), MyService.class);
startService(i);
Log.v(TAG, "Started service");
}

Log.v(TAG, "started up: " + info);
}


private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
createchannel();
}

@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String info = "Nothing";
Bundle extras = getIntent().getExtras();
if (extras != null) {
/*
* for API 26+ create notification channels
*/
private void createchannel() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel mChannel = new NotificationChannel(id,
getString(R.string.channel_name), //name of the channel
NotificationManager.IMPORTANCE_DEFAULT); //importance level
//important level: default is is high on the phone. high is urgent on the phone. low is medium, so none is low?
// Configure the notification channel.
mChannel.setDescription(getString(R.string.channel_description));
mChannel.enableLights(true);
// Sets the notification light color for notifications posted to this channel, if the device supports this feature.
mChannel.setLightColor(Color.RED);
mChannel.enableVibration(true);
mChannel.setShowBadge(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
nm.createNotificationChannel(mChannel);

info = extras.getString("mText");
Log.d(TAG, "new value");
}
Log.v(TAG, "New intent " + info);

mFragment.settext(info);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package edu.cs4730.broadcastboot;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
Expand All @@ -8,7 +9,9 @@
import android.widget.TextView;

/**
* All this fragment does is display information. The bulk of the example is in mainActivity and myService.
* All this fragment does is display information.
* <p>
* It also has a button to "jump start" the process. Basically the first message.
*/

public class MainFragment extends Fragment {
Expand Down Expand Up @@ -43,15 +46,19 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View myView = inflater.inflate(R.layout.fragment_main, container, false);
logger = (TextView) myView.findViewById(R.id.textView2);
settext(info);
return myView;
}

public void settext(String i) {
info = i;
logger = myView.findViewById(R.id.textView2);
logger.setText(info);

myView.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.ACTION);
intent.setPackage("edu.cs4730.broadcastboot"); //in API 26, it must be explicit now.
getActivity().sendBroadcast(intent);
getActivity().finish();
}
});
return myView;
}

}
Original file line number Diff line number Diff line change
@@ -1,23 +1,111 @@
package edu.cs4730.broadcastboot;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import java.util.Calendar;
import java.util.Random;

/*
* this receiver get the on boot completed message then starts the service.
* it's registered in the androidmanifest file.
*/
public class MyReceiver extends BroadcastReceiver {

String TAG="MyReceiver";

@Override
public void onReceive(Context context, Intent intent) {
int NotiID=1;
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
//boot has completed, now time to start our background service.
Log.v("MyReceiver", "Got the boot one!");
Intent i = new Intent(context, MyService.class);
context.startService(i);
Log.wtf(TAG, "Got the boot one!");
setalarm(context, 2,NotiID); //NotiID is initialize to 1, which is the start.
} else if (intent.getAction().equals(MainActivity.ACTION)) { //my custom intent
Bundle extras =intent.getExtras();
if (extras != null) {
NotiID = extras.getInt("notiid");
}
sendNoti(context, NotiID);
setalarm(context, 2, NotiID+1); //use the next notification ID number.
}
}


public void setalarm(Context context, int time, int notiID) {

//---use the AlarmManager to trigger an alarm---
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
//---get current date and time---
Calendar calendar = Calendar.getInstance();
//---sets the time for the alarm to trigger in 2 minutes from now---
calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) + time);
calendar.set(Calendar.SECOND, 0);


//---PendingIntent to launch receiver when the alarm triggers-
//Intent notificationIntent = new Intent(getApplicationContext(), MyReceiver.class);
Intent notificationIntent = new Intent(MainActivity.ACTION);
notificationIntent.setPackage("edu.cs4730.broadcastboot"); //in API 26, it must be explicit now.
notificationIntent.putExtra("notiid", notiID);
PendingIntent contentIntent = PendingIntent.getBroadcast(context, notiID, notificationIntent, 0);
Log.i(TAG, "Set alarm, I hope");
//---sets the alarm to trigger---
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), contentIntent);

}

public void sendNoti(Context context, int notiID) {

String info = "error"; //changed below.
Random myRandom = new Random();
NotificationManager mManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

//---PendingIntent to launch activity if the user selects
// the notification---
Intent notificationIntent = new Intent(context, MainActivity.class);
//random notification
switch (myRandom.nextInt(4)) {
case 0:
info = "Iphone6 is very bendy!";
break;
case 1:
info = "Pixel phones are cool.";
break;
case 2:
info = "Nexus 6 phone is huge at 5.9 inches!";
break;
case 3:
info = "Hope the Samsung 8 note doesn't catch fire!";
break;
default:
info = "No new headline.";
}

notificationIntent.putExtra("mText", info);

PendingIntent contentIntent = PendingIntent.getActivity(context, notiID, notificationIntent, 0);

//create the notification
Notification notif = new NotificationCompat.Builder(context, MainActivity.id)
.setSmallIcon(R.drawable.ic_launcher)
.setWhen(System.currentTimeMillis()) //When the event occurred, now, since noti are stored by time.
.setContentTitle("New headline!") //Title message top row.
.setContentText(info) //message when looking at the notification, second row
.setContentIntent(contentIntent) //what activity to open.
.setChannelId(MainActivity.id)
.setAutoCancel(true) //allow auto cancel when pressed.
.build(); //finally build and return a Notification.
//Show the notification
mManager.notify(1, notif); //and if we want different notifications, use notiID here instead of 1.
}

}
Loading

0 comments on commit cabe845

Please sign in to comment.