Neither handleIntent nor onCreate being called in Searchable Activity - java

I know there are many questions like this on here, and I have looked at many of them, like this one and all of the questions it references, but I still have no solution. The problem is that I have followed the Android Developer guide on using the search widget, but when I open my app and hit the search widget, the onNewIntent method never gets called. I put a Log.e into the handleIntent method so I could check if everything was connecting before I moved on to the next part of the function, but it never gets called. I thought the issue might be in the MainActivity in the onCreateOptionsMenu, if maybe I'm not calling something right there. This is my first time trying to do this, and I'd really appreciate any kind of help on this issue, thanks.
Here is my SearchableActivity:
package com.gmd.referenceapplication;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
public class SearchableActivity extends ListActivity {
DatabaseTable db= new DatabaseTable(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_searchable);
// get the intent sent when user searches from search widget, verify the action and extract what is typed in
Intent intent = getIntent();
handleIntent(intent);
}
public void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
Cursor c = db.getWordMatches(query, null);
Log.e("Search Operation", "Database searched");
System.out.println(R.string.app_name);
//still need to process Cursor and display results
}
}
public void onListItemClick(ListView l,
View v, int position, long id) {
// call detail activity for clicked entry
}
private void doSearch(String queryStr) {
// get a Cursor, prepare the ListAdapter
// and set it
}
}
Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
package="com.gmd.referenceapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/nist_logo"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<meta-data
android:name="android.app.default_searchable"
android:value="com.example.SearchActivity" />
<!-- main activity below, will be a home screen -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- //the physical constants overview page, will hopefully split into smaller categories -->
<activity
android:name=".FundamentalPhysicalConstants"
android:label="#string/app_name" />
<!-- searchable activity, performs searches and presents results -->
<activity android:name=".SearchableActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
<provider
android:name=".ConstantSuggestionProvider"
android:authorities="query"
android:enabled="true"
android:exported="true" />
<activity android:name=".ExampleListView" />
<activity android:name=".CommonConstants" />
<activity android:name=".ElectromagneticConstants" />
<activity android:name=".AtomicNuclearConstants" />
<activity android:name=".PhysicoChemicalConstants" />
<activity android:name=".ReferenceLinks" />
<activity android:name=".SIBaseUnits"/>
</application>
</manifest>
Searchable xml:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint">
</searchable>
Database Table:
package com.gmd.referenceapplication;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.text.TextUtils;
import android.util.Log;
import com.gmd.referenceapplication.R;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* Created by gmd on 6/8/2016.
*/
public class DatabaseTable {
public static final String TAG = "ConstantDatabase";
//the columns included in the table
public static final String COL_QUANTITY = "QUANTIY";
public static final String COL_VALUE = "VALUE";
public static final String COL_UNCERTAINTY = "UNCERTAINTY";
public static final String COL_UNIT = "UNIT";
private static final String DATABASE_NAME = "CONSTANTS";
private static final String FTS_VIRTUAL_TABLE = "FTS";
private static final int DATABASE_VERSION = 1;
private final DatabaseOpenHelper mDatabaseOpenHelper;
public DatabaseTable(Context context){
mDatabaseOpenHelper = new DatabaseOpenHelper(context);
}
private static class DatabaseOpenHelper extends SQLiteOpenHelper {
private final Context mHelperContext;
private SQLiteDatabase mDatabase;
private static final String FTS_TABLE_CREATE =
"CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE +
" USING fts3 (" +
COL_QUANTITY + ", " +
COL_VALUE + "," +
COL_UNCERTAINTY + "," +
COL_UNIT + ")";
public DatabaseOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.e("Database Operation", "Database Created / Opened...");
mHelperContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
mDatabase = db;
mDatabase.execSQL(FTS_TABLE_CREATE);
Log.e("Database Operation", "Constants Table Created ...");
loadConstants();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + FTS_VIRTUAL_TABLE);
onCreate(db);
}
// populating the virtual table with a string reading code
private void loadConstants() {
new Thread(new Runnable() {
public void run() {
try {
loadConstantss();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
Log.e("Loading", "Constants Table Populated ...");
}
private void loadConstantss() throws IOException {
final Resources resources = mHelperContext.getResources();
InputStream inputStream = resources.openRawResource(R.raw.txt);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] strings = TextUtils.split(line, ",");
if (strings.length < 4) continue;
long id = addConstant(strings[0].trim(), strings[1].trim(), strings[2].trim(), strings[3].trim());
if (id < 0) {
Log.e(TAG, "unable to add word: " + strings[0].trim());
}
}
} finally {
reader.close();
}
}
public long addConstant(String quantity, String value, String uncertainty, String unit) {
ContentValues initialValues = new ContentValues();
initialValues.put(COL_QUANTITY, quantity);
initialValues.put(COL_VALUE, value);
initialValues.put(COL_UNCERTAINTY, uncertainty);
initialValues.put(COL_UNIT, unit);
return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
}
}
public Cursor getWordMatches(String query, String[] columns) {
String selection = COL_QUANTITY + " MATCH ?";
String[] selectionArgs = new String[] {query+"*"};
return query(selection, selectionArgs, columns);
}
public Cursor query(String selection, String[] selectionArgs, String[] columns) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(FTS_VIRTUAL_TABLE);
Cursor cursor = builder.query(mDatabaseOpenHelper.getReadableDatabase(),
columns, selection, selectionArgs, null, null, null);
if (cursor == null) {
return null;
} else if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
return cursor;
}
}
MainActivity:
package com.gmd.referenceapplication;
import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.Context;
import android.content.Intent;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.support.v7.widget.SearchView;
public class MainActivity extends AppCompatActivity {
DatabaseTable dbHelper = new DatabaseTable(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.overflow, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
//search button is pressed
dbHelper.getWordMatches(query,null);
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
// User changed the text
return true;
}
});
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.constants:
startActivity(new Intent(MainActivity.this, FundamentalPhysicalConstants.class));
return true;
case R.id.joes_rules:
//go to rules
//startActivity(new Intent(MainActivity.this, ExampleListView.class));
return true;
case R.id.home:
//Go back to the home screen
return true;
case R.id.search:
//open search
return true;
case R.id.links:
//go to referencelinks
startActivity(new Intent(this, ReferenceLinks.class));
return true;
case R.id.base_units:
//go to baseunits
startActivity(new Intent(this, SIBaseUnits.class));
return true;
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
}

