Starting Activity from a non-Activity in c2dm not showing - android

I am trying to display messages from C2DM so When I start an Activity from a non activity it works but only first time. My activity contains View and close button so if the user is not inside the app when he receive the push notification then it should start the app when he press view button or close it on close this works as well but when user press view button and enters the app after than I am unable to start the activity again, it seems like the activity is there but its not visible to user. My code is as below , hope you understand what I am saying. The C2DM code example used is taken from here
C2DMReceiver
package com.mks.android.example;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.google.android.c2dm.C2DMBaseReceiver;
import com.google.android.c2dm.C2DMessaging;
import com.mks.android.example.activity.MessageDialogActivity;
public class C2DMReceiver extends C2DMBaseReceiver {
private static String senderId = "mysenderemail#gmail.com";
String registrationId;
public C2DMReceiver() {
super(senderId);
}
#Override
public void onRegistrered(Context context, String registrationId) {
this.registrationId = registrationId;
Log.e("Error", registrationId);
}
#Override
public void onUnregistered(Context context) {
C2DMessaging.register(context, senderId);
}
#Override
public void onError(Context context, String errorId) {
Log.w("Error", errorId);
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.i("Error", "MessageReceived");
Bundle bundle = intent.getExtras();
intent = new Intent();
intent.putExtra("messageBundle", bundle);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
intent.setClass(context, MessageDialogActivity.class);
startActivity(intent);
// load message display activity here
}
}
MESSAGE DIALOG ACTIVITY CLASS
package com.mks.android.example.activity;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import com.mks.android.example.R;
import com.mks.android.example.activity.list.Functions;
public class MessageDialogActivity extends Activity {
private Functions func = new Functions();
private int isAppActive = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showMessages();
}
private void showMessages(){
Bundle bundle = getIntent().getBundleExtra("messageBundle");
String title = bundle.getString("title");
String message = bundle.getString("message");
setContentView(R.layout.c2dm_message);
TextView txtTitle = (TextView) findViewById(R.id.title);
TextView txtMessage = (TextView) findViewById(R.id.message);
Button btnView = (Button) findViewById(R.id.btnView);
Button btnClose = (Button) findViewById(R.id.btnClose);
txtTitle.setText(title);
txtMessage.setText(message);
this.isAppActive = func.getAppState(this);
if(isAppActive==1){
btnView.setVisibility(View.GONE);
}
btnView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(isAppActive == 0){
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.mks.android.example","com.mks.android.example.activity.MainActivity"));
startActivity(intent);
}
MessageDialogActivity.this.finish();
}
});
btnClose.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
showMessages();
}
}
AndroidManifest FIle
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mks.android.example"
android:versionCode="1"
android:versionName="1.0" android:installLocation="preferExternal">
<uses-sdk android:minSdkVersion="4" />
<application android:label="#string/app_name" android:icon="#drawable/icon_launcher" android:debuggable="true">
<uses-library android:name="com.google.android.maps" />
<activity android:name=".activity.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activity.MessageDialogActivity" android:theme="#style/DialogNoTitle" android:activity android:launchMode="singleTop" />
<service android:name=".C2DMReceiver" />
<!-- Only C2DM servers can send messages for the app. If permission is not set - any other app can generate it -->
<receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<!-- Receive the actual message -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.mks.android.example" />
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.mks.android.example" />
</intent-filter>
</receiver>
</application>
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<permission android:name="com.mks.android.example.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.mks.android.example.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive message -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
If i remove androidLaunchMode singleTop form manifest file and add set flag to multipleTask in C2DMReciver class it works but i get lots of dialog for each message. Thanks for help .

Set flag to singletop , the code to call messagedialogactivity is as under:
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setClass(context, MessageDialogActivity.class);

Related

My Bluetooth application crashes for a some reason

