There is a strange behaviour of assigning/modifying instance variable of the class inside Button OnClick() handlers.
As shown below, the instance variable "CurrentFile" is modified inside imgBtn.setOnClickListener() handlers. But when this variable is accessed in onActivityResult() method, this variable contains the value "null".
According to my understanding, the activity "GetPicActivity" will not be destroyed till the Camera activity returns. So, the instance variable "CurrentFile" should not be null.
Please help, if I am missing some basics.
import java.io.File;
import java.io.IOException;
import com.favoritepics.R;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;
public class GetPicActivity extends Activity {
protected static final int ID_REQ_IMAGE_CAPTURE = 1;
protected static final int ID_REQ_PICK_PHOTO = 0;
protected File currentFile = null; /// Goal is "to modify this variable inside Button onClick handlers"
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.DKGRAY));
setContentView(R.layout.activity_get_pic);
// set handler image gallery
ImageButton imgBtn = (ImageButton) findViewById(R.id.imgGallery);
imgBtn.setOnClickListener(new ImageButton.OnClickListener() {
#Override
public void onClick(View v) {
// create intent to take picture on camera
Intent pickPhoto = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto, ID_REQ_PICK_PHOTO);
}
});
// set handler for camera image
imgBtn = (ImageButton) findViewById(R.id.imgCamera);
imgBtn.setOnClickListener(new ImageButton.OnClickListener() {
#Override
public void onClick(View v) {
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File tempDir = Environment.getExternalStorageDirectory();
File tempFile = null;
try {
currentFile = File
.createTempFile("_jpeg_", ".jpg", tempDir);
} catch (IOException exception) {
Toast.makeText(
GetPicActivity.this,
"Problem occured during creation of temp file! "
+ exception.getMessage(),
Toast.LENGTH_SHORT).show();
}
if (currentFile != null) {
takePicture.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(currentFile));
startActivityForResult(takePicture, ID_REQ_IMAGE_CAPTURE);
}
}
});
// set handler for cancel button
Button btnCancel = (Button) findViewById(R.id.btnCancel);
btnCancel.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case ID_REQ_IMAGE_CAPTURE:
if (resultCode == RESULT_OK) {
Intent newIntent = new Intent();
newIntent.putExtra("TYPE", requestCode);
newIntent.putExtra("PATH", currentFile.getAbsolutePath());
setResult(RESULT_OK, newIntent);
finish();
}
break;
default:
break;
}
}
}
click here to see Logcat messages
Steps what I intend to do:
1, Create a temporary file in External storage for the destination of Camera picture
2, Start Camera to take a picture by passing the URI of temporary file
3, OnActivityResult() from camera, return the (temporary) File path to previous activity for further process
But here what I see is,
As soon as the Camera is started & picture is taken, the GetPicActivity is created again. Because of this, the instance variable "CurrentFile" will be null & in OnActivityResult() , I could not get the File path of temporary file.
Why is the GetPicActivity destroyed after starting Camera?
When the camera is started, the Camera appears in the screen orientation "Landscape".
Even the orientation of already existing activity stack is changed to "Landscape" itseems.
So, When the result of Camera is returned to GetPicActivity method OnActivityResult(), the GetPicActivity is created again. But now, the instance variable "CurrentFile" is null. This, gives a NullPointerException.
Related
In my MainActivity XML file, I have an EditText which id is editsearch. I have a service class for listening to the clipboard text and open my app. Everything is happening fine but I can't set the text to my editsearch when my app opens from service class.
findViewById method is not work in the onStartCommand method of my service. I have also tried defining my editsearch EditText as a static property in my MainActivity class but not getting my expected result.
Here is my service class
package com.learn24bd.ad;
import android.app.Service;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
public class MyServiceReceiver extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("MySerivce","Service Started");
final ClipboardManager clipboard = (ClipboardManager) this.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.addPrimaryClipChangedListener(new ClipboardManager.OnPrimaryClipChangedListener() {
public void onPrimaryClipChanged() {
String copiedText = clipboard.getText().toString();
Log.i("Copied",copiedText);
/* here i want to setText to my editsearch
also tried with static property
MainActivity.editsearch.setText(copiedText);
*/
Intent i = new Intent();
i.setClass(getApplicationContext(), MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
});
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
Services aren't suitable for dealing with UI.
Instead, in your case, you should pass the clipboard content for the MainActivity class to handle. For that, pass it as an intent extra:
Intent i = new Intent();
i.setClass(getApplicationContext(), MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("clipboard_text", copiedText)
startActivity(i);
And receive and handle the text in your activity:
String clipboardText = getIntent().getStringExtra("clipboard_text");
Then you can set the text to your EditText:
editText.setText(clipboardText)
I used Ucrop to crop an image from camera, but the activity skips. Here is my MainActivity.java file. I think i'm missing something. My code is little bit longer, please take a look. Thanks in advance.
package com.example.sathwik.uploadtrail1;
import java.io.File;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.yalantis.ucrop.UCrop;
public class MainActivity extends AppCompatActivity {
// LogCat tag
private static final String TAG = MainActivity.class.getSimpleName();
// Camera activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private Uri fileUri; // file url to store image/video
private Button btnCapturePicture, btnRecordVideo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Changing action bar background color
//getActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor(getResources().getString(R.color.action_bar))));
btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
btnRecordVideo = (Button) findViewById(R.id.btnRecordVideo);
/**
* Capture image button click event
*/
btnCapturePicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
captureImage();
}
});
/**
Record video button click event
*/
btnRecordVideo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// record video
recordVideo();
}
});
// Checking camera availability
if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"Sorry! Your device doesn't support camera",
Toast.LENGTH_LONG).show();
// will close the app if the device does't have camera
finish();
}
}
/**
checking device has camera hardware or not
*/
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/**
* Launching camera app to capture image
*/
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
/**
* Launching camera app to record video
*/
private void recordVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
// set video quality
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);// set the image file
// name
// start the video capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
}
/** Perform UCrop */
public void performUcrop(){
UCrop.of(fileUri, fileUri).start(this);
}
/**
* Here we store the file url as it will be null after returning from camera
* app
*/
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save file url in bundle as it will be null on screen orientation
// changes
outState.putParcelable("file_uri", fileUri);
}
#Override
protected void onRestoreInstanceState (Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}
/**
* Receiving activity result method will be called after closing the camera
* */
#Override
protected void onActivityResult ( int requestCode, int resultCode, Intent data){
// if the result is capturing Image
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
performUcrop();
// successfully captured the image
// launching upload activity
launchUploadActivity(true);
} else if (resultCode == RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
}
} else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// video successfully recorded
//launching upload activity
launchUploadActivity(false);
} else if (resultCode == RESULT_CANCELED) {
// user cancelled recording
Toast.makeText(getApplicationContext(), "Sorry! Failed to record video", Toast.LENGTH_SHORT).show();
}
}
}
private void launchUploadActivity(boolean isImage){
Intent i = new Intent(MainActivity.this, UploadActivity.class);
i.putExtra("filePath", fileUri.getPath());
i.putExtra("isImage", isImage);
startActivity(i);
}
/**
* Creating file uri to store image/video
*/
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* returning image / video
*/
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
Config.IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "Oops! Failed create "+ Config.IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
//Logout function
private void logout(){
//Creating an alert dialog to confirm logout
android.support.v7.app.AlertDialog.Builder alertDialogBuilder = new android.support.v7.app.AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Are you sure you want to logout?");
alertDialogBuilder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
//Getting out sharedpreferences
SharedPreferences preferences = getSharedPreferences(Config.SHARED_PREF_NAME, Context.MODE_PRIVATE);
//Getting editor
SharedPreferences.Editor editor = preferences.edit();
//Puting the value false for loggedin
editor.putBoolean(Config.LOGGEDIN_SHARED_PREF, false);
//Putting blank value to email
editor.putString(Config.EMAIL_SHARED_PREF, "");
//Saving the sharedpreferences
editor.commit();
//Starting login activity
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
}
});
alertDialogBuilder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
}
});
//Showing the alert dialog
android.support.v7.app.AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.menuLogout) {
logout();
}
return super.onOptionsItemSelected(item);
}
}
I added Ucrop libraries in my gradle file. My gradle app module has this
compile 'com.github.yalantis:ucrop:2.2.1-native'
Android monitor shows this log
07-02 00:42:22.953 1534-2050/system_process I/ActivityManager: START u0 {cmp=com.example.sathwik.uploadtrail1/com.yalantis.ucrop.UCropActivity (has extras)} from uid 10058 on display 0
07-02 00:42:22.954 1534-2050/system_process V/WindowManager: addAppToken: AppWindowToken{2e96b812 token=Token{39e8cb9d ActivityRecord{22ae1a74 u0 com.example.sathwik.uploadtrail1/com.yalantis.ucrop.UCropActivity t29}}} to stack=1 task=29 at 2
07-02 00:42:22.959 1534-1955/system_process I/ActivityManager: START u0 {cmp=com.example.sathwik.uploadtrail1/.UploadActivity (has extras)} from uid 10058 on display 0
07-02 00:42:22.962 1534-1955/system_process V/WindowManager: addAppToken: AppWindowToken{278b8499 token=Token{39cc69e0 ActivityRecord{322e0be3 u0 com.example.sathwik.uploadtrail1/.UploadActivity t29}}} to stack=1 task=29 at 3
07-02 00:42:23.578 14053-14053/com.example.sathwik.uploadtrail1 I/Choreographer: Skipped 36 frames! The application may be doing too much work on its main thread.
07-02 00:42:23.945 1534-1836/system_process V/WindowManager: Adding window Window{14ab833f u0 com.example.sathwik.uploadtrail1/com.example.sathwik.uploadtrail1.UploadActivity} at 6 of 11 (after Window{14c5edfe u0 com.android.camera/com.android.camera.Camera})
07-02 00:42:24.332 1534-1563/system_process I/ActivityManager: Displayed com.example.sathwik.uploadtrail1/.UploadActivity: +1s293ms
07-02 00:42:24.333 1534-1558/system_process I/ActivityManager: Killing 2721:com.google.android.gms.unstable/u0a7 (adj 15): empty for 3423s
07-02 00:42:24.333 1534-1558/system_process W/libprocessgroup: failed to open /acct/uid_10007/pid_2721/cgroup.procs: No such file or directory
07-02 00:42:25.366 2376-14273/com.google.android.gms W/PlatformStatsUtil: Could not retrieve Usage & Diagnostics setting. Giving up.
07-02 00:42:25.374 1534-1836/system_process I/ActivityManager: Killing 9541:com.android.calendar/u0a18 (adj 15): empty for 2545s
07-02 00:42:25.374 1534-1836/system_process W/libprocessgroup: failed to open /acct/uid_10018/pid_9541/cgroup.procs: No such file or directory
UCrop is working fine, but you are starting it the wrong way, if you specify the same argument for source and destination, the onActivityResult will be called immediately. and obviously with no result, fix:
1. specify different source and destination
UCrop.of(fileUri, dstUri).start(this);
2. add the code to handle the response from uCrop. in my tutorial
https://youtu.be/glwM0cAUV4A, the code in onActivityResult is not perfect but it works.
I've been able to successfully create an app (thanks davidgyoung!) that monitors beacons in the background and then subsequently opens the app in the background.
Now I would like my app to first prompt with a notification in the status bar saying something like "I've detected a beacon! Would you like to open out app?". Then the user would click on the notification to open the app or dismiss it and ignore the notification.
I've searched on stack overflow for something like but haven't had much success in finding something relevant to beacons. I did find this page that talks about adding StatusBar notifications but I'm not having much success.
Particularly its in my BeaconReferenceApplication.java and MonitoringActivity.java file. I think I put the code in the correct place (after didEnterRegion) but I have unresolved classes for areas like notificationButton, setLatestEventInfo, etc. Can someone help? Thanks in advance!
BeaconReferenceApplication.java:
import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.Identifier;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
import org.altbeacon.beacon.startup.RegionBootstrap;
import org.altbeacon.beacon.startup.BootstrapNotifier;
public class BeaconReferenceApplication extends Application implements BootstrapNotifier {
private static final String TAG = "BeaconReferenceApp";
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
private boolean haveDetectedBeaconsSinceBoot = false;
private MonitoringActivity monitoringActivity = null;
public void onCreate() {
super.onCreate();
BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
// By default the AndroidBeaconLibrary will only find AltBeacons. If you wish to make it
// find a different type of beacon, you must specify the byte layout for that beacon's
// advertisement with a line like below. The example shows how to find a beacon with the
// same byte layout as AltBeacon but with a beaconTypeCode of 0xaabb. To find the proper
// layout expression for other beacon types, do a web search for "setBeaconLayout"
// including the quotes.
//
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));
Log.d(TAG, "setting up background monitoring for beacons and power saving");
// wake up the app when a beacon is seen
Region region = new Region("backgroundRegion", Identifier.parse("2F234454F4911BA9FFA6"), null, null);
regionBootstrap = new RegionBootstrap(this, region);
// simply constructing this class and holding a reference to it in your custom Application
// class will automatically cause the BeaconLibrary to save battery whenever the application
// is not visible. This reduces bluetooth power usage by about 60%
backgroundPowerSaver = new BackgroundPowerSaver(this);
// If you wish to test beacon detection in the Android Emulator, you can use code like this:
// BeaconManager.setBeaconSimulator(new TimedBeaconSimulator() );
// ((TimedBeaconSimulator) BeaconManager.getBeaconSimulator()).createTimedSimulatedBeacons();
}
#Override
public void didEnterRegion(Region arg0) {
// In this example, this class sends a notification to the user whenever a Beacon
// matching a Region (defined above) are first seen.
Log.d(TAG, "did enter region.");
if (!haveDetectedBeaconsSinceBoot) {
Log.d(TAG, "sending notification to StatusBar");
#SuppressWarnings("deprecation")
private void Notify(String notificationTitle, String notificationMessage) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
#SuppressWarnings("deprecation")
Notification notification = new Notification(R.mipmap.ic_launcher,
"New Message", System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MonitoringActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(MonitoringActivity.this, notificationTitle,
notificationMessage, pendingIntent);
notificationManager.notify(9999, notification);
}
}
} else {
if (monitoringActivity != null) {
Log.d(TAG, "auto launching MainActivity");
// The very first time since boot that we detect an beacon, we launch the
// MainActivity
Intent intent = new Intent(this, MonitoringActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Important: make sure to add android:launchMode="singleInstance" in the manifest
// to keep multiple copies of this activity from getting created if the user has
// already manually launched the app.
this.startActivity(intent);
haveDetectedBeaconsSinceBoot = true;
}
}
}
#Override
public void didExitRegion(Region region) {
if (monitoringActivity != null) {
Log.d(TAG,"I no longer see a beacon.");
}
}
#Override
public void didDetermineStateForRegion(int state, Region region) {
if (monitoringActivity != null) {
Log.d(TAG,"I have just switched from seeing/not seeing beacons: " + state);
}
}
private void sendNotification() {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setContentTitle("Beacon Reference Application")
.setContentText("An beacon is nearby.")
.setSmallIcon(R.mipmap.ic_launcher);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntent(new Intent(this, MonitoringActivity.class));
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
builder.setContentIntent(resultPendingIntent);
NotificationManager notificationManager =
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, builder.build());
}
public void setMonitoringActivity(MonitoringActivity activity) {
this.monitoringActivity = activity;
}
}
MonitoringActivity.java:
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import org.altbeacon.beacon.BeaconManager;
public class MonitoringActivity extends Activity {
protected static final String TAG = "MonitoringActivity";
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
private WebView mWebView;
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_monitoring);
// code for button notification
Button notificationButton = (Button) findViewById(R.id.notificationButton);
notificationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Notify("Title: Meeting with Business",
"Msg:Pittsburg 10:00 AM EST ");
}
});
// code for button notification
mWebView = (WebView) findViewById(R.id.activity_main_webview);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.loadUrl("http://communionchapelefca.org/edy-home");
mWebView.setWebViewClient(new MyAppWebViewClient());
verifyBluetooth();
Log.d(TAG, "Application just launched");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android M Permission check
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect beacons in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#TargetApi(23)
#Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
}
private class HelloWebViewClient extends WebViewClient{
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView webView, String url)
{
webView.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
progressBar.setVisibility(view.GONE);
}
}
#Override
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
public void onRangingClicked(View view) {
Intent myIntent = new Intent(this, RangingActivity.class);
this.startActivity(myIntent);
}
#Override
public void onResume() {
super.onResume();
((BeaconReferenceApplication) this.getApplicationContext()).setMonitoringActivity(this);
}
#Override
public void onPause() {
super.onPause();
((BeaconReferenceApplication) this.getApplicationContext()).setMonitoringActivity(null);
}
private void verifyBluetooth() {
try {
if (!BeaconManager.getInstanceForApplication(this).checkAvailability()) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Bluetooth not enabled");
builder.setMessage("Please enable bluetooth in settings and restart this application.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
finish();
System.exit(0);
}
});
builder.show();
}
}
catch (RuntimeException e) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Bluetooth LE not available");
builder.setMessage("Sorry, this device does not support Bluetooth LE.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
finish();
System.exit(0);
}
});
builder.show();
}
}
}
So I was able to fix my problem by using the example from the Android Developers website for Notifications. I used their sample code, adapted it to my use, and then even further used .bigText to make my notification look great. Credit goes to them and daviggyoung for getting my app working. Thanks!
I also didnt need to edit my MonitoringActivity.java like I posted earlier.
final BeaconReferenceApplication.java:
import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.RemoteViews;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.Identifier;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
import org.altbeacon.beacon.startup.RegionBootstrap;
import org.altbeacon.beacon.startup.BootstrapNotifier;
public class BeaconReferenceApplication extends Application implements BootstrapNotifier {
private static final String TAG = "BeaconReferenceApp";
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
private boolean haveDetectedBeaconsSinceBoot = false;
private MonitoringActivity monitoringActivity = null;
public void onCreate() {
super.onCreate();
BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
// By default the AndroidBeaconLibrary will only find AltBeacons. If you wish to make it
// find a different type of beacon, you must specify the byte layout for that beacon's
// advertisement with a line like below. The example shows how to find a beacon with the
// same byte layout as AltBeacon but with a beaconTypeCode of 0xaabb. To find the proper
// layout expression for other beacon types, do a web search for "setBeaconLayout"
// including the quotes.
//
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));
Log.d(TAG, "setting up background monitoring for beacons and power saving");
// wake up the app when a beacon is seen
Region region = new Region("backgroundRegion", Identifier.parse("2F234454F4911BA9FFA6"), null, null);
regionBootstrap = new RegionBootstrap(this, region);
// simply constructing this class and holding a reference to it in your custom Application
// class will automatically cause the BeaconLibrary to save battery whenever the application
// is not visible. This reduces bluetooth power usage by about 60%
backgroundPowerSaver = new BackgroundPowerSaver(this);
// If you wish to test beacon detection in the Android Emulator, you can use code like this:
// BeaconManager.setBeaconSimulator(new TimedBeaconSimulator() );
// ((TimedBeaconSimulator) BeaconManager.getBeaconSimulator()).createTimedSimulatedBeacons();
}
#Override
public void didEnterRegion(Region arg0) {
// In this example, this class sends a notification to the user whenever a Beacon
// matching a Region (defined above) are first seen.
Log.d(TAG, "did enter region.");
if (!haveDetectedBeaconsSinceBoot) {
Log.d(TAG, "sending notification to StatusBar");
//begin code for notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Message from Communion Chapel")
.setContentText("Welcome! Thanks for coming!")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("We noticed that you're here today, click here to open the app and get today's Sermon Notes and Bulletin."))
.setAutoCancel(true);
;
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, MonitoringActivity.class);
// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MonitoringActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(123, mBuilder.build());
}
}
#Override
public void didExitRegion(Region region) {
if (monitoringActivity != null) {
Log.d(TAG,"I no longer see a beacon.");
}
}
#Override
public void didDetermineStateForRegion(int state, Region region) {
if (monitoringActivity != null) {
Log.d(TAG,"I have just switched from seeing/not seeing beacons: " + state);
}
}
private void sendNotification() {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setContentTitle("Beacon Reference Application")
.setContentText("A beacon is nearby.")
.setSmallIcon(R.drawable.app_icon);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntent(new Intent(this, MonitoringActivity.class));
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
builder.setContentIntent(resultPendingIntent);
NotificationManager notificationManager =
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, builder.build());
}
public void setMonitoringActivity(MonitoringActivity activity) {
this.monitoringActivity = activity;
}
}
I'm trying to make facebook for "someone" else opens on application, not on a browser, for example National Geography https://www.facebook.com/natgeo
Here is the code I have:
ddc.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/natgeo"));
startActivity(browserIntent);
}
});
I found one on stackoverflow and I tried it and it has errors, here is the code:
try {
//try to open page in facebook native app.
String uri = "fb://page/" + natgeo; //Custom URL
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);
}
catch (ActivityNotFoundException ex){
//facebook native app isn't available, use browser.
String uri = "https://www.facebook.com/natgeo" + natgeo; //Normal URL
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(uriMobile));
startActivity(i);
}
the thing is I want, if someone didn't have facebook App, it will open in the browser.
Edited
package fa;
import com.f.fa.R;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
Button ddc;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_item);
addListenerOnButton();
}
public void addListenerOnButton() {
ddc = (Button) findViewById(R.id.ddc);
try {
//try to open page in facebook native app.
String uri = "fb://page/" + natgeo; //Custom URL
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);
}
catch (ActivityNotFoundException ex){
//facebook native app isn't available, use browser.
String uri = "https://www.facebook.com/natgeo" + natgeo; //Normal URL
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(i);
}
}
}
You use a variable, which is not declared before (read compiler errors)..
Add String natgeo = "my content"; before your try-catch block to make your code compiling.
I'm trying to develop an app which will scan a barcode, store the value in a variable, then scan another barcode and match that value with the previous value and return a 'match' or 'no match' result. I have already got the first part working thanks to help from foamyguy, here's the initial code that I used,
package com.barcodesample;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class BarcodeSample extends Activity {
private Button scanBtn;
private TextView resultsTxt;
/** Called when the activity is first created. */;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
scanBtn = (Button) findViewById(R.id.scanBtn);
resultsTxt = (TextView) findViewById(R.id.resultsTxt);
scanBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
resultsTxt.setText("Scanning...");
Intent intent = new intent("com.google.zxing.client.android.SCAN");
try {
startActivityForResult(intent, 0);
} catch (ActivityNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
new AlertDialog.Builder(v.getContext())
.setTitle("WARNING:")
.setMessage("You don't have Barcode Scanner installed. Please install it.")
.setCancelable(false)
.setNeutralButton("Install it now", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
}
})
.show();
}
}
});
}
/*Here is where we come back after the Barcode Scanner is done*/
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
// contents contains whatever the code was
String contents = intent.getStringExtra("SCAN_RESULT");
// Format contains the type of code i.e. UPC, EAN, QRCode etc...
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
// Handle successful scan. In this example I just put the results into the TextView
resultsTxt.setText(format + "\n" + contents);
} else if (resultCode == RESULT_CANCELED) {
// Handle cancel. If the user presses 'back' before a code is scanned.
resultsTxt.setText("Canceled");
}
}
}
}
Now how do I start another intent with another scan button similar to the one above, and finally how to compare both values and return the match or no match in a new screen?
Thanks in advance for the valuable advice
Use the same code on the other button except following.
startActivityForResult(intent, 1); // right now it's 0 for button 1
Now add one more section in onActivityResult for returning results for 2nd button.
if (requestCode == 1) {
// your code here that will be used for comparing.
}