Related

Pass a new activity as main activity to render first

This is ClassifierActivity.java file which is rendering by default:
package org.tensorflow.lite.examples.classification;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Typeface;
import android.media.ImageReader.OnImageAvailableListener;
import android.os.SystemClock;
import android.util.Size;
import android.util.TypedValue;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import org.tensorflow.lite.examples.classification.env.BorderedText;
import org.tensorflow.lite.examples.classification.env.Logger;
import org.tensorflow.lite.examples.classification.tflite.Classifier;
import org.tensorflow.lite.examples.classification.tflite.Classifier.Device;
import org.tensorflow.lite.examples.classification.tflite.Classifier.Model;
public class ClassifierActivity extends CameraActivity implements OnImageAvailableListener {
private static final Logger LOGGER = new Logger();
private static final Size DESIRED_PREVIEW_SIZE = new Size(640, 480);
private static final float TEXT_SIZE_DIP = 10;
private Bitmap rgbFrameBitmap = null;
private long lastProcessingTimeMs;
private Integer sensorOrientation;
public Classifier classifier;
private BorderedText borderedText;
/** Input image size of the model along x axis. */
private int imageSizeX;
/** Input image size of the model along y axis. */
private int imageSizeY;
#Override
protected int getLayoutId() {
return R.layout.camera_connection_fragment;
}
#Override
protected Size getDesiredPreviewFrameSize() {
return DESIRED_PREVIEW_SIZE;
}
#Override
public void onPreviewSizeChosen(final Size size, final int rotation) {
final float textSizePx =
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());
borderedText = new BorderedText(textSizePx);
borderedText.setTypeface(Typeface.MONOSPACE);
recreateClassifier(getModel(), getDevice(), getNumThreads());
if (classifier == null) {
LOGGER.e("No classifier on preview!");
return;
}
previewWidth = size.getWidth();
previewHeight = size.getHeight();
sensorOrientation = rotation - getScreenOrientation();
LOGGER.i("Camera orientation relative to screen canvas: %d", sensorOrientation);
LOGGER.i("Initializing at size %dx%d", previewWidth, previewHeight);
rgbFrameBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
}
#Override
protected void processImage() {
rgbFrameBitmap.setPixels(getRgbBytes(), 0, previewWidth, 0, 0, previewWidth, previewHeight);
final int cropSize = Math.min(previewWidth, previewHeight);
runInBackground(
new Runnable() {
#Override
public void run() {
if (classifier != null) {
final long startTime = SystemClock.uptimeMillis();
final List<Classifier.Recognition> results =
classifier.recognizeImage(rgbFrameBitmap, sensorOrientation);
lastProcessingTimeMs = SystemClock.uptimeMillis() - startTime;
LOGGER.v("Detect: %s", results);
runOnUiThread(
new Runnable() {
#Override
public void run() {
showResultsInBottomSheet(results);
showFrameInfo(previewWidth + "x" + previewHeight);
showCropInfo(imageSizeX + "x" + imageSizeY);
showCameraResolution(cropSize + "x" + cropSize);
showRotationInfo(String.valueOf(sensorOrientation));
showInference(lastProcessingTimeMs + "ms");
}
});
}
readyForNextImage();
}
});
}
#Override
protected void onInferenceConfigurationChanged() {
if (rgbFrameBitmap == null) {
// Defer creation until we're getting camera frames.
return;
}
final Device device = getDevice();
final Model model = getModel();
final int numThreads = getNumThreads();
runInBackground(() -> recreateClassifier(model, device, numThreads));
}
private void recreateClassifier(Model model, Device device, int numThreads) {
if (classifier != null) {
LOGGER.d("Closing classifier.");
classifier.close();
classifier = null;
}
if (device == Device.GPU && model == Model.QUANTIZED) {
LOGGER.d("Not creating classifier: GPU doesn't support quantized models.");
runOnUiThread(
() -> {
Toast.makeText(this, "GPU does not yet supported quantized models.", Toast.LENGTH_LONG)
.show();
});
return;
}
try {
LOGGER.d(
"Creating classifier (model=%s, device=%s, numThreads=%d)", model, device, numThreads);
classifier = Classifier.create(this, model, device, numThreads);
} catch (IOException e) {
LOGGER.e(e, "Failed to create classifier.");
}
// Updates the input image size.
imageSizeX = classifier.getImageSizeX();
imageSizeY = classifier.getImageSizeY();
}
}
I created a new activity named Main.java and I want this activity to render first and pass it ClassifierActivity.java as intent by click on button:
package org.tensorflow.lite.examples.classification;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.VideoView;
public class Main extends AppCompatActivity {
VideoView videoView;
private Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// hide title bar
getSupportActionBar().hide();
// set button on click to scan where open the camera
btn=(Button)findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openActivity();
}
});
videoView = findViewById(R.id.videoview);
Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.turkey);
videoView.setVideoURI(uri);
videoView.start();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
}
protected void openActivity(){
Intent i = new Intent(this, ClassifierActivity.class);
startActivity(i);
}
#Override
protected void onPostResume() {
videoView.resume();
super.onPostResume();
}
#Override
protected void onRestart() {
videoView.start();
super.onRestart();
}
#Override
protected void onPause() {
videoView.suspend();
super.onPause();
}
#Override
protected void onDestroy() {
videoView.stopPlayback();
super.onDestroy();
}
}
This is old AndroidManifest.xml (app running successfully)
<activity
android:name=".ClassifierActivity"
android:label="#string/activity_name_classification"
android:screenOrientation="portrait"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
And I want to run Main first. So, I changed android:name=".ClassifierActivity" from old AndroidManifest.xml to android:name=".Main" (app is stop running):
<activity
android:name=".Main"
android:label="#string/activity_name_classification"
android:screenOrientation="portrait"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
All activities need to be defined in the manifest.
You are replacing the original Activity with the new one and now the old one is not defined. So you just need to add it back.
<application
...
/>
<activity
android:name=".ClassifierActivity"
android:label="#string/activity_name_classification"
android:screenOrientation="portrait"
android:exported="true" >
</activity>
<activity
android:name=".Main"
android:label="#string/activity_name_classification"
android:screenOrientation="portrait"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