My mainactivity
package com.example.vivek.trackblue;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
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.Toast;
public class MainActivity extends AppCompatActivity {
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
Context context = getApplicationContext();
CharSequence text = "Bluetooth is not supported";
int duration = Toast.LENGTH_SHORT;
Toast toast1 = Toast.makeText(context, text, duration);
Button b1 = (Button)findViewById(R.id.button);
private final static int REQUEST_ENABLE_BT=1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
if(bt == null){
toast1.show();
}
if(bt.isEnabled())
{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
});
}
}
and this is my AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.vivek.trackblue">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<permission android:name="android.permission.BLUETOOTH" android:label="BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I am Trying to create an application where the user would press a button to start Bluetooth.
My code shows no errors on the ide but when it gets installed in the device, it crashes with an error "Unfortunately TrackBlue stopped working". Here trackblue is my application's name.
Simply because you have assigned value to button variable before setting content view for the screen.
Error is because it tries to find the view by the given button's ID even before it is set on to screen.
Solution:
Write the findViewById() line after setContentView() inside onCreate()

what is the category parameter in define a receiver

I know that when I define a Broadcast receiver from manifest in bellow of intent filter I can define category that it's optional.
<receiver android:name=".PushMessageReceiver" >
<intent-filter>
<!-- Receives the actual messages. -->
<category android:name="com.test.myAppname" />
<action android:name="com.test.client.MSGRECEIVE" />
</intent-filter>
</receiver>
I googled but cant get it what is the exact point of adding category or how I can use it. I appreciate to give me some examples.
MainActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* send
*
*/
public class MainActivity extends Activity {
private static final String MY_ACTION = "com.chaowen.action.MY_ACTION";
private Button btn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.Button01);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent= new Intent();
intent.setAction(MY_ACTION);
//Intent message
intent.putExtra("msg", "ha ha");
//send
sendBroadcast(intent);
}
});
}
}
MyReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* receive
*
*/
public class MyReceive extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//get Intent message
String msg = intent.getStringExtra("msg");
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:text="send..."
android:id="#+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.chaowen"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<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>
<receiver
android:name="MyReceive"
>
<intent-filter>
<action
android:name="com.chaowen.action.MY_ACTION" />
</intent-filter>
</receiver>
</application>

can broadcast receiver handle ACTION_NDEF_DISCOVERED?

I am trying to write an app that would perform following operations:
once the user unlock the phone he has 10 seconds to scan an NFC tag in order to start camera app. and the NFC tag will have a mime type of
application/com.testformat.nfcdemo
To detect screen unlock, I used a broadcast receiver to detected User present.
And this works fine.
And I started a CountdownTimer inside the broadcast receiver for 10 seconds.
And the NFC detection part did not work, I could use some help here! thank you all!
My activity:
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class DisplayActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
}
Manifest xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.nfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-permission android:name="android.permission.NFC" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity
android:name=".DisplayActivity"
android:label="#string/activity_title" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".ScreenStateReceiver">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/com.testformat.nfcdemo" />
</intent-filter>
</receiver>
</application>
</manifest>
Receiver:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.os.CountDownTimer;
import android.widget.Toast;
public class ScreenStateReceiver extends BroadcastReceiver {
private boolean countdown_end = false;
NfcAdapter mNfcAdapter;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
CharSequence text = context.getResources().getString(R.string.unlock_message);
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
startCountdown(10000);
if (intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
if (!countdown_end) {
text = context.getResources().getString(R.string.nfc_detected);
Toast nfc_toast = Toast.makeText(context, text, duration);
toast.show();
}
}else if ( intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)){
if (!countdown_end) {
text = context.getResources().getString(R.string.nfc_detected);
Toast nfc_toast = Toast.makeText(context, text, duration);
toast.show();
}
}
}
}
private void startCountdown(long milliseconds){
new CountDownTimer(milliseconds, 1000) {
#Override
public void onTick(long l) {
}
public void onFinish() {
countdown_end=true;
}
}.start();
}
}
can broadcast receiver handle ACTION_NDEF_DISCOVERED?
No. That is an activity action, used with startActivity(). It is not broadcast and therefore cannot be picked up by a BroadcastReceiver.

Unable to start service Intent { act=com.google.android.c2dm.intent.REGISTRATION (has extras) } U=0: not found

