43
43
import java .io .*;
44
44
import java .security .Permission ;
45
45
46
-
47
46
class AndroidBuild extends JavaBuild {
48
47
// static final String basePackage = "changethispackage.beforesubmitting.tothemarket";
49
48
static final String basePackage = "processing.test" ;
@@ -171,7 +170,8 @@ public File createProject() throws IOException, SketchException {
171
170
172
171
final File resFolder = new File (tmpFolder , "res" );
173
172
writeRes (resFolder , sketchClassName );
174
- writeMainActivity (srcFolder );
173
+ String [] permissions = manifest .getPermissions ();
174
+ writeMainActivity (srcFolder , permissions );
175
175
176
176
177
177
// new location for SDK Tools 17: /opt/android/tools/proguard/proguard-android.txt
@@ -186,6 +186,10 @@ public File createProject() throws IOException, SketchException {
186
186
// PApplet.saveStream(new File(libsFolder, "processing-core.jar"), input);
187
187
Util .copyFile (coreZipFile , new File (libsFolder , "processing-core.jar" ));
188
188
189
+ // Copy the compatibility package, needed for the permission handling
190
+ File compatJarFile = mode .getContentFile ("mode/android-support-v4.jar" );
191
+ Util .copyFile (compatJarFile , new File (libsFolder , "android-support-v4.jar" ));
192
+
189
193
// Copy any imported libraries (their libs and assets),
190
194
// and anything in the code folder contents to the project.
191
195
copyLibraries (libsFolder , assetsFolder );
@@ -893,7 +897,7 @@ private File mkdirs(final File parent, final String name) throws SketchException
893
897
}
894
898
895
899
896
- private void writeMainActivity (final File srcDirectory ) {
900
+ private void writeMainActivity (final File srcDirectory , String [] permissions ) {
897
901
File mainActivityFile = new File (new File (srcDirectory , manifest .getPackageName ().replace ("." , "/" )),
898
902
"MainActivity.java" );
899
903
final PrintWriter writer = PApplet .createWriter (mainActivityFile );
@@ -904,25 +908,32 @@ private void writeMainActivity(final File srcDirectory) {
904
908
writer .println ("import android.view.WindowManager;" );
905
909
writer .println ("import android.widget.FrameLayout;" );
906
910
writer .println ("import android.view.ViewGroup.LayoutParams;" );
907
- writer .println ("import android.app.FragmentTransaction;" );
911
+ writer .println ("import android.app.FragmentTransaction;" );
912
+
913
+ writer .println ("import android.content.pm.PackageManager;" );
914
+ writer .println ("import android.support.v4.app.ActivityCompat;" );
915
+ writer .println ("import android.support.v4.content.ContextCompat;" );
916
+ writer .println ("import java.util.ArrayList;" );
917
+ writer .println ("import android.app.AlertDialog;" );
918
+ writer .println ("import android.content.DialogInterface;" );
919
+ writer .println ("import android.Manifest;" );
920
+
908
921
writer .println ("import processing.core.PApplet;" );
909
922
writer .println ("public class MainActivity extends Activity {" );
910
923
writer .println (" PApplet fragment;" );
911
924
writer .println (" private static final String MAIN_FRAGMENT_TAG = \" main_fragment\" ;" );
925
+ writer .println (" private static final int REQUEST_PERMISSIONS = 1;" );
912
926
writer .println (" int viewId = 0x1000;" );
913
927
writer .println (" @Override" );
914
928
writer .println (" protected void onCreate(Bundle savedInstanceState) {" );
915
929
writer .println (" super.onCreate(savedInstanceState);" );
916
930
writer .println (" Window window = getWindow();" );
917
931
writer .println (" requestWindowFeature(Window.FEATURE_NO_TITLE);" );
918
- writer .println ("window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,"
919
- + "WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);" );
920
- writer .println ("window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,"
921
- + "WindowManager.LayoutParams.FLAG_FULLSCREEN);" );
932
+ writer .println (" window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);" );
933
+ writer .println (" window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);" );
922
934
writer .println (" FrameLayout frame = new FrameLayout(this);" );
923
935
writer .println (" frame.setId(viewId);" );
924
- writer .println (" setContentView(frame, new LayoutParams(LayoutParams.MATCH_PARENT, "
925
- + "LayoutParams.MATCH_PARENT));" );
936
+ writer .println (" setContentView(frame, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));" );
926
937
writer .println (" if (savedInstanceState == null) {" );
927
938
writer .println (" fragment = new " + sketchClassName + "();" );
928
939
writer .println (" FragmentTransaction ft = getFragmentManager().beginTransaction();" );
@@ -936,6 +947,61 @@ private void writeMainActivity(final File srcDirectory) {
936
947
writer .println (" fragment.onBackPressed();" );
937
948
writer .println (" super.onBackPressed();" );
938
949
writer .println (" }" );
950
+
951
+ // Requesting permissions from user when the app resumes.
952
+ // Nice example on how to handle user response
953
+ // http://stackoverflow.com/a/35495855
954
+ // More on permission in Android 23:
955
+ // https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en
956
+ writer .println (" @Override" );
957
+ writer .println (" public void onResume() {" );
958
+ writer .println (" super.onResume();" );
959
+ writer .println (" ArrayList<String> needed = new ArrayList<String>();" );
960
+ writer .println (" int check;" );
961
+ writer .println (" boolean danger = false;" );
962
+ for (String p : permissions ) {
963
+ for (String d : Permissions .dangerous ) {
964
+ if (d .equals (p )) {
965
+ writer .println (" check = ContextCompat.checkSelfPermission(this, Manifest.permission." + p + ");" );
966
+ writer .println (" if (check != PackageManager.PERMISSION_GRANTED) {" );
967
+ writer .println (" needed.add(Manifest.permission." + p + ");" );
968
+ writer .println (" } else {" );
969
+ writer .println (" danger = true;" );
970
+ writer .println (" }" );
971
+ }
972
+ }
973
+ }
974
+ writer .println (" if (!needed.isEmpty()) {" );
975
+ writer .println (" ActivityCompat.requestPermissions(this, needed.toArray(new String[needed.size()]), REQUEST_PERMISSIONS);" );
976
+ writer .println (" } else if (danger) {" );
977
+ writer .println (" fragment.onPermissionsGranted();" );
978
+ writer .println (" }" );
979
+ writer .println (" }" );
980
+
981
+ // The event handler for the permission result
982
+ writer .println (" @Override" );
983
+ writer .println (" public void onRequestPermissionsResult(int requestCode," );
984
+ writer .println (" String permissions[], int[] grantResults) {" );
985
+ writer .println (" if (requestCode == REQUEST_PERMISSIONS) {" );
986
+ writer .println (" if (grantResults.length > 0) {" );
987
+ writer .println (" for (int i = 0; i < grantResults.length; i++) {" );
988
+ writer .println (" if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {" );
989
+ writer .println (" AlertDialog.Builder builder = new AlertDialog.Builder(this);" );
990
+ writer .println (" builder.setMessage(\" The app cannot run without these permissions, will quit now.\" )" );
991
+ writer .println (" .setCancelable(false)" );
992
+ writer .println (" .setPositiveButton(\" OK\" , new DialogInterface.OnClickListener() {" );
993
+ writer .println (" public void onClick(DialogInterface dialog, int id) {}" );
994
+ writer .println (" });" );
995
+ writer .println (" AlertDialog alert = builder.create();" );
996
+ writer .println (" alert.show();" );
997
+ writer .println (" finishAffinity();" );
998
+ writer .println (" }" );
999
+ writer .println (" }" );
1000
+ writer .println (" fragment.onPermissionsGranted();" );
1001
+ writer .println (" }" );
1002
+ writer .println (" }" );
1003
+ writer .println (" }" );
1004
+
939
1005
writer .println ("}" );
940
1006
writer .flush ();
941
1007
writer .close ();
0 commit comments