how to install apk programmatically from another app in android - java

I want to install new version of my app programmatically. with targetSdkVersion=23 app works fine and this is my code:
public class MainActivity extends AppCompatActivity {
private int PERMISSION_REQUEST_STORAGE = 0;
private DownloadController downloadController;
Button btn_download;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_download = findViewById(R.id.buttonDownload);
btn_download.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkStoragePermission();
}
});
}
public void checkStoragePermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
String url= getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/example.apk";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(Uri.parse("file://" + url), "application/vnd.android.package-archive");
String selfPackageName = getApplicationContext().getPackageName();
ComponentName componentName = intent.resolveActivity(getApplicationContext().getPackageManager());
String otherPackageName = (componentName != null ? componentName.getPackageName() : "");
if (MainActivity.this == null || !selfPackageName.equals(otherPackageName)) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
startActivity(intent);
} else {
requestStoragePermission();
}
}
public void requestStoragePermission() {
ActivityCompat.requestPermissions(
MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_REQUEST_STORAGE);
}
}
but with targetSdkVersion=29 I heard that I have to use FileProvider. I used this instructure but unfortunately it dosent open my apk to install. this is my res=>xml=>file_provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<files-path
name="files"
path="." />
</paths>
my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mysms">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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>
<receiver android:name=".service.OnComplete" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths" />
</provider>
</application>
</manifest>
my mainActivity
public class MainActivity extends AppCompatActivity {
private int PERMISSION_REQUEST_STORAGE = 0;
private DownloadController downloadController;
Button btn_download;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_download = findViewById(R.id.buttonDownload);
btn_download.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkStoragePermission();
}
});
}
public void checkStoragePermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
File file = new File(getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/example.apk");
Uri uri = FileProvider.getUriForFile(getApplicationContext(), "com.example.myapp", file);
Intent install = new Intent(Intent.ACTION_VIEW);
install.setData(Uri.fromFile(file));
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.setClassName("com.example.myapp", "com.example.myapp.MainActivity");
install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ClipData clipData = new ClipData(new ClipDescription("Meshes", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}), new ClipData.Item(uri));
install.setClipData(clipData);
startActivity(install);
} else {
requestStoragePermission();
}
}
public void requestStoragePermission() {
ActivityCompat.requestPermissions(
MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_REQUEST_STORAGE);
}
}
I get this error
2019-12-17 00:46:38.035 32020-32020/com.example.myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mysms, PID: 32020
android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.example.myapp/files/Download/example.apk exposed beyond app through Intent.getData()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
at android.net.Uri.checkFileUriExposed(Uri.java:2346)
at android.content.Intent.prepareToLeaveProcess(Intent.java:8933)
at android.content.Intent.prepareToLeaveProcess(Intent.java:8894)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1517)
at android.app.Activity.startActivityForResult(Activity.java:4224)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
at android.app.Activity.startActivityForResult(Activity.java:4183)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
at android.app.Activity.startActivity(Activity.java:4507)
at android.app.Activity.startActivity(Activity.java:4475)
at com.example.mysms.MainActivity.checkStoragePermission(MainActivity.java:107)
at com.example.mysms.MainActivity$3.onClick(MainActivity.java:76)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

It seems the problem is that you set wrong uri to intent data:
install.setData(Uri.fromFile(file));
You need to set uri which was created with FileProvider:
Uri uri = FileProvider.getUriForFile(getApplicationContext(), "com.example.myapp", file);
install.setData(uri);
The same is done in the instruction you have found:
val contentUri = FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID + PROVIDER_PATH,
File(destination)
)
val install = Intent(Intent.ACTION_VIEW)
install.data = contentUri

Related

Can't read SMS on android