Detecting incoming call and opening a service in background on top of the dialer app

After detecting the incoming call, I am opening a messenger like chat icon on incoming call. But I am facing two issues :
1.The incoming call is not detected when my application is closed (not running even in background).
2.When my phone is locked, the chat icon does not appear. The chat icon hides behind the dialer app on an incoming call.
I am using Broadcast Receiver to receive the incoming call using PhoneCallReceiver class which calls methods defined under CallReceiver class and on detecting incoming call I am starting the service ChatHeadService which opens a chat like icon. I have attached screenshot of how the chat icon appears. I have been facing this problem since past 6 months and was not able to solve it. Any help would be appreciated.
compileSdkVersion 23
buildToolsVersion '27.0.3'
targetSdkVersion 23
I tested the app on two devices with API level 18 and API level 26. In API level 18, my app worked fine and both of the above issues were fixed. But in API level 26, my app worked didn't work and the chat icon was hidden behind the dialer app.
I am facing the following error on incoming call in Oreo API 26.
06-13 16:22:23.969 1238-4375/? W/BroadcastQueue: Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x1000010 (has extras) } to com.skype.m2/com.skype.nativephone.connector.NativePhoneCallReceiver requires android.permission.READ_PHONE_STATE due to sender android (uid 1000)
API level 26
API level 18
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.tarun.notifyme2">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.Settings.ACTION_MANAGE_OVERLAY_PERMISSION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission
android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
<application
android:allowBackup="true"
android:enabled="true"
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".SignUp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SendNoti" />
<receiver android:name=".CallReceiver"
android:enabled="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<service
android:name=".ChatHeadService"
android:exported="true"
android:enabled="true"/>
<service android:name=".FirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".FirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:theme="#style/AppTheme.NoActionBar" />
<activity android:name=".MainChat" />
<activity android:name=".ChatRoom" />
<activity android:name=".Feedback" />
</application>
</manifest>
PhonecallReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import java.util.Date;
public abstract class PhonecallReceiver extends BroadcastReceiver
{
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber;
#Override
public void onReceive(Context context, Intent intent)
{
try
{
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL"))
{
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
}
else
{
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE))
{
state = TelephonyManager.CALL_STATE_IDLE;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
{
state = TelephonyManager.CALL_STATE_OFFHOOK;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING))
{
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, state, number);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
//Derived classes should override these to respond to specific events of interest
protected void onIncomingCallStarted(Context ctx, String number, Date start){}
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end){}
public void onCallStateChanged(Context context, int state, String number)
{
if(lastState == state)
{
//No change, debounce extras
return;
}
switch (state)
{
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallStarted(context, number, callStartTime);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if (isIncoming)
{
onIncomingCallEnded(context,savedNumber,callStartTime,new Date());
}
case TelephonyManager.CALL_STATE_IDLE:
if(isIncoming)
{
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
}
}
lastState = state;
}
}
CallReceiver.java
import android.app.Activity;
import android.app.Dialog;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;
import android.os.Handler;
import java.util.Date;
public class CallReceiver extends PhonecallReceiver
{
Context context;
#Override
protected void onIncomingCallStarted(final Context ctx, String number, Date start)
{
Toast.makeText(ctx,"New Incoming Call"+ number,Toast.LENGTH_LONG).show();
context = ctx;
final Intent intent = new Intent(context, ChatHeadService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("phone_no",number);
SharedPreferences.Editor editor = ctx.getSharedPreferences("Notify", Context.MODE_PRIVATE).edit();
editor.putString("incomingNo",number);
editor.commit();
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
//start service which opens a chat icon after 2 seconds wait
context.startService(intent);
}
},2000);
}
#Override
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end)
{
final Intent intent = new Intent(context, ChatHeadService.class);
ctx.stopService(intent);
Toast.makeText(ctx,"Bye Bye"+ number,Toast.LENGTH_LONG).show();
}
}
ChatHeadService.java
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;
public class ChatHeadService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
WindowManager.LayoutParams params;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int res = super.onStartCommand(intent, flags, startId);
return res;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.bell2);
chatHead.setClickable(true);
params= new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 400;
windowManager.addView(chatHead, params);
chatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(ChatHeadService.this, SendNoti.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
stopSelf();
}
});
//this code is for dragging the chat head
chatHead.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
int flag=0;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
if(flag==3){
flag=1;
return true;
}else{
flag=1;
return false;
}
case MotionEvent.ACTION_UP:
if(flag==3){
flag=2;
return true;
}else{
flag=2;
return false;
}
case MotionEvent.ACTION_MOVE:
flag=3;
params.x = initialX
+ (int) (event.getRawX() - initialTouchX);
params.y = initialY
+ (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, params);
return true;
default:
Toast.makeText(getApplicationContext(),"You ckiced the imageview",Toast.LENGTH_LONG).show();
Log.i("tag","You clicked the imageview");
/*
Intent i = new Intent(view.getContext(),SendNoti.class);
startActivity(i);
stopSelf();*/
return true;
}
}
});
/*
Snackbar.make(chatHead, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();*/
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null)
windowManager.removeView(chatHead);
stopSelf();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Some time ago I found this example. I've added only that, call is incoming or outgoing. Pass your data to the service by intent and use it to perform service. Should work in api 23. In newest versions I can't ensure that.
public class CallReceiver extends BroadcastReceiver {
private final static String TAG = "CallReceiver";
private static PhoneCallStartEndDetector listener;
private String outgoingSavedNumber;
protected Context savedContext;
#Override
public void onReceive(Context context, Intent intent) {
this.savedContext = context;
if (listener == null) {
listener = new PhoneCallStartEndDetector();
}
String phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (phoneState == null) {
listener.setOutgoingNumber(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
} else if (phoneState.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
listener.setOutgoingNumber(intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER));
}
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
//Deals with actual events
private class PhoneCallStartEndDetector extends PhoneStateListener {
int lastState = TelephonyManager.CALL_STATE_IDLE;
boolean isIncoming;
boolean isOutgoing;
String savedNumber; //because the passed incoming is only valid in ringing
private PhoneCallStartEndDetector() {
}
//The outgoing number is only sent via a separate intent, so we need to store it out of band
private void setOutgoingNumber(String number) {
savedNumber = number;
}
Intent serviceIntent = new Intent(savedContext, YourService.class);
//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
if (lastState == state) {
//No change, debounce extras
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
savedNumber = incomingNumber;
serviceIntent.putExtra("label", value);
savedContext.startService(serviceIntent);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//Transition of ringing->offhook are pickups of incoming calls. Nothing donw on them
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
if (!isOutgoing) {
isOutgoing = true;
}
if (!savedNumber.equals("")) {
serviceIntent.putExtra("label", value);
savedContext.startService(serviceIntent);
}
}
break;
case TelephonyManager.CALL_STATE_IDLE:
//Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
//Ring but no pickup- a miss
savedContext.stopService(serviceIntent);
} else if (isIncoming) {
savedContext.stopService(serviceIntent);
} else {
if (isOutgoing) {
savedContext.stopService(serviceIntent);
isOutgoing = false;
}
}
break;
}
lastState = state;
}
}
}
Register this receiver in manifest, this should work in api 25:
<receiver
android:name=".calls.CallReceiver"
android:enabled="true">
<intent-filter android:priority="-1">
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
Or register BroadcastReceiver in code, this should work in api 26:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.PHONE_STATE");
CallReceiver receiver = new CallReceiver();
registerReceiver(receiver, intentFilter);
Of course, to use this code, you need grant permission. In manifest for api level less then 23:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
And for api 23 and newest, ask user about permission:
Manifest.permission.READ_PHONE_STATE
Call this method after call end
private void alert(Context ctx) {
StringBuffer sb = new StringBuffer();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Cursor cur = getContentResolver().query(CallLog.Calls.CONTENT_URI,
null, null, null, CallLog.Calls.DATE + " DESC limit 1;");
//Cursor cur = getContentResolver().query( CallLog.Calls.CONTENT_URI,null, null,null, android.provider.CallLog.Calls.DATE + " DESC");
int number = cur.getColumnIndex( CallLog.Calls.NUMBER );
int duration = cur.getColumnIndex( CallLog.Calls.DURATION);
int type = cur.getColumnIndex(CallLog.Calls.TYPE);
int date = cur.getColumnIndex(CallLog.Calls.DATE);
sb.append( "Call Details : \n");
phNumber = null;
callDuration = null;
callType = null;
callDate = null;
String dir = null;
String callDayTime = null;
while ( cur.moveToNext() ) {
phNumber = cur.getString( number );
callDuration = cur.getString( duration );
callType = cur.getString( type );
callDate = cur.getString( date );
callDayTime = new Date(Long.valueOf(callDate)).toString();
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
// sb.append( "\nPhone Number:--- "+phNumber +" \nCall duration in sec :--- "+callDuration );
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
Log.e("dir",dir);
}
cur.close();
callType=dir;
callDate=callDayTime;
Log.e("call ",phNumber+" duration"+callDuration+" type "+callType+" date "+callDate);
startactivity(ctx);
}
it will give you last call detail's

