I am trying to build my own custom camera application I have learn through the Android developers Group about how to code the whole application but as soon as I launch the camera it crashes I don't know what is the problem here is my code:
package com.example.tapeit;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore.Files.FileColumns;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
public class CameraActivity extends Activity implements Camera.PictureCallback {
private Camera mCamera;
private CameraPreview mPreview;
String TAG = "TapeIt";
public static final int MEDIA_TYPE_IMAGE = 1;
Button captureButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.preview_layout);
mCamera = getCameraInstance();
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(preview);
captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
mCamera.takePicture(null, null, mPicture);
}
});
}
private boolean checkCameraHardware(Context context){
if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
return true;
}else{
return false;
}
}
public static Camera getCameraInstance() {
// TODO Auto-generated method stub
Camera c = null;
try {
c = Camera.open();
} catch (Exception e) {
}
return c;
}
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " );
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
private static File getOutputMediaFile(int mediaTypeImage) {
// TODO Auto-generated method stub
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "CameraApp");
if(! mediaStorageDir.exists()){
if(! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = new File(mediaStorageDir.getPath() + File.separator +"IMG_"+ timeStamp + ".jpg");
return mediaFile;
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " );
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
}
And here is my preview Class:
package com.example.tapeit;
import java.io.IOException;
import android.content.Context;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.hardware.Camera;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
private Camera mCamera;
private SurfaceHolder mHolder;
String TAG = "TapeIt";
public CameraPreview (Context context, Camera camera){
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
}
public void surfaceCreated(SurfaceHolder holder){
try{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}catch(IOException e){
Log.d(TAG, "Error setting camera preview" + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// TODO Auto-generated method stub
if(mHolder.getSurface() == null){
return;
}
try{
mCamera.stopPreview();
}catch(Exception e){
}
//You should make here changes when the device is rotated or when any other change
// set preview size and make any resize, rotate or
// reformatting changes here
//mCamera.getParameters().getSupportedPreviewSizes();
try{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}catch(IOException e){
Log.d(TAG, "Error setting camera preview" + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
}
My manifest uses all the permision here they are:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.tapeit.CameraActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
My logcat in the console is posted here:
04-04 11:19:32.010: D/AndroidRuntime(21270): Shutting down VM
04-04 11:19:32.010: W/dalvikvm(21270): threadid=1: thread exiting with uncaught exception (group=0x40eb72a0)
04-04 11:19:32.010: E/AndroidRuntime(21270): FATAL EXCEPTION: main
04-04 11:19:32.010: E/AndroidRuntime(21270): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tapeit/com.example.tapeit.CameraActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2092)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.app.ActivityThread.access$700(ActivityThread.java:134)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.os.Handler.dispatchMessage(Handler.java:99)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.os.Looper.loop(Looper.java:137)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.app.ActivityThread.main(ActivityThread.java:4867)
04-04 11:19:32.010: E/AndroidRuntime(21270): at java.lang.reflect.Method.invokeNative(Native Method)
04-04 11:19:32.010: E/AndroidRuntime(21270): at java.lang.reflect.Method.invoke(Method.java:511)
04-04 11:19:32.010: E/AndroidRuntime(21270): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
04-04 11:19:32.010: E/AndroidRuntime(21270): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
04-04 11:19:32.010: E/AndroidRuntime(21270): at dalvik.system.NativeStart.main(Native Method)
04-04 11:19:32.010: E/AndroidRuntime(21270): Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.view.ViewGroup.addViewInner(ViewGroup.java:3439)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.view.ViewGroup.addView(ViewGroup.java:3310)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.view.ViewGroup.addView(ViewGroup.java:3255)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.view.ViewGroup.addView(ViewGroup.java:3231)
04-04 11:19:32.010: E/AndroidRuntime(21270): at com.example.tapeit.CameraActivity.onCreate(CameraActivity.java:39)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.app.Activity.performCreate(Activity.java:5047)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
04-04 11:19:32.010: E/AndroidRuntime(21270): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2056)
04-04 11:19:32.010: E/AndroidRuntime(21270): ... 11 more
preview.addView(preview);
You are attempting to add the FrameLayout to itself. This will not work.
Presumably, the parameter should be mPreview.
You may wish to use more distinctive names for variables, such as not having both preview and mPreview.
Related
Hi I am trying to print a text file with the double data, line by line, read from a file on my android device however it doesn't seem to be working what is wrong? I get no errors but not proper print out?
in my bodyTempInfo View I get readout:
Your Body Temperature Readings are:[]
my temp2.txt file, there is a total of 1440 numbers, not going to paste them all here
37.06750839
36.89390613
36.88484785
36.81941363
36.81815453
36.97372599
37.0510889
36.90421803
36.90452867
36.81245808
36.91739551
37.05989195
36.80757783
36.85141347
37.04927826
36.80384926
36.94000689
37.04948705
37.07007973
36.95211596
37.05161886
36.97029703
37.03218835
36.89381629
My bodyTempInfo.Java
package com.teamfara.circadianrhythmmonitor4;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class bodyTempInfo extends AppCompatActivity {
ArrayList<Double> currentBodyTemp;
public void displayCurrentBodyTempArray(View view) throws FileNotFoundException {
ArrayList<Double> list = new ArrayList<>();
File sdcard = Environment.getExternalStorageDirectory();
//Get the text file
//Read text from file
File file = new File(sdcard, "temp2.txt");
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
list.add(Double.parseDouble(line));
text.append('\n');
}
br.close();
}
catch(IOException e) {
}
/*
Scanner file2 = new Scanner(new File(sdcard, "temp.txt"));
while (file2.hasNextLine()) {
String line = file2.nextLine();
Scanner scanner = new Scanner(line);
scanner.useDelimiter(",");
while (scanner.hasNextDouble()) {
list.add(scanner.nextDouble());
}
scanner.close();
}
*/
currentBodyTemp = list;
displayBodyTemp("Your Body Temperature Readings are:" + list);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_body_temp_info);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
try {
displayCurrentBodyTempArray(findViewById(R.id.bodyTempInfoArray));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void displayBodyTemp(String bodyTemp) {
TextView textView = (TextView) findViewById(R.id.bodyTempInfoArray);
textView.setText(bodyTemp);
}
}
logcat
10-25 14:15:11.041 11084-11084/? E/Zygote: MountEmulatedStorage()
10-25 14:15:11.041 11084-11084/? E/Zygote: v2
10-25 14:15:11.041 11084-11084/? I/libpersona: KNOX_SDCARD checking this for 10385
10-25 14:15:11.041 11084-11084/? I/libpersona: KNOX_SDCARD not a persona
10-25 14:15:11.051 11084-11084/? I/SELinux: Function: selinux_compare_spd_ram , priority [2] , priority version is VE=SEPF_SM-G920V_5.1.1_0033
10-25 14:15:11.051 11084-11084/? E/SELinux: [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
10-25 14:15:11.051 11084-11084/? I/art: Late-enabling -Xcheck:jni
10-25 14:15:11.111 11084-11084/? D/TimaKeyStoreProvider: TimaSignature is unavailable
10-25 14:15:11.111 11084-11084/? D/ActivityThread: Added TimaKeyStore provider
10-25 14:15:11.211 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: Inside getClassLibPath + mLibMap{0=, 1=}
10-25 14:15:11.231 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: Inside getClassLibPath caller
10-25 14:15:11.241 11084-11084/com.teamfara.circadianrhythmmonitor4 D/InjectionManager: InjectionManager
10-25 14:15:11.241 11084-11084/com.teamfara.circadianrhythmmonitor4 D/InjectionManager: fillFeatureStoreMap com.teamfara.circadianrhythmmonitor4
10-25 14:15:11.241 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: Constructor com.teamfara.circadianrhythmmonitor4, Feature store :{}
10-25 14:15:11.241 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: featureStore :{}
10-25 14:15:11.301 11084-11084/com.teamfara.circadianrhythmmonitor4 D/SecWifiDisplayUtil: Metadata value : SecSettings2
10-25 14:15:11.491 11084-11084/com.teamfara.circadianrhythmmonitor4 D/PhoneWindow: *FMB* installDecor mIsFloating : false
10-25 14:15:11.491 11084-11084/com.teamfara.circadianrhythmmonitor4 D/PhoneWindow: *FMB* installDecor flags : -2139029248
10-25 14:15:11.761 11084-11084/com.teamfara.circadianrhythmmonitor4 D/Activity: performCreate Call Injection manager
10-25 14:15:11.771 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: dispatchOnViewCreated > Target : com.teamfara.circadianrhythmmonitor4.MainActivity isFragment :false
10-25 14:15:11.791 11084-11175/com.teamfara.circadianrhythmmonitor4 D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
10-25 14:15:11.821 11084-11084/com.teamfara.circadianrhythmmonitor4 D/PhoneWindow: *FMB* isFloatingMenuEnabled mFloatingMenuBtn : null
10-25 14:15:11.821 11084-11084/com.teamfara.circadianrhythmmonitor4 D/PhoneWindow: *FMB* isFloatingMenuEnabled return false
10-25 14:15:11.891 11084-11084/com.teamfara.circadianrhythmmonitor4 D/SRIB_DCS: log_dcs ThreadedRenderer::initialize entered!
10-25 14:15:11.951 11084-11175/com.teamfara.circadianrhythmmonitor4 D/libEGL: loaded /vendor/lib64/egl/libGLES_mali.so
10-25 14:15:11.991 11084-11175/com.teamfara.circadianrhythmmonitor4 I/OpenGLRenderer: Initialized EGL, version 1.4
10-25 14:15:12.001 11084-11175/com.teamfara.circadianrhythmmonitor4 I/OpenGLRenderer: HWUI protection enabled for context , &this =0x7f79c8abc0 ,&mEglDisplay = 1 , &mEglConfig = 1912140464
10-25 14:15:12.011 11084-11175/com.teamfara.circadianrhythmmonitor4 D/OpenGLRenderer: Get maximum texture size. GL_MAX_TEXTURE_SIZE is 8192
10-25 14:15:12.011 11084-11175/com.teamfara.circadianrhythmmonitor4 D/OpenGLRenderer: Enabling debug mode 0
10-25 14:15:12.011 11084-11175/com.teamfara.circadianrhythmmonitor4 D/mali_winsys: new_window_surface returns 0x3000, [1440x2560]-format:1
10-25 14:15:12.391 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: dispatchCreateOptionsMenu :com.teamfara.circadianrhythmmonitor4.MainActivity
10-25 14:15:12.391 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: dispatchPrepareOptionsMenu :com.teamfara.circadianrhythmmonitor4.MainActivity
10-25 14:15:12.461 11084-11084/com.teamfara.circadianrhythmmonitor4 I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy#2f8d81aa time:4028871
10-25 14:15:12.801 11084-11084/com.teamfara.circadianrhythmmonitor4 V/ActivityThread: updateVisibility : ActivityRecord{81a0e76 token=android.os.BinderProxy#2f8d81aa {com.teamfara.circadianrhythmmonitor4/com.teamfara.circadianrhythmmonitor4.MainActivity}} show : true
10-25 14:15:14.701 11084-11084/com.teamfara.circadianrhythmmonitor4 I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy#2f8d81aa time:4031112
10-25 14:15:14.921 11084-11084/com.teamfara.circadianrhythmmonitor4 D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
10-25 14:15:14.971 11084-11084/com.teamfara.circadianrhythmmonitor4 I/Timeline: Timeline: Activity_launch_request id:com.teamfara.circadianrhythmmonitor4 time:4031384
10-25 14:15:15.051 11084-11084/com.teamfara.circadianrhythmmonitor4 D/PhoneWindow: *FMB* installDecor mIsFloating : false
10-25 14:15:15.051 11084-11084/com.teamfara.circadianrhythmmonitor4 D/PhoneWindow: *FMB* installDecor flags : -2139029248
10-25 14:15:15.071 11084-11084/com.teamfara.circadianrhythmmonitor4 D/Activity: performCreate Call Injection manager
10-25 14:15:15.121 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: dispatchOnViewCreated > Target : com.teamfara.circadianrhythmmonitor4.bodyTempInfo isFragment :false
10-25 14:15:15.121 11084-11084/com.teamfara.circadianrhythmmonitor4 D/SecWifiDisplayUtil: Metadata value : SecSettings2
10-25 14:15:15.141 11084-11084/com.teamfara.circadianrhythmmonitor4 D/PhoneWindow: *FMB* isFloatingMenuEnabled mFloatingMenuBtn : null
10-25 14:15:15.141 11084-11084/com.teamfara.circadianrhythmmonitor4 D/PhoneWindow: *FMB* isFloatingMenuEnabled return false
10-25 14:15:15.181 11084-11084/com.teamfara.circadianrhythmmonitor4 D/SRIB_DCS: log_dcs ThreadedRenderer::initialize entered!
10-25 14:15:15.181 11084-11175/com.teamfara.circadianrhythmmonitor4 D/mali_winsys: new_window_surface returns 0x3000, [1440x2560]-format:1
10-25 14:15:15.201 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: dispatchCreateOptionsMenu :com.teamfara.circadianrhythmmonitor4.bodyTempInfo
10-25 14:15:15.201 11084-11084/com.teamfara.circadianrhythmmonitor4 I/InjectionManager: dispatchPrepareOptionsMenu :com.teamfara.circadianrhythmmonitor4.bodyTempInfo
10-25 14:15:15.271 11084-11084/com.teamfara.circadianrhythmmonitor4 I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy#1f826b14 time:4031688
10-25 14:15:15.311 11084-11084/com.teamfara.circadianrhythmmonitor4 V/ActivityThread: updateVisibility : ActivityRecord{81a0e76 token=android.os.BinderProxy#2f8d81aa {com.teamfara.circadianrhythmmonitor4/com.teamfara.circadianrhythmmonitor4.MainActivity}} show : false
My content_body_temp_info.xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_body_temp_info"
tools:context="com.teamfara.circadianrhythmmonitor4.bodyTempInfo">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text = "Body Temperature Measurements will go here"
android:id = "#+id/bodyTempInfoArray"/>
</RelativeLayout>
my MainActivity.java
package com.teamfara.circadianrhythmmonitor4;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private final static int REQUEST_ENABLE_BT = 1;
UUID myUUID = UUID.randomUUID();
private static final int DISCOVER_DURATION = 300;
private static final int REQUEST_BLU = 1;
ArrayAdapter<String> mArrayAdapter;
ArrayList<Double> currentBodyTemp;
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBIntent, REQUEST_ENABLE_BT);
}
//If there are paired devices
/*Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
//Loop through the paired devices
for (BluetoothDevice device : pairedDevices) {
//add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
*/
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
ArrayList<Double> lightInfo;
public void sendLightFile() {
String filename = "lightInfo";
String string = "Here is light info" + lightInfo;
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
// Send information over bluetooth?
}
public void goToBodyInfo(View view) {
Intent intent = new Intent(this, bodyTempInfo.class);
startActivity(intent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void sendLight(View view) {
Intent intent = new Intent(this, ConnectTest.class);
startActivity(intent);
}
// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("CircadianRhythmMonitor", myUUID);
} catch (IOException e) {
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
//manageConnectedSocket(socket);
//mmServerSocket.close();
break;
}
}
}
/**
* Will cancel the listening socket, and cause the thread to finish
*/
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) {
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
// mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
//.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private void displayBodyTemp(String bodyTemp) {
TextView textView = (TextView) findViewById(R.id.bodyTempInfoArray);
textView.setText(bodyTemp);
}
}
my AndroidManfiest.xml
package="com.teamfara.circadianrhythmmonitor4" >
<!-- Allows bluetooth to be used from this app -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.NFC" />
<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"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".bodyTempInfo"
android:label="#string/title_activity_body_temp_info"
android:parentActivityName=".MainActivity"
android:theme="#style/AppTheme.NoActionBar" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.teamfara.circadianrhythmmonitor4.MainActivity" />
</activity>
<activity
android:name=".ConnectTest"
android:label="#string/title_activity_body_temp_info"
android:parentActivityName=".MainActivity"
android:theme="#style/AppTheme.NoActionBar" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.teamfara.circadianrhythmmonitor4.MainActivity" />
</activity>
</application>
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
</manifest>
In your displayBodyTemp() function, you are passing a String and using + to add an arraylist. That is the story.You need to pass a string only. Or override the toString() method of the Arraylist
OR, try this:
displayBodyTemp("Your Body Temperature Readings are:" + text);
Trying to create an android application to record video and capture images. I've followed the tutorials thus far with some success however I must have a lack of knowledge about the android sdk to not be able to get around this issue. No doubt I will feel stupid once someone figures this out but I'm here to learn in the end.
Here is the MainActivity.java
package example.myapplication;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
public MainActivity(Context context) {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
/** Check if this device has a camera */
public boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Here is the CameraPreview.java
package example.myapplication;
import android.content.Context;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/** A basic Camera preview class */
public class CameraPreview extends MainActivity implements SurfaceHolder.Callback {
private android.hardware.Camera.PictureCallback mPicture;
private Camera mCamera;
private CameraPreview mPreview;
private SurfaceHolder mHolder;
private SurfaceHolder holder;
public void setContentView(int activity_camera) {}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private static final String TAG = "CameraPreview";
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HH:mm:ss").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;
}
public void onClick() {
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0){
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
});
}
public SurfaceHolder getHolder() {
return holder;
}
public void setHolder(SurfaceHolder holder) {
this.holder = holder;
}
}
Here is the AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.myapplication" >
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera2" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
and the logcat
Process: example.myapplication, PID: 20671
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{example.myapplication/example.myapplication.MainActivity}: java.lang.InstantiationException: can't instantiate class example.myapplication.MainActivity; no empty constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2514)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2653)
at android.app.ActivityThread.access$800(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5872)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.InstantiationException: can't instantiate class installation04.myapplication.MainActivity; no empty constructor
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2505)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2653)
at android.app.ActivityThread.access$800(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5872)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
at dalvik.system.NativeStart.main(Native Method)
A couple of things that need to be sorted:
Please remove all constructors from classes that extend Activity. - Activities do not work this way. Please look read how Activity Life cycle works.
Please add the CameraPreview activity to your manifest as well.
delete MainActivity constructor
public MainActivity(Context context) {
}
Please read carefully the stacktrace:
java.lang.RuntimeException: Unable to instantiate activity
ComponentInfo{example.myapplication/example.myapplication.MainActivity}:
java.lang.InstantiationException: can't instantiate class
example.myapplication.MainActivity; no empty constructor
You have created constructor in your Activity. Remove the constructor from your Activities and use the Lifecycle callbacks.
As per android guidelines you should not create constructor in the Activity classes since android OS creates object of Activity classes and it use the default empty constructor of the class to create object.
I have been trying to learn how Google Cloud Messaging works in Android apps, specifically multicast messaging, so I found a tutorial with source code. Unfortunately I can get the program to compile without error but when it runs, I get a fatal exception. Anyone know what is wrong?
Here is the main activity:
package com.ganyo.pushtest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gcm.GCMRegistrar;
import static com.ganyo.pushtest.Util.*;
import static com.ganyo.pushtest.Util.TAG;
public class PushMainActivity extends Activity {
private TextView messageTextView;
private Button sendButton;
private AlertDialogManager alert = new AlertDialogManager();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this is a hack to force AsyncTask to be initialized on main thread. Without this things
// won't work correctly on older versions of Android (2.2, apilevel=8)
try {
Class.forName("android.os.AsyncTask");
} catch (Exception ignored) {}
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
initUI();
AppServices.loginAndRegisterForPush(this);
}
private void initUI() {
setContentView(R.layout.main);
messageTextView = (TextView)findViewById(R.id.lblMessage);
sendButton = (Button)findViewById(R.id.sendButton);
sendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AppServices.sendMyselfANotification(v.getContext());
}
});
registerReceiver(notificationReceiver, new IntentFilter(DISPLAY_MESSAGE_ACTION));
}
/**
* Receives push Notifications
* */
private final BroadcastReceiver notificationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
/**
* Take some action upon receiving a push notification here!
**/
String message = intent.getExtras().getString(EXTRA_MESSAGE);
if (message == null) { message = "Empty Message"; }
Log.i(TAG, message);
messageTextView.append("\n" + message);
alert.showAlertDialog(context, getString(R.string.gcm_alert_title), message);
Toast.makeText(getApplicationContext(), getString(R.string.gcm_message, message), Toast.LENGTH_LONG).show();
WakeLocker.release();
}
};
// this will be called when the screen rotates instead of onCreate()
// due to manifest setting, see: android:configChanges
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
initUI();
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(notificationReceiver);
}
}
Here is the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ganyo.pushtest"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16"/>
<permission android:name="com.ganyo.pushtest.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.ganyo.pushtest.permission.C2D_MESSAGE" />
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<activity android:name="com.ganyo.pushtest.PushMainActivity"
android:label="#string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.ganyo.pushtest" />
</intent-filter>
</receiver>
<service android:name="GCMIntentService" />
</application>
</manifest>
Here is Appservices:
package com.ganyo.pushtest;
import android.content.Context;
import android.util.Log;
import com.apigee.sdk.ApigeeClient;
import com.apigee.sdk.data.client.DataClient;
import com.apigee.sdk.data.client.callbacks.ApiResponseCallback;
import com.apigee.sdk.data.client.callbacks.DeviceRegistrationCallback;
import com.apigee.sdk.data.client.entities.Device;
import com.apigee.sdk.data.client.entities.Entity;
import com.apigee.sdk.data.client.response.ApiResponse;
import com.apigee.sdk.data.client.utils.JsonUtils;
import com.google.android.gcm.GCMRegistrar;
import com.apigee.sdk.data.client.push.GCMPayload;
import com.apigee.sdk.data.client.push.GCMDestination;
import java.util.HashMap;
import static com.ganyo.pushtest.Util.*;
import static com.ganyo.pushtest.Settings.*;
public final class AppServices {
private static DataClient client;
private static Device device;
static synchronized DataClient getClient(Context context) {
if (client == null) {
if (ORG.equals("<<your org name here>>")) {
Log.e(TAG, "ORG value has not been set.");
} else {
ApigeeClient apigeeClient = new ApigeeClient(ORG,APP,API_URL,context);
client = apigeeClient.getDataClient();
}
}
return client;
}
static void loginAndRegisterForPush(final Context context) {
if ((USER != null) && (USER.length() > 0)) {
DataClient dataClient = getClient(context);
if (dataClient != null) {
dataClient.authorizeAppUserAsync(USER, PASSWORD, new ApiResponseCallback() {
#Override
public void onResponse(ApiResponse apiResponse) {
Log.i(TAG, "login response: " + apiResponse);
registerPush(context);
}
#Override
public void onException(Exception e) {
displayMessage(context, "Login Exception: " + e);
Log.i(TAG, "login exception: " + e);
}
});
} else {
Log.e(TAG,"Data client is null, did you set ORG value in Settings.java?");
}
} else {
registerPush(context);
}
}
static void registerPush(Context context) {
final String regId = GCMRegistrar.getRegistrationId(context);
if ("".equals(regId)) {
GCMRegistrar.register(context, Settings.GCM_SENDER_ID);
} else {
if (GCMRegistrar.isRegisteredOnServer(context)) {
Log.i(TAG, "Already registered with GCM");
} else {
AppServices.register(context, regId);
}
}
}
/**
* Register this user/device pair on App Services.
*/
static void register(final Context context, final String regId) {
Log.i(TAG, "registering device: " + regId);
DataClient dataClient = getClient(context);
if (dataClient != null) {
dataClient.registerDeviceForPushAsync(dataClient.getUniqueDeviceID(), NOTIFIER, regId, null, new DeviceRegistrationCallback() {
#Override
public void onResponse(Device device) {
Log.i(TAG, "register response: " + device);
AppServices.device = device;
displayMessage(context, "Device registered as: " + regId);
DataClient dataClient = getClient(context);
if (dataClient != null) {
// connect Device to current User - if there is one
if (dataClient.getLoggedInUser() != null) {
dataClient.connectEntitiesAsync("users", dataClient.getLoggedInUser().getUuid().toString(),
"devices", device.getUuid().toString(),
new ApiResponseCallback() {
#Override
public void onResponse(ApiResponse apiResponse) {
Log.i(TAG, "connect response: " + apiResponse);
}
#Override
public void onException(Exception e) {
displayMessage(context, "Connect Exception: " + e);
Log.i(TAG, "connect exception: " + e);
}
});
}
} else {
Log.e(TAG,"data client is null, did you set ORG value in Settings.java?");
}
}
#Override
public void onException(Exception e) {
displayMessage(context, "Register Exception: " + e);
Log.i(TAG, "register exception: " + e);
}
#Override
public void onDeviceRegistration(Device device) { /* this won't ever be called */ }
});
} else {
Log.e(TAG, "Data client is null, did you set ORG value in Settings.java?");
}
}
static void sendMyselfANotification(final Context context) {
if (device == null) {
displayMessage(context, "Device not registered. ORG value set in Settings.java?");
} else {
DataClient dataClient = getClient(context);
if (dataClient != null) {
GCMDestination destination = GCMDestination.destinationSingleDevice(device.getUuid());
GCMPayload payload = new GCMPayload();
payload.setAlertText("Hi there!");
dataClient.pushNotificationAsync(payload, destination, "google", new ApiResponseCallback() {
#Override
public void onResponse(ApiResponse apiResponse) {
Log.i(TAG, "send response: " + apiResponse);
}
#Override
public void onException(Exception e) {
displayMessage(context, "Send Exception: " + e);
Log.i(TAG, "send exception: " + e);
}
});
} else {
Log.e(TAG, "data client is null, did you set ORG value in Settings.java?");
}
}
}
/**
* Unregister this device within the server.
*/
static void unregister(final Context context, final String regId) {
Log.i(TAG, "unregistering device: " + regId);
register(context, "");
}
}
Gmcintentservices:
package com.ganyo.pushtest;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import com.google.android.gcm.GCMBaseIntentService;
import static com.ganyo.pushtest.Settings.GCM_SENDER_ID;
import static com.ganyo.pushtest.Util.displayMessage;
public class GCMIntentService extends GCMBaseIntentService {
public GCMIntentService() {
super(GCM_SENDER_ID);
}
/**
* Method called on device registered
**/
#Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: " + registrationId);
displayMessage(context, getString(R.string.gcm_registered, registrationId));
AppServices.register(context, registrationId);
}
/**
* Method called on device unregistered
* */
#Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
displayMessage(context, getString(R.string.gcm_unregistered, registrationId));
AppServices.unregister(context, registrationId);
}
/**
* Method called on receiving a new message
* */
#Override
protected void onMessage(Context context, Intent intent) {
String message = intent.getExtras().getString("data");
Log.i(TAG, "Received message: " + message);
displayMessage(context, message);
generateNotification(context, message);
}
/**
* Method called on receiving a deleted message
* */
#Override
protected void onDeletedMessages(Context context, int total) {
Log.i(TAG, "Received deleted messages notification");
String message = getString(R.string.gcm_deleted, total);
displayMessage(context, message);
generateNotification(context, message);
}
/**
* Method called on Error
* */
#Override
public void onError(Context context, String errorId) {
Log.i(TAG, "Received error: " + errorId);
displayMessage(context, getString(R.string.gcm_error, errorId));
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
Log.i(TAG, "Received recoverable error: " + errorId);
displayMessage(context, getString(R.string.gcm_recoverable_error, errorId));
return super.onRecoverableError(context, errorId);
}
/**
* Issues a Notification to inform the user that server has sent a message.
*/
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(context, PushMainActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(context)
.setContentText(message)
.setContentTitle(context.getString(R.string.app_name))
.setSmallIcon(icon)
.setWhen(when)
.setContentIntent(intent)
.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
}
Alertdialoguemanager:
package com.ganyo.pushtest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
public class AlertDialogManager {
public void showAlertDialog(Context context, String title, String message) {
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle(title);
alertDialog.setMessage(message);
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
}
}
Util:
package com.ganyo.pushtest;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.google.android.gcm.GCMRegistrar;
public final class Util {
static final String TAG = "com.ganyo.pushtest";
static final String DISPLAY_MESSAGE_ACTION = "com.ganyo.pushtest.DISPLAY_MESSAGE";
static final String EXTRA_MESSAGE = "message";
static void displayMessage(Context context, String message) {
Intent intent = new Intent(DISPLAY_MESSAGE_ACTION);
intent.putExtra(EXTRA_MESSAGE, message);
context.sendBroadcast(intent);
}
}
Wakelocker:
package com.ganyo.pushtest;
import android.content.Context;
import android.os.PowerManager;
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context context) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.ON_AFTER_RELEASE |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE |
PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeLock");
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
Here is the logcat area of the fatal exception:
05-01 00:26:52.757: D/AndroidRuntime(166): Shutting down VM
05-01 00:26:52.777: D/jdwp(166): adbd disconnected
05-01 00:26:52.817: I/AndroidRuntime(166): NOTE: attach of thread 'Binder Thread #3' failed
05-01 00:26:53.050: I/ActivityThread(258): Publishing provider com.svox.pico.providers.SettingsProvider: com.svox.pico.providers.SettingsProvider
05-01 00:26:53.627: I/ActivityManager(58): Start proc com.ganyo.pushtest for activity com.ganyo.pushtest/.PushMainActivity: pid=267 uid=10036 gids={3003}
05-01 00:26:54.687: W/WindowManager(58): No window to dispatch pointer action 0
05-01 00:26:54.707: W/WindowManager(58): No window to dispatch pointer action 1
05-01 00:26:55.467: D/AndroidRuntime(267): Shutting down VM
05-01 00:26:55.467: W/dalvikvm(267): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
05-01 00:26:55.537: E/AndroidRuntime(267): FATAL EXCEPTION: main
05-01 00:26:55.537: E/AndroidRuntime(267): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.ganyo.pushtest/com.ganyo.pushtest.PushMainActivity}: java.lang.ClassNotFoundException: com.ganyo.pushtest.PushMainActivity in loader dalvik.system.PathClassLoader[/data/app/com.ganyo.pushtest-2.apk]
05-01 00:26:55.537: E/AndroidRuntime(267): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
05-01 00:26:55.537: E/AndroidRuntime(267): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
05-01 00:26:55.537: E/AndroidRuntime(267): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
05-01 00:26:55.537: E/AndroidRuntime(267): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
05-01 00:26:55.537: E/AndroidRuntime(267): at android.os.Handler.dispatchMessage(Handler.java:99)
05-01 00:26:55.537: E/AndroidRuntime(267): at android.os.Looper.loop(Looper.java:123)
05-01 00:26:55.537: E/AndroidRuntime(267): at android.app.ActivityThread.main(ActivityThread.java:4627)
05-01 00:26:55.537: E/AndroidRuntime(267): at java.lang.reflect.Method.invokeNative(Native Method)
05-01 00:26:55.537: E/AndroidRuntime(267): at java.lang.reflect.Method.invoke(Method.java:521)
05-01 00:26:55.537: E/AndroidRuntime(267): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
05-01 00:26:55.537: E/AndroidRuntime(267): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
05-01 00:26:55.537: E/AndroidRuntime(267): at dalvik.system.NativeStart.main(Native Method)
05-01 00:26:55.537: E/AndroidRuntime(267): Caused by: java.lang.ClassNotFoundException: com.ganyo.pushtest.PushMainActivity in loader dalvik.system.PathClassLoader[/data/app/com.ganyo.pushtest-2.apk]
05-01 00:26:55.537: E/AndroidRuntime(267): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
05-01 00:26:55.537: E/AndroidRuntime(267): at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
05-01 00:26:55.537: E/AndroidRuntime(267): at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
05-01 00:26:55.537: E/AndroidRuntime(267): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
05-01 00:26:55.537: E/AndroidRuntime(267): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)
05-01 00:26:55.537: E/AndroidRuntime(267): ... 11 more
05-01 00:26:55.617: W/ActivityManager(58): Force finishing activity com.ganyo.pushtest/.PushMainActivity
05-01 00:26:56.499: W/ActivityManager(58): Activity pause timeout for HistoryRecord{460133f8 com.ganyo.pushtest/.PushMainActivity}
05-01 00:26:56.687: I/ARMAssembler(58): generated scanline__00000077:03515104_00000000_00000000 [ 33 ipp] (47 ins) at [0x3261a0:0x32625c] in 1336038 ns
05-01 00:26:56.777: I/ARMAssembler(58): generated scanline__00000177:03515104_00001001_00000000 [ 91 ipp] (114 ins) at [0x3265b8:0x326780] in 1506105 ns
05-01 00:26:57.337: I/ARMAssembler(58): generated scanline__00000077:03545404_00000004_00000000 [ 47 ipp] (67 ins) at [0x326788:0x326894] in 951792 ns
05-01 00:26:57.967: D/AndroidRuntime(271): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
05-01 00:26:58.009: D/AndroidRuntime(271): CheckJNI is ON
05-01 00:27:00.377: D/AndroidRuntime(271): --- registering native functions ---
Thanks for the help!
It turned out to be all the .java files in the java folder. Once I redid them in the src path, the program worked correctly.
Pretty new on this android stuff and gets a NullPointException that I can't seem to figure out. I am trying to implement an onResume() method in my CameraActivity and have moved almost all of the orginal code in onCreate() to onResume() and then call onResume() in onCreate(). The activity worked fine when the code was in onCreate(), but when placed in onResume() the exception arsises. What is causing it?
package com.example.tensioncamapp_project;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "PreviewAactivity";
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
this.mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
this.mHolder = getHolder();
this.mHolder.addCallback(this);
}
/**Displays the picture on the camera */
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
this.mCamera.setPreviewDisplay(holder);
this.mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
this.mCamera.release();
this.mCamera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
//add things here
}
}
and my CameraActivityClass
package com.example.tensioncamapp_project;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import android.content.Intent;
import android.app.Activity;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
public class CameraActivity extends Activity {
private ImageButton captureButton;
private Camera mCamera;
private CameraPreview mPreview;
private PictureCallback mPicture;
private ImageView imageView;
private static final int STD_DELAY = 400;
private static final int MEDIA_TYPE_IMAGE = 1;
protected static final String TAG = "CameraActivity";
/**Starts up the camera */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
onResume();
}
/**Connects the capture button on the view to a listener
* and redirects the client to a preview of the captures image*/
private void addListenerOnButton() {
this.captureButton = (ImageButton) findViewById(R.id.button_capture_symbol);
this.captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View capturebutton) {
mCamera.takePicture(null, null, mPicture);
delay();
Intent viewPic = new Intent(CameraActivity.this, ViewPicActivity.class);
startActivity(viewPic);
}
});
}
/** A safe way to get an instance of the Camera object. Code collected from elsewhere */
public static Camera getCameraInstance(){
Camera c = null;
try {
// attempt to get a Camera instance
c = Camera.open();
//getting current parameters
Camera.Parameters params = c.getParameters();
//setting new parameters with flash
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
c.setParameters(params);
}
catch (Exception e){
// camera is not available (in use or does not exist)
}
// returns null if camera is unavailable
return c;
}
/**Generates a delay needed for application to save new pictures */
private void delay(){
try {
//Makes the program inactive for a specific amout of time
Thread.sleep(STD_DELAY);
} catch (Exception e) {
e.getStackTrace();
}
}
/**Method for releasing the camera immediately on pause event*/
#Override
protected void onPause() {
super.onPause();
//Shuts down the preview shown on the screen
mCamera.stopPreview();
//Calls an internal help method to restore the camera
releaseCamera();
}
/**Help method to release the camera */
private void releaseCamera(){
//Checks if there is a camera object active
if (this.mCamera != null){
//Releases the camera
this.mCamera.release();
//Restore the camera object to its initial state
this.mCamera = null;
}
}
/**Activates the camera and makes it appear on the screen */
protected void onResume() {
// TODO Auto-generated method stub
// deleting image from external storage
FileHandler.deleteFromExternalStorage();
// Create an instance of Camera.
this.mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
this.mPreview = new CameraPreview(this, this.mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(this.mPreview);
//add the capture button
addListenerOnButton();
// In order to receive data in JPEG format
this.mPicture = new PictureCallback() {
/**Creates a file when a image is taken, if the file doesn't already exists*/
#Override
public void onPictureTaken(byte[] data, Camera mCamera) {
File pictureFile = FileHandler.getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions");
return;
}
try {
//Writes the image to the disc
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
super.onResume();
}
}
Log cat:
05-21 14:32:05.424: D/OpenGLRenderer(1030): Enabling debug mode 0
05-21 14:32:10.986: E/CameraActivity(1030): camera not availableFail to connect to camera service
05-21 14:32:11.033: I/Choreographer(1030): Skipped 66 frames! The application may be doing too much work on its main thread.
05-21 14:32:11.203: W/EGL_emulation(1030): eglSurfaceAttrib not implemented
05-21 14:32:13.013: D/AndroidRuntime(1030): Shutting down VM
05-21 14:32:13.013: W/dalvikvm(1030): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
05-21 14:32:13.083: E/AndroidRuntime(1030): FATAL EXCEPTION: main
05-21 14:32:13.083: E/AndroidRuntime(1030): java.lang.NullPointerException
05-21 14:32:13.083: E/AndroidRuntime(1030): at com.example.tensioncamapp_project.CameraPreview.surfaceCreated(CameraPreview.java:33)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.SurfaceView.updateWindow(SurfaceView.java:569)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.SurfaceView.access$000(SurfaceView.java:86)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:174)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:680)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1842)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.Choreographer.doCallbacks(Choreographer.java:562)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.Choreographer.doFrame(Choreographer.java:532)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.os.Handler.handleCallback(Handler.java:725)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.os.Handler.dispatchMessage(Handler.java:92)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.os.Looper.loop(Looper.java:137)
05-21 14:32:13.083: E/AndroidRuntime(1030): at android.app.ActivityThread.main(ActivityThread.java:5041)
05-21 14:32:13.083: E/AndroidRuntime(1030): at java.lang.reflect.Method.invokeNative(Native Method)
05-21 14:32:13.083: E/AndroidRuntime(1030): at java.lang.reflect.Method.invoke(Method.java:511)
05-21 14:32:13.083: E/AndroidRuntime(1030): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
05-21 14:32:13.083: E/AndroidRuntime(1030): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
05-21 14:32:13.083: E/AndroidRuntime(1030): at dalvik.system.NativeStart.main(Native Method)
The solution was to call the getCameraInstancemethod() in onResume() in an if-statement
protected void onResume() {
// TODO Auto-generated method stub
// deleting image from external storage
FileHandler.deleteFromExternalStorage();
// Create an instance of Camera.
if (this.mCamera == null){
this.mCamera = getCameraInstance();}
I think your problem is here
this.mPreview = new CameraPreview(this, this.mCamera);
this.mCamera seems to be null, it's not be set a new instance of the class, this needs to be done in the getCameraInstance() method.
getCameraInstance() returns null if an exception was thrown.
This cause the NPE as this.mCamera is null.
You should check if an exception was thrown in getCameraInstance and handle it correctly. The most basic thing is to log it and try to understand the reason.
I am trying to implement Stephen Wylie's Google Drive example (here). Here is my code:
package com.googledrive.googledriveapp;
// For Google Drive / Play Services
// Version 1.1 - Added new comments & removed dead code
// Stephen Wylie - 10/20/2012
import java.io.IOException;
import java.util.ArrayList;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.AccountPicker;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.android2.AndroidHttp;
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.json.JsonHttpRequest;
import com.google.api.client.http.json.JsonHttpRequestInitializer;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Apps.List;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.DriveRequest;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
public class MainActivity extends Activity {
private static final int CHOOSE_ACCOUNT=0;
private static String accountName;
private static int REQUEST_TOKEN=0;
private Button btn_drive;
private Context ctx = this;
private Activity a = this;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set up the GUI layout
setContentView(R.layout.activity_main);
// set the variables to access the GUI controls
btn_drive = (Button) findViewById(R.id.btn_drive);
btn_drive.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
chooseAccount();
}
});
}
public void chooseAccount() {
Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"}, false, null, null, null, null);
startActivityForResult(intent, CHOOSE_ACCOUNT);
}
// Fetch the access token asynchronously.
void getAndUseAuthTokenInAsyncTask(Account account) {
AsyncTask<Account, String, String> task = new AsyncTask<Account, String, String>() {
ProgressDialog progressDlg;
AsyncTask<Account, String, String> me = this;
#Override
protected void onPreExecute() {
progressDlg = new ProgressDialog(ctx, ProgressDialog.STYLE_SPINNER);
progressDlg.setMax(100);
progressDlg.setTitle("Validating...");
progressDlg.setMessage("Verifying the login data you entered...\n\nThis action will time out after 10 seconds.");
progressDlg.setCancelable(false);
progressDlg.setIndeterminate(false);
progressDlg.setOnCancelListener(new android.content.DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface d) {
progressDlg.dismiss();
me.cancel(true);
}
});
progressDlg.show();
}
#Override
protected String doInBackground(Account... params) {
return getAccessToken(params[0]);
}
#Override
protected void onPostExecute(String s) {
if (s == null) {
// Wait for the extra intent
} else {
accountName = s;
getDriveFiles();
}
progressDlg.dismiss();
}
};
task.execute(account);
}
/**
* Fetches the token from a particular Google account chosen by the user. DO NOT RUN THIS DIRECTLY. It must be run asynchronously inside an AsyncTask.
* #param activity
* #param account
* #return
*/
private String getAccessToken(Account account) {
try {
return GoogleAuthUtil.getToken(ctx, account.name, "oauth2:" + DriveScopes.DRIVE_READONLY); // IMPORTANT: DriveScopes must be changed depending on what level of access you want
} catch (UserRecoverableAuthException e) {
// Start the Approval Screen intent, if not run from an Activity, add the Intent.FLAG_ACTIVITY_NEW_TASK flag.
a.startActivityForResult(e.getIntent(), REQUEST_TOKEN);
e.printStackTrace();
return null;
} catch (GoogleAuthException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private Drive getDriveService() {
HttpTransport ht = AndroidHttp.newCompatibleTransport(); // Makes a transport compatible with both Android 2.2- and 2.3+
JacksonFactory jf = new JacksonFactory(); // You need a JSON parser to help you out with the API response
Credential credential = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(accountName);
HttpRequestFactory rf = ht.createRequestFactory(credential);
Drive.Builder b = new Drive.Builder(ht, jf, null);
b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
#Override
public void initialize(JsonHttpRequest request) throws IOException {
DriveRequest driveRequest = (DriveRequest) request;
driveRequest.setPrettyPrint(true);
driveRequest.setOauthToken(accountName);
}
});
return b.build();
}
/**
* Obtains a list of all files on the signed-in user's Google Drive account.
*/
private void getDriveFiles() {
Drive service = getDriveService();
Log.d("SiteTrack", "FUNCTION getDriveFiles()");
Files.List request;
try {
request = service.files().list(); // .setQ("mimeType=\"text/plain\"");
} catch (IOException e) {
e.printStackTrace();
return;
}
do {
FileList files;
try {
Log.d("SiteTrack", request.toString());
files = request.execute();
} catch (IOException e) {
e.printStackTrace();
Log.d("SiteTrack", "Exception");
return;
}
ArrayList<File> fileList = (ArrayList<File>) files.getItems();
Log.d("SiteTrack", "Files found: " + files.getItems().size());
for (File f : fileList) {
String fileId = f.getId();
String title = f.getTitle();
Log.d("SiteTrack", "File " + fileId + ": " + title);
}
request.setPageToken(files.getNextPageToken());
} while (request.getPageToken() != null && request.getPageToken().length() >= 0);
}
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
if (requestCode == CHOOSE_ACCOUNT && resultCode == RESULT_OK) {
accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
GoogleAccountManager gam = new GoogleAccountManager(this);
getAndUseAuthTokenInAsyncTask(gam.getAccountByName(accountName));
Log.d("SiteTrack", "CHOOSE_ACCOUNT");
} else if (requestCode == REQUEST_TOKEN && resultCode == RESULT_OK) {
accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
Log.d("SiteTrack", "REQUEST_TOKEN");
}
}
}
Here is my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.googledrive.googledriveapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="android.app.ActivityGroup" />
</activity>
</application>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Here is my activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btn_drive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Connect to Google Drive" />
</LinearLayout>
And here is the LogCat error I receive. It occurs when the button is pressed:
10-28 00:25:28.637: E/AndroidRuntime(842): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.google.android.gms.common.account.CHOOSE_ACCOUNT (has extras) }
10-28 00:25:28.637: E/AndroidRuntime(842): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1512)
10-28 00:25:28.637: E/AndroidRuntime(842): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1384)
10-28 00:25:28.637: E/AndroidRuntime(842): at android.app.Activity.startActivityForResult(Activity.java:3190)
10-28 00:25:28.637: E/AndroidRuntime(842): at com.googledrive.googledriveapp.MainActivity.chooseAccount(MainActivity.java:67)
10-28 00:25:28.637: E/AndroidRuntime(842): at com.googledrive.googledriveapp.MainActivity$1.onClick(MainActivity.java:60)
10-28 00:25:28.637: E/AndroidRuntime(842): at android.view.View.performClick(View.java:3511)
10-28 00:25:28.637: E/AndroidRuntime(842): at android.view.View$PerformClick.run(View.java:14105)
10-28 00:25:28.637: E/AndroidRuntime(842): at android.os.Handler.handleCallback(Handler.java:605)
10-28 00:25:28.637: E/AndroidRuntime(842): at android.os.Handler.dispatchMessage(Handler.java:92)
10-28 00:25:28.637: E/AndroidRuntime(842): at android.os.Looper.loop(Looper.java:137)
10-28 00:25:28.637: E/AndroidRuntime(842): at android.app.ActivityThread.main(ActivityThread.java:4424)
10-28 00:25:28.637: E/AndroidRuntime(842): at java.lang.reflect.Method.invokeNative(Native Method)
10-28 00:25:28.637: E/AndroidRuntime(842): at java.lang.reflect.Method.invoke(Method.java:511)
10-28 00:25:28.637: E/AndroidRuntime(842): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-28 00:25:28.637: E/AndroidRuntime(842): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-28 00:25:28.637: E/AndroidRuntime(842): at dalvik.system.NativeStart.main(Native Method)
Can anyone help out?
We've been doing some experimenting, and our current theory is that the new Google OAuth Library depends on having the latest version of Google Play.
We found that if your device still has the Android Marketplace, or an older Google Play we couldn't get OAuth to work.
So you might try opening the Android Marketplace or Google Play App to kick off an upgrade.
Open the Android Marketplace, Accept the Upgrade to Google Play.
Close the Marketplace, and open the Google Play App.
Accept the Terms of Service for Google Play.
Wait a few seconds, sacrifice a chicken, and then you should be able to run Google OAuth.
EDIT: Looks like Google Provides some guidance on what your app should do if your users are missing the correct Google Play version. See: https://developer.android.com/google/play-services/setup.html#ensure
Google Drive API seems (acording to the Google people) to only works on a real Device, in the Emulator it will crash with this error.
So my Advice, try on a real device.