I can't seem to get a basic sms reading app to work on android. Not sure what am I missing here. I think I have all the basic minimum specified in the code, despite that it seems to be not working. The onReceive() of SmsReceiver is never invoked. All the required permissions are set.
Here are my files.
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//...
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestReadAndSendSmsPermission();
smsReceiver = new SmsReceiver() {
#Override
protected void onData(String data) {
//handle
}
};
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
//intentFilter.setPriority(999);
registerReceiver(smsReceiver, intentFilter);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(smsReceiver);
}
private void requestReadAndSendSmsPermission() {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_SMS},1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECEIVE_SMS},1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_RESPOND_VIA_MESSAGE}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_NETWORK_STATE}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CHANGE_NETWORK_STATE}, 1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.INTERNET}, 1);
}
//...
//...
}
SmsReceiver.java
public abstract class SmsReceiver extends BroadcastReceiver {
private static final String TAG = "SmsReceiver";
#Override
public void onReceive(Context context, Intent intent) {
if (context == null || intent == null) {
return;
}
String action = intent.getAction();
if (!action.equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
return;
}
//read sms
onData("sms received");
}
protected abstract void onData(String data);
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mysmsapp">
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MySMSApp">
<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>
You are missing defining the receiver entry in AndroidManifest.xml file for your BroadcastReceiver named SmsReceiver please make the entry for it else OS will not know if you have a broadcast receiver waiting to be triggered.
Depending upon what is your use case it might be something like
<receiver
android:name=".SmsReceiver"
android:exported="true"
android:permission="com.google.android.gms.auth.api.phone.permission.SEND">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
Or
<receiver
android:name=". SmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Note: These receiver are sample receiver please use the correct one as per your use case, the main point is you are missing receiver entry in your manifest file
i use this code to read incoming message
public class SmsReceiver extends BroadcastReceiver {
private static final Uri smsuri = Apconsts.smsuri;
private static final String pdu_type = "pdus";
#Override
public void onReceive(Context context, Intent intent){
// Get the SMS message.
Bundle bundle = intent.getExtras();
SmsMessage[] msgs;
String format = bundle.getString("format");
// Retrieve the SMS message received.
Object[] pdus = (Object[]) bundle.get(pdu_type);
String body="";String adrs="";
if (pdus != null) {
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++){
if(Build.VERSION.SDK_INT < 23){ msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); }
else{ msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format); }
adrs=msgs[i].getOriginatingAddress();
body += ""+msgs[i].getMessageBody();
}
Toast.makeText(getApplicationContext(), "The message Body: "+body+"\nThe address: "+adrs, Toast.LENGTH_LONG).show();
}
}
}
and this receiver in manifest
<receiver android:name=".SmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>

Attempt to invoke virtual method 'java.lang.String java.io.File.getCanonicalPath()' on a null object reference

I'm setting up a share button on my app, that takes a screenshot of a particular list view, and then lets the user to share this. To do this, I created three methods:
Take the screenshot
Save it in my storage
Share it to the user.
Here is my code:
Android Manifest file:
<?xml version="1.0"
encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.transfergame">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".ViewPlayerHistoryContents" />
<activity android:name=".CorrectScreen" />
<activity
android:name=".DifficultyScreen"
android:label="Transfer Game">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.transfergame.provider"
android:exported="false"
android:grantUriPermissions="true">
<!-- ressource file to create -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths">
</meta-data>
</provider>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
File_Paths.xml (in Res folder):
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>
Main Activity code:
package com.example.transfergame;
public class ViewPlayerHistoryContents extends AppCompatActivity {
public ImageButton shareButton;
public static File imagePath;
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
public void saveBitmap(Bitmap bitmap) {
imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
private void shareIt() {
File imageFile = null;
Uri imageUri = FileProvider.getUriForFile(
ViewPlayerHistoryContents.this,
"com.example.transfergame.provider", //(use your app signature + ".provider" )
imageFile);
// Uri uri = Uri.fromFile(imagePath);
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("image/*");
String shareBody = "In Tweecher, My highest score with screen shot";
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Tweecher score");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
sharingIntent.putExtra(Intent.EXTRA_STREAM, imageFile);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_player_history);
shareButton = findViewById(R.id.shareButton);
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
// now setting onClickListener to query button
shareButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
shareIt();
}
});
}
}
The error message I am getting is this:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.transfergame, PID: 20421
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.io.File.getCanonicalPath()' on a null object reference
at androidx.core.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:728)
at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:418)
at com.example.transfergame.ViewPlayerHistoryContents.shareIt(ViewPlayerHistoryContents.java:149)
at com.example.transfergame.ViewPlayerHistoryContents.access$000(ViewPlayerHistoryContents.java:30)
at com.example.transfergame.ViewPlayerHistoryContents$1.onClick(ViewPlayerHistoryContents.java:189)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
The line
at com.example.transfergame.ViewPlayerHistoryContents.shareIt(ViewPlayerHistoryContents.java:149)
is talking about
Uri imageUri = FileProvider.getUriForFile(
ViewPlayerHistoryContents.this,
"com.example.transfergame.provider", //(use your app signature + ".provider" )
imageFile);
in my shareIt() method, but I'm not sure why that is giving me an error as that matches exactly with my authorities in my android manifest file.
Does anyone else know what I am doing wrong?

Unsuccessful Download using DownloadManager in Android 9