I am trying to get the registration id of a device (testing using the emulator) to set up push notifications using GCM.
I have tried the following code, which gives me the following error:
Unable to start service Intent { act=com.google.android.c2dm.intent.REGISTRATION (has extras) } U=0: not found
Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.me.pushnotifications"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<permission android:name="com.me.pushnotifications.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.me.pushnotifications.permission.C2D_MESSAGE" />
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="com.me.pushnotifications.MyBroadcastReceiver"
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.me.pushnotifications"/>
</intent-filter>
</receiver>
<activity
android:name="com.me.pushnotifications.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>
I am using a BroadcastReceiver to achieve the purpose:
package com.me.pushnotifications;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context arg0, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
Log.i("action::",action);
try{
if(action.equals("com.google.android.c2dm.intent.REGISTRATION")){
String regId = intent.getStringExtra("registration_id");
String error = intent.getStringExtra("error");
String unregistered = intent.getStringExtra("unregistered");
Log.i("regId::",regId);
}
else if(action.equals("com.google.android.c2dm.intent.RECEIVE")){
String data = intent.getStringExtra("data");
Log.i("data::",data);
}
}
finally{
}
}
}
MainActivity
package com.me.pushnotifications;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Context context = getApplicationContext();
final String appId = getResources().getString(R.string.appId) ;
Log.i("appName::",appId);
Button activateButton,deactivateButton;
activateButton = (Button)findViewById(R.id.activateButton);
deactivateButton = (Button)findViewById(R.id.deactivateButton);
activateButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("activate::","clicked");
Intent regIntent = new Intent("com.google.android.c2dm.intent.REGISTRATION");
Log.i("intent::","created");
regIntent.putExtra("app", PendingIntent.getBroadcast(context, 0,
new Intent(), 0));
regIntent.putExtra("sender", "registration_id");
startService(regIntent);
}
});
deactivateButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("deactivate::","clicked");
Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER");
Log.i("intent::","created");
unregIntent.putExtra("app", PendingIntent.getBroadcast(context, 0,
new Intent(), 0));
startService(unregIntent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I have installed the Google API's for API Level 18. What may be the reason for the issue?
add this line in your intent-filter tag in manifest
file
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
Like this
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.androidhive.pushnotifications" />
</intent-filter>
Use like this:
<receiver
android:name="com.example.gcmclient.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTER" />
<category android:name="com.example.gcmclient" />
</intent-filter>
</receiver>
<service android:name="com.example.gcmclient.GcmMessageHandler" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service android:name=".GcmIntentService" />

Android:Broadcast demo not working

I am new to android, i am trying a broadcast demo, I gave my best effort by reading the documentation but its not working. Please have a look at my code:
BroadcastDemoActivity.java
package com.broadcastdemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class BroadcastDemoActivity extends Activity {
/** Called when the activity is first created. */
public static final String PUBLIC_HOLIDAYS = "com.paad.action.PUBLIC_HOLIDAYS";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = new Intent(PUBLIC_HOLIDAYS);
intent.putExtra("Holiday", "8th April is a holiday");
sendBroadcast(getIntent());
}
}
Receive.java
package com.broadcastdemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class Receive extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String message = intent.getStringExtra("Holiday");
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.broadcastdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".BroadcastDemoActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".Receive">
<intent-filter>
<action android:name="com.paad.action.PUBLIC_HOLIDAYS"/>
</intent-filter>
</receiver>
</application>
</manifest>
I know that i am missing something which i am not aware of, please help.
I believe your problem is in the call to sendBroadcast.
Intent intent = new Intent(PUBLIC_HOLIDAYS);
intent.putExtra("Holiday", "8th April is a holiday");
sendBroadcast(getIntent());
You are not sending the intent that you construct, you're sending the intent returned from getIntent(), which will be the intent that the activity was started with.
It should be
Intent intent = new Intent(PUBLIC_HOLIDAYS);
intent.putExtra("Holiday", "8th April is a holiday");
sendBroadcast(intent);

Categories

Resources