SQLite Database issue in TextView

I've been working on an app where the main Activity leads to CalendarActivity, which has a button leading to another Activity where the user creates an event. Once the event is created, the user is taken back to CalendarActivity, and a previously empty TextView displays the event. The code I've used seems like it should work, and is near verbatim from an online tutorial. I researched the comments of the video and the video maker's blog, and many others seem to say it works fine. I've check over and over, and I believe that its grammatically correct, etc, but I can not get it to load the event into the TextView. Any pointers even would help. I would ask you keep it near basic english, I am just getting into programming and am using this app as a learning experience.
Thanks!
CalendarActivity:
package com.bm.sn.sbeta;
import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
public class CalendarActivity extends AppCompatActivity {
CalendarView calendar;
Button createEvent;
public static String createEventDate;
DatabaseHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
Cursor result = db.getAllData();
if (result.getCount() == 0) {
noEventToday();
}else{
TextView eventList = (TextView)findViewById(R.id.eventList);
StringBuffer stringBuffer = new StringBuffer();
while (result.moveToNext()) {
stringBuffer.append("eventDat : "+result.getString(0)+"\n");
stringBuffer.append("timeHour : "+result.getString(1)+"\n");
stringBuffer.append("timeMinue : "+result.getString(2)+"\n");
stringBuffer.append("event : "+result.getString(3)+"\n");
stringBuffer.append("location : "+result.getString(4)+"\n");
stringBuffer.append("crew : "+result.getString(5)+"\n\n");
eventList.setText(stringBuffer);
}
}
calendar = (CalendarView)findViewById(R.id.calendar);
calendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener(){
#Override
public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth){
createEventDate = (month+"."+dayOfMonth+"."+year);
createEvent.setText("Create Event for "+createEventDate);
}
});
createEvent = (Button)findViewById(R.id.eventCreateButton);
createEvent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent toEventCreateActivity = new Intent(CalendarActivity.this, EventCreateActivity.class);
startActivity(toEventCreateActivity);
}
});
}
/*public void fillEventList (){
}
public void noEventToday(){
TextView eventList = (TextView)findViewById(R.id.eventList);
eventList.setText("Nothing scheduled for today.");
}*/
}
EventCreateActivity:
package com.bm.sn.sbeta;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
public class EventCreateActivity extends AppCompatActivity {
DatabaseHelper db;
String textViewText = CalendarActivity.createEventDate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_create);
db = new DatabaseHelper(this);
final TextView titleTextView = (TextView)findViewById(R.id.titleTextView);
titleTextView.setText("Create event for "+textViewText);
final TimePicker timePicker = (TimePicker)findViewById(R.id.timePicker);
final EditText entryEvent = (EditText)findViewById(R.id.entryEvent);
final EditText entryLocation = (EditText)findViewById(R.id.entryLocation);
final EditText entryCrew = (EditText)findViewById(R.id.entryCrew);
Button createEventButton = (Button)findViewById(R.id.saveEvent);
createEventButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db.insertData(
titleTextView.toString(),
timePicker.getCurrentHour().toString(),
timePicker.getCurrentMinute().toString(),
entryEvent.getText().toString(),
entryLocation.getText().toString(),
entryCrew.getText().toString()
);
Toast.makeText(EventCreateActivity.this, "I'll keep that in mind.", Toast.LENGTH_LONG).show();
Intent toCalendarActivity = new Intent(EventCreateActivity.this, CalendarActivity.class);
startActivity(toCalendarActivity);
}
});
}
}
DatabaseHelper:
package com.bm.sn.sbeta;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "SavitaCalendar.db";
public static final String TABLE_NAME = "CalendarEvents";
public static final String col_0 = "ID";
public static final String col_1 = "eventDate" ;
public static final String col_2 = "timeHour";
public static final String col_3 = "timeMinute";
public static final String col_4 = "event";
public static final String col_5 = "location";
public static final String col_6 = "crew";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table "+TABLE_NAME+ " (ID INTEGER PRIMARY KEY AUTOINCREMENT,EVENTDATE TEXT,TIMEHOUR TEXT,TIMEMINUTE TEXT, EVENT TEXT, LOCATION TEXT, CREW TEXT); ");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public void insertData (String eventDate, String timeHour, String timeMinute, String event, String location, String crew){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(col_1, eventDate);
contentValues.put(col_2, timeHour);
contentValues.put(col_3, timeMinute);
contentValues.put(col_4, event);
contentValues.put(col_5, location);
contentValues.put(col_6, crew);
db.insert(TABLE_NAME, null, contentValues);
db.close();
}
public Cursor getAllData(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor result = db.rawQuery("select * from "+TABLE_NAME, null);
return result;
}
}
You're reading your data from the DB in onCreate().
onCreate() is called when the Activity is (re)created. It is not guaranteed that it will be called when you navigate back from EventCreateActivity.
Take a look at the docs on the Activity lifecycle.
As #nuccio pointed it out, you also seem to forgot to initialize your DatabaseHelper instance.
You should use a singleton pattern there, something like this:
private static DatabaseHelper instance;
private DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
public static DatabaseHelper getInstance(Context context) {
if (instance == null) {
instance = new DatabaseHelper(context.getApplicationContext());
}
return instance;
}
You could start EventCreateActivity using startActivityForResult(), and override onActivityResult() in CalendarActivity to update your TextView.
For example:
public class CalendarActivity extends AppCompatActivity {
private static final int REQUEST_CREATE_EVENT = 0;
CalendarView calendar;
Button createEvent;
public static String createEventDate;
TextView eventList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
eventList = (TextView) findViewById(R.id.eventList);
getEvents();
calendar = (CalendarView) findViewById(R.id.calendar);
calendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
#Override
public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth) {
createEventDate = (month + "." + dayOfMonth + "." + year);
createEvent.setText("Create Event for " + createEventDate);
}
});
createEvent = (Button) findViewById(R.id.eventCreateButton);
createEvent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent toEventCreateActivity = new Intent(CalendarActivity.this, EventCreateActivity.class);
startActivityForResult(toEventCreateActivity, REQUEST_CREATE_EVENT);
}
});
}
private void getEvents() {
// getting our DatabaseHelper instance
DatabaseHelper db = DatabaseHelper.getInstance(this);
Cursor result = db.getAllData();
if (result.getCount() == 0) {
noEventToday();
} else {
StringBuffer stringBuffer = new StringBuffer();
while (result.moveToNext()) {
stringBuffer.append("eventDat : " + result.getString(0) + "\n");
stringBuffer.append("timeHour : " + result.getString(1) + "\n");
stringBuffer.append("timeMinue : " + result.getString(2) + "\n");
stringBuffer.append("event : " + result.getString(3) + "\n");
stringBuffer.append("location : " + result.getString(4) + "\n");
stringBuffer.append("crew : " + result.getString(5) + "\n\n");
eventList.setText(stringBuffer);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK && requestCode == REQUEST_CREATE_EVENT) {
getEvents();
}
}
public void noEventToday(){
TextView eventList = (TextView)findViewById(R.id.eventList);
eventList.setText("Nothing scheduled for today.");
}
}
And in EventCreateActivity:
createEventButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db.insertData(
titleTextView.toString(),
timePicker.getCurrentHour().toString(),
timePicker.getCurrentMinute().toString(),
entryEvent.getText().toString(),
entryLocation.getText().toString(),
entryCrew.getText().toString()
);
Toast.makeText(EventCreateActivity.this, "I'll keep that in mind.", Toast.LENGTH_LONG).show();
setResult(RESULT_OK);
finish();
}
});
An even better approach would be to pass your new event data in the Intent, so you don't have to read the DB when going back to CalendarActivity.
Or at least return the new row ID, so only one record needs to be queried.
You didn't instantiate your db properly in CalendarActivity.
add this
db = new DatabaseHelper(this);
Here is where to add this to the class:
package com.mac.training.calendaractivitysqlhelperthing;
imports ...
public class CalendarActivity extends AppCompatActivity {
CalendarView calendar;
Button createEvent;
public static String createEventDate;
DatabaseHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
//ADD this line here
db = new DatabaseHelper(this);
Cursor result = db.getAllData();
if (result.getCount() == 0) {
//noEventToday();
}else{
//etc
That alone should work, but if not. Also update your Manifest as well with this:
activity android:name=".EventCreateActivity"
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mac.training.calendaractivitysqlhelperthing">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".CalendarActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".EventCreateActivity" />
</application>
</manifest>

No such table - error inserting values in SQLite Android [duplicate]

This question already has answers here:
When does SQLiteOpenHelper onCreate() / onUpgrade() run?
(15 answers)
Closed 8 years ago.
I want to develop an application in which i need to use SQLite database in Android. Below is the code shown which is implementing the database and all its operations my application requires with random data(just to implement the logic successfully first).
This code is written in DBHelperDisplay.java which is called through intent by MainActivity.java.
My DBHelperDisplay.java :
package course.examples.jumboquest;
import java.util.Random;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
//import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
//import android.content.Intent;
import android.os.CountDownTimer;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
public class DBHelperDisplay extends ActionBarActivity {
TextView tv;
DBHelper myDB;
RadioGroup radioChoices;
RadioButton rbtChoice;
Button btSubmit;
String choice1;
String choice2;
String choice3;
String choice4;
String strAns;
CustomTimer cdt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dbhelper_display);
cdt = new CustomTimer(20000, 1000);
cdt.start();
myDB = new DBHelper(this);
myDB.insertQuestion(1, "who is the team member whose name starts with s?", "Vinita", "Akanksha", "Swati", "Megha", "Swati");
myDB.insertQuestion(2, "who is the team member whose name starts with m?", "Vinita", "Akanksha", "Swati", "Megha", "Megha");
myDB.insertQuestion(3, "who is the team member whose name starts with a?", "Vinita", "Akanksha", "Swati", "Megha", "Akanksha");
myDB.insertQuestion(4, "who is the team member whose name starts with v?", "Vinita", "Akanksha", "Swati", "Megha", "Vinita");
myDB.insertQuestion(5, "who is the team member whose name ends with i?", "Vinita", "Akanksha", "Swati", "Megha", "Swati");
Cursor rs = myDB.getData();
String Question = rs.getString(rs.getColumnIndex(DBHelper.Col_Ques));
choice1 = rs.getString(rs.getColumnIndex(DBHelper.Col_Choice1));
choice2 = rs.getString(rs.getColumnIndex(DBHelper.Col_Choice2));
choice3 = rs.getString(rs.getColumnIndex(DBHelper.Col_Choice3));
choice4 = rs.getString(rs.getColumnIndex(DBHelper.Col_Choice4));
strAns = rs.getString(rs.getColumnIndex(DBHelper.Col_Ans));
tv = (TextView) findViewById(R.id.timertxt);
final TextView quest = (TextView) findViewById(R.id.quest);
quest.setText(Question);
//final TextView ans = (TextView) findViewById(R.id.ans);
Button btClear = (Button)findViewById(R.id.btClear);
btClear.setText("CLEAR");
addListenerRadioChoices() ;
btClear.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
//ans.setText("");
}
});
}
public void addListenerRadioChoices(){
radioChoices = (RadioGroup) findViewById(R.id.radioChoices);
((RadioButton) radioChoices.getChildAt(0)).setText(choice1);
((RadioButton) radioChoices.getChildAt(1)).setText(choice2);
((RadioButton) radioChoices.getChildAt(2)).setText(choice3);
((RadioButton) radioChoices.getChildAt(3)).setText(choice4);
btSubmit = (Button)findViewById(R.id.btSubmit);
btSubmit.setText("SUBMIT");
btSubmit.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
int selected = radioChoices.getCheckedRadioButtonId();
rbtChoice = (RadioButton) findViewById(selected);
String Ans = rbtChoice.getText().toString();
if(Ans.equalsIgnoreCase(strAns)){
cdt.cancel();
//ans.setText(" ANSWER");
}
/* else{
// ans.setText("WRONG ANSWER");
}*/
}
});
}
public class CustomTimer extends CountDownTimer{
//TextView ed;
public CustomTimer(long millisInFuture, long countDownInterval){
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished){
//current = millisUntilFinished/1000;
tv.setText("Time Left:" + millisUntilFinished/1000);
}
#Override
public void onFinish() {
tv.setText("Time Up - lost the game!");
}
}
public class DBHelper extends SQLiteOpenHelper {
public static final String Database_Name = "Questions.db";
public static final String Table_Name = "Comics";
public static final String Col_ID = "id";
public static final String Col_Ques = "question";
public static final String Col_Choice1 = "choice1";
public static final String Col_Choice2 = "choice2";
public static final String Col_Choice3 = "choice3";
public static final String Col_Choice4 = "choice4";
public static final String Col_Ans = "answer";
public DBHelper(Context context){
super(context, Database_Name, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db){
// TODO Auto-generated method stub
db.execSQL(
"CREATE TABLE Comics" +
"(id integer primary key, question text, choice1 text, choice2 text, choice3 text, choice4 text, answer text)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS Comics");
onCreate(db);
}
public boolean insertQuestion(int id, String question, String choice1, String choice2, String choice3, String choice4, String answer){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("id",id);
contentValues.put("question",question);
contentValues.put("choice1",choice1);
contentValues.put("choice2",choice2);
contentValues.put("choice3",choice3);
contentValues.put("choice4",choice4);
contentValues.put("answer",answer);
db.insert("Comics", null, contentValues);
db.close();
return true;
}
public Cursor getData(){
SQLiteDatabase db = this.getReadableDatabase();
int numRows = (int)DatabaseUtils.queryNumEntries(db,Table_Name);
int min = 1;
int max = numRows;
Random r = new Random();
int id = r.nextInt(max - min + 1) + min;
Cursor res= db.rawQuery("Select * from Comics where id = " + id + "", null);
return res;
}
}
}
My AndroidManifest.xml file :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.examples.jumboquest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/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>
<activity android:name=".DBHelperDisplay"></activity>
</application>
</manifest>
On executing the above code, I am getting the following error :
I have searched a lot and found many stack overflow links with same problem but still it is not resolved. I am new to this topic. Please help me.
I have had two adapters :
public class DBController_for_drivinglicense extends SQLiteOpenHelper {
public DBController_for_drivinglicense(Context applicationcontext) {
super(applicationcontext,"nozadb", null, 1);
}
//Creates Table
#Override
public void onCreate(SQLiteDatabase database) {
String query;
query = "CREATE TABLE if not exists drivinglicense ( id INTEGER PRIMARY KEY, comment TEXT,rates float,names TEXT,date DEFAULT CURRENT_TIMESTAMP, udpateStatus TEXT)";
database.execSQL(query);
}
first adapter was :
public DBController_for_landregistration(Context applicationcontext) {
super(applicationcontext,"nozadb", null, 1);
}
#Override
public void onCreate(SQLiteDatabase database) {
String query;
query = "CREATE TABLE if not exists landregistration ( id INTEGER PRIMARY KEY, comment TEXT,rates float,names TEXT,date DEFAULT CURRENT_TIMESTAMP, udpateStatus TEXT)";
database.execSQL(query);
}
And when i changed the second one to :
public class DBController_for_drivinglicense extends SQLiteOpenHelper {
public DBController_for_drivinglicense(Context applicationcontext) {
super(applicationcontext,"nozadb", null, 2);
}
//Creates Table
#Override
public void onCreate(SQLiteDatabase database) {
String query;
query = "CREATE TABLE if not exists drivinglicense ( id INTEGER PRIMARY KEY, comment TEXT,rates float,names TEXT,date DEFAULT CURRENT_TIMESTAMP, udpateStatus TEXT)";
database.execSQL(query);
}

Using IExtendedNetworkService to get USSD response in Android

I'm trying to find the way to make USSD requests in Android. I found this - http://commandus.com/blog/?p=58 .
I added all needed files to my project.
USSDDumbExtendedNetworkService.java:
package com.android.ussdcodes;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.IBinder;
import android.os.PatternMatcher;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.telephony.IExtendedNetworkService;
import com.android.ussdcodes.R;
/**
* Service implements IExtendedNetworkService interface.
* USSDDumbExtendedNetworkService
* Service must have name "com.android.ussd.IExtendedNetworkService" of the intent declared
* in the Android manifest file so com.android.phone.PhoneUtils class bind
* to this service after system rebooted.
* Please note service is loaded after system reboot!
* Your application must check is system rebooted.
* #see Util#syslogHasLine(String, String, String, boolean)
*/
public class USSDDumbExtendedNetworkService extends Service {
public static final String TAG = "CommandusUSSDExtNetSvc";
public static final String LOG_STAMP = "*USSDTestExtendedNetworkService bind successfully*";
public static final String URI_SCHEME = "ussdcodes";
public static final String URI_AUTHORITY = "android.com";
public static final String URI_PATH = "/";
public static final String URI_PAR = "return";
public static final String URI_PARON = "on";
public static final String URI_PAROFF = "off";
public static final String MAGIC_ON = ":ON;)";
public static final String MAGIC_OFF = ":OFF;(";
public static final String MAGIC_RETVAL = ":RETVAL;(";
private static boolean mActive = false;
private static CharSequence mRetVal = null;
private Context mContext = null;
private String msgUssdRunning = "USSD running...";
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_INSERT.equals(intent.getAction())) {
mContext = context;
if (mContext != null) {
msgUssdRunning = mContext.getString(R.string.USSD_run);
mActive = true;
Log.d(TAG, "activate");
}
} else if (Intent.ACTION_DELETE.equals(intent.getAction())) {
mContext = null;
mActive = false;
Log.d(TAG, "deactivate");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub() {
#Override
public void setMmiString(String number) throws RemoteException {
Log.d(TAG, "setMmiString: " + number);
}
#Override
public CharSequence getMmiRunningText() throws RemoteException {
Log.d(TAG, "getMmiRunningText: " + msgUssdRunning);
return msgUssdRunning;
}
#Override
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
if (MAGIC_ON.contentEquals(text)) {
mActive = true;
Log.d(TAG, "control: ON");
return text;
} else {
if (MAGIC_OFF.contentEquals(text)) {
mActive = false;
Log.d(TAG, "control: OFF");
return text;
} else {
if (MAGIC_RETVAL.contentEquals(text)) {
mActive = false;
Log.d(TAG, "control: return");
return mRetVal;
}
}
}
if (!mActive) {
Log.d(TAG, "getUserMessage deactivated: " + text);
return text;
}
String s = text.toString();
// store s to the !
Uri uri = new Uri.Builder()
.scheme(URI_SCHEME)
.authority(URI_AUTHORITY)
.path(URI_PATH)
.appendQueryParameter(URI_PAR, text.toString())
.build();
sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, uri));
mActive = false;
mRetVal = text;
Log.d(TAG, "getUserMessage: " + text + "=" + s);
return null;
}
#Override
public void clearMmiString() throws RemoteException {
Log.d(TAG, "clearMmiString");
}
};
/**
* Put stamp to the system log when PhoneUtils bind to the service
* after Android has rebooted. Application must call {#link Util#syslogHasLine(String, String, String, boolean)} to
* check is phone rebooted or no. Without reboot phone application does not bind tom this service!
*/
#Override
public IBinder onBind(Intent intent) {
// Do not localize!
Log.i(TAG, LOG_STAMP);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(URI_SCHEME);
filter.addDataAuthority(URI_AUTHORITY, null);
filter.addDataPath(URI_PATH, PatternMatcher.PATTERN_LITERAL);
registerReceiver(mReceiver, filter);
return mBinder;
}
public IBinder asBinder() {
Log.d(TAG, "asBinder");
return mBinder;
}
}
Manifest:
<receiver android:name="com.android.ussdcodes.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".USSDDumbExtendedNetworkService" >
<intent-filter android:icon="#drawable/ic_launcher">
<action android:name="com.android.ussd.IExtendedNetworkService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
BootReceiver.java:
package com.android.ussdcodes;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d("USSDService", context.getString(R.string.service_started));
context.startService(new Intent(context,USSDDumbExtendedNetworkService.class));
}
}
So now the service starts after boot complete.
And my question is how I have to send USSD request and get responce with service?
Thanks!)
Well, I have found the answer.
I just put the link on my gist.
Deactivate messages
USSDDumbExtendedNetworkService.mActive = false;
Send USSD:
Intent launchCall = new Intent(Intent.ACTION_CALL,
Uri.parse("tel:" + Uri.encode(ussdcode)));
launchCall.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
launchCall.addFlags(Intent.FLAG_FROM_BACKGROUND);
startActivity(launchCall);
Activate messages again
USSDDumbExtendedNetworkService.mActive = true;
USSDDumbExtendedNetworkService.mRetVal = null;

Categories