I have an xls file in my server which needs to be downloaded in my phone using an apps. I'm using Nokia 5 and Android 9 for testing. My compile sdk version is 29. When I clicked download button, it didn't do anything, and after waiting for a while, a "Download Unsuccessful" notification popped up.
This is my MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_STORAGE_CODE = 1000;
EditText editUrl;
Button btnDownload;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editUrl = findViewById(R.id.edit_url);
btnDownload = findViewById(R.id.btn_download);
btnDownload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
String [] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions, PERMISSION_STORAGE_CODE);
}
else {
startDownloading();
}
}
else {
startDownloading();
}
}
});
}
private void startDownloading() {
String url = editUrl.getText().toString().trim();
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setTitle("Download");
request.setDescription("Downloading file...");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, ""+System.currentTimeMillis());
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch(requestCode) {
case PERMISSION_STORAGE_CODE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
startDownloading();
else
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
}
I added network_security_config.xml (domain is blurred for security reason)
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">moneytracker.mauini******.com</domain>
</domain-config>
</network-security-config>
and added it in manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.main.downloadtest">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:networkSecurityConfig="#xml/network_security_config"
android:usesCleartextTraffic="true">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
And lastly, the download url is something like this:
http://moneytracker.mauini******.com/uploads/asd.xls
The file is successfully downloaded when that URL is executed in browser.
Am I missing something? Those are all I can get, searching for days. Please help.
First, on your code request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, ""+System.currentTimeMillis());. After Environment.DIRECTORY_DOWNLOADS param, you should put correct file name on it. coolfilename.xxx. Or, get its Uri value and put the Uri.getLastPathSegment() as the second parameter. Second, try to put request.setMimeType(param).

Android: Receive and forward text message from service

I am trying to make a simple app that will forward all messages with particular body to another number.
Broadcast receiver in my class is not being called. Any leads will be appreciated
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Settings.Applog("App started !!");
Intent intent = new Intent(this, SMSService.class);
startService(intent);
}
SMSService.java
public class SMSService extends Service {
private IntentFilter mIntentFilter;
private SMSreceiver mSMSreceiver;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
super.onCreate();
Settings.Applog("Service started !!");
//SMS event receiver
mSMSreceiver = new SMSreceiver();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(mSMSreceiver, mIntentFilter);
}
#Override
public void onDestroy()
{
super.onDestroy();
// Unregister the SMS receiver
unregisterReceiver(mSMSreceiver);
}
private String ConvertNumber(String from){
return from;
}
public class SMSreceiver extends BroadcastReceiver
{
private final String TAG = this.getClass().getSimpleName();
#Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
String strMessage = "";
Settings.Applog("Got a message!!");
if ( bundle != null )
{
try{
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] msgs = new SmsMessage[pdus.length];
for(int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
String msg_from = msgs[i].getOriginatingAddress();
String msgBody = msgs[i].getMessageBody();
Settings.Applog("Message body ::"+msgBody);
}
}catch(Exception e){
//Log.d("Exception caught",e.getMessage());
}
}
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mypackage">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".SMSService"
android:exported="false">
</service>
</application>
</manifest>
You have to register the Broadcast Receiver for receiving SMS in the manifest file.
Just the permission will not work.
Inside the application tag it would look something like:
<application android:icon="#drawable/icon" android:label="#string/app_name" android:debuggable="true" >
<receiver android:name=".SMSBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
</application>
Use this as an example for receiving the SMS message. It should be a good starting point.
http://javapapers.com/android/android-receive-sms-tutorial/

Android GoogleApiClient application crash at connect()

my app crashes without any error message at googleApiClient.connect(). It never gets to onConnectionFailed. Here's what I have:
at MainActivity
public class MainMenu extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static final int REQUEST_LEADERBOARD = 1;
public static int SCREEN_WIDTH;
public static int SCREEN_HEIGHT;
private GoogleApiClient googleApiClient;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
SCREEN_WIDTH = metrics.widthPixels;
SCREEN_HEIGHT = metrics.heightPixels;
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
public void newGame(View view) {
Intent intent = new Intent(MainMenu.this, Game.class);
startActivity(intent);
finish();
}
public void highScore(View view) {
if (isSignedIn()) {
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(googleApiClient,
String.valueOf(R.string.leaderboard_id)), REQUEST_LEADERBOARD);
}
else {
System.out.println("not sign in");
}
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
System.out.println("failed");
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.connect(); //here it crashed
}
private boolean isSignedIn() {
return (googleApiClient != null && googleApiClient.isConnected());
}
}
What I've done:
I have generated signed APK, I have sha1 key. I published the app for alpha testing.
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="my.package"
android:versionCode="2"
android:versionName="1.1">
<uses-sdk android:minSdkVersion="1"/>
<application android:icon="#drawable/ic_launcher" android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.NoActionBar"
android:isGame="true" >
<meta-data
android:name="com.google.android.gms.games.APP_ID"
android:value="#string/app_id" />
<meta-data
android:name="my.package.version"
android:value="com.google.android.gms.version" />
<activity android:name=".activities.MainMenu">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".activities.Game"/>
<activity android:name=".activities.GameOver"/>
<activity android:name=".activities.HighScore"/>
</application>
</manifest>
I'm testing it on device with Google Play Service installed. Could you help me?
You should add the internet permission to your manifest.
<uses-permission android:name="android.permission.INTERNET"/>
If you need more help, you should show the error stacktrace.
Hope it helps you!
The solution is simple
<meta-data
android:name="my.package.version"
android:value="com.google.android.gms.version" />
is nonsense.
it should be:
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />

Categories